From: Ricardo Cruz Date: Thu, 12 Aug 2004 20:55:05 +0000 (+0000) Subject: Added what I called of actions to Sprite. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=d88eb6fed051a3c6bea58857955ec5d902e63e04;p=supertux.git Added what I called of actions to Sprite. Instead of putting "left", "right", "jump-right"... as different sprites, we can now put them as one, and name them with different actions. To change to an action, just do set_action("jump-left"); , for instance. Suggested by Ryan. SVN-Revision: 1757 --- diff --git a/lib/special/sprite.cpp b/lib/special/sprite.cpp index cf35687c4..94e015321 100644 --- a/lib/special/sprite.cpp +++ b/lib/special/sprite.cpp @@ -29,44 +29,79 @@ using namespace SuperTux; Sprite::Sprite(lisp_object_t* cur) { - init_defaults(); + for(; !lisp_nil_p(cur); cur = lisp_cdr(cur)) + { + std::string token = lisp_symbol(lisp_car(lisp_car(cur))); + lisp_object_t* data = lisp_car(lisp_cdr(lisp_car(cur))); + LispReader reader(lisp_cdr(lisp_car(cur))); + + if(token == "name") + name = lisp_string(data); + else if(token == "action") + parse_action(reader); + } + + if(name.empty()) + Termination::abort("Error: Sprite wihtout name.", ""); + if(actions.empty()) + Termination::abort("Error: Sprite wihtout actions.", ""); +} + +Sprite::~Sprite() +{ + for(Actions::iterator i_act = actions.begin(); i_act != actions.end(); ++i_act) + { + for(std::vector::iterator i_sur = i_act->second->surfaces.begin(); + i_sur != i_act->second->surfaces.end(); ++i_sur) + delete *i_sur; + delete i_act->second; + } +} + +void +Sprite::parse_action(LispReader& lispreader) +{ + action = new Action; - LispReader reader(cur); + init_defaults(action); - if(!reader.read_string("name", name)) - Termination::abort("Sprite wihtout name", ""); - reader.read_int("x-hotspot", x_hotspot); - reader.read_int("y-hotspot", y_hotspot); - reader.read_float("fps", fps); + if(!lispreader.read_string("name", action->name)) + if(!actions.empty()) + Termination::abort("Error: If there are more than one action, they need names!", ""); + lispreader.read_int("x-hotspot", action->x_hotspot); + lispreader.read_int("y-hotspot", action->y_hotspot); + lispreader.read_float("fps", action->fps); std::vector images; - if(!reader.read_string_vector("images", images)) - Termination::abort("Sprite contains no images: ", name.c_str()); + if(!lispreader.read_string_vector("images", images)) + Termination::abort("Sprite contains no images: ", action->name.c_str()); for(std::vector::size_type i = 0; i < images.size(); ++i) { - surfaces.push_back( + action->surfaces.push_back( new Surface(datadir + "/images/" + images[i], true)); } - frame_delay = 1000.0f/fps; + action->frame_delay = 1000.0f/action->fps; + + actions[action->name] = action; } -Sprite::~Sprite() +void +Sprite::init_defaults(Action* act) { - for(std::vector::iterator i = surfaces.begin(); i != surfaces.end(); - ++i) - delete *i; + act->x_hotspot = 0; + act->y_hotspot = 0; + act->fps = 10; + act->frame_delay = 1000.0f/act->fps; + time = 0; } void -Sprite::init_defaults() +Sprite::set_action(std::string& act) { - x_hotspot = 0; - y_hotspot = 0; - fps = 10; - time = 0; - frame_delay = 1000.0f/fps; +Actions::iterator i = actions.find(act); +action = i->second; } void @@ -83,11 +118,11 @@ Sprite::draw(DrawingContext& context, const Vector& pos, int layer, time = SDL_GetTicks(); unsigned int frame = get_current_frame(); - if (frame < surfaces.size()) + if (frame < action->surfaces.size()) { - Surface* surface = surfaces[frame]; + Surface* surface = action->surfaces[frame]; - context.draw_surface(surface, pos - Vector(x_hotspot, y_hotspot), layer, drawing_effect); + context.draw_surface(surface, pos - Vector(action->x_hotspot, action->y_hotspot), layer, drawing_effect); } } @@ -112,20 +147,20 @@ Sprite::reset() int Sprite::get_current_frame() const { - unsigned int frame = static_cast(fmodf(time, surfaces.size()*frame_delay)/frame_delay); - return frame % surfaces.size(); + unsigned int frame = static_cast(fmodf(time, action->surfaces.size()*action->frame_delay)/action->frame_delay); + return frame % action->surfaces.size(); } int Sprite::get_width() const { - return surfaces[get_current_frame()]->w; + return action->surfaces[get_current_frame()]->w; } int Sprite::get_height() const { - return surfaces[get_current_frame()]->h; + return action->surfaces[get_current_frame()]->h; } /* EOF */ diff --git a/lib/special/sprite.h b/lib/special/sprite.h index f397a4bd1..e8b79374f 100644 --- a/lib/special/sprite.h +++ b/lib/special/sprite.h @@ -22,6 +22,7 @@ #include #include +#include #include "../utils/lispreader.h" #include "../video/surface.h" @@ -32,6 +33,25 @@ namespace SuperTux class Sprite { + private: + + struct Action + { + std::string name; + + int x_hotspot; + int y_hotspot; + + /** Frames per second */ + float fps; + + /** Number of seconds that a frame is displayed until it is switched + to the next frame */ + float frame_delay; + + std::vector surfaces; + }; + public: /** cur has to be a pointer to data in the form of ((x-hotspot 5) (y-hotspot 10) ...) */ @@ -46,13 +66,16 @@ namespace SuperTux Uint32 drawing_effect = NONE_EFFECT); int get_current_frame() const; + /** Set action (or state) */ + void set_action(std::string& act); + float get_fps() { - return fps; + return action->fps; } ; int get_frames() { - return surfaces.size(); + return action->surfaces.size(); } ; std::string get_name() const @@ -64,29 +87,23 @@ namespace SuperTux Surface* get_frame(unsigned int frame) { - if(frame < surfaces.size()) - return surfaces[frame]; + if(frame < action->surfaces.size()) + return action->surfaces[frame]; else - return surfaces[0]; + return action->surfaces[0]; } private: - std::string name; + void init_defaults(Action* act); + void parse_action(LispReader& lispreader); - int x_hotspot; - int y_hotspot; - - /** Frames per second */ - float fps; - - /** Number of seconds that a frame is displayed until it is switched - to the next frame */ - float frame_delay; + std::string name; float time; - std::vector surfaces; + typedef std::map Actions; + Actions actions; - void init_defaults(); + Action* action; }; } //namespace SuperTux