X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fsprite%2Fsprite.cpp;h=c508642670188c3e8cc22318780bdcd28fb6e240;hb=9eab9403c2b9ff629c07380e8d5f1032d21bd3f7;hp=782fc5223e4d343801aa62c74cd26d808633cf6c;hpb=08813a74da6ac1fd045a105e4e8105f1d7f716f0;p=supertux.git diff --git a/src/sprite/sprite.cpp b/src/sprite/sprite.cpp index 782fc5223..c50864267 100644 --- a/src/sprite/sprite.cpp +++ b/src/sprite/sprite.cpp @@ -14,45 +14,59 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include - #include "sprite/sprite.hpp" + +#include +#include + #include "supertux/timer.hpp" -Sprite::Sprite(SpriteData& newdata) - : data(newdata), - frame(0), - animation_loops(-1), - angle(0.0f), - color(1.0f, 1.0f, 1.0f, 1.0f) +Sprite::Sprite(SpriteData& newdata) : + data(newdata), + frame(0), + frameidx(0), + animation_loops(-1), + last_ticks(), + angle(0.0f), + color(1.0f, 1.0f, 1.0f, 1.0f), + blend(), + action(data.get_action("normal")) { - action = data.get_action("normal"); if(!action) action = data.actions.begin()->second; last_ticks = game_time; } -Sprite::Sprite(const Sprite& other) - : data(other.data), frame(other.frame), - animation_loops(other.animation_loops), - angle(0.0f), - color(1.0f, 1.0f, 1.0f, 1.0f), - action(other.action) +Sprite::Sprite(const Sprite& other) : + data(other.data), + frame(other.frame), + frameidx(other.frameidx), + animation_loops(other.animation_loops), + last_ticks(game_time), + angle(0.0f), // FIXME: this can't be right + color(1.0f, 1.0f, 1.0f, 1.0f), + blend(), + action(other.action) { - last_ticks = game_time; } Sprite::~Sprite() { } +SpritePtr +Sprite::clone() const +{ + return SpritePtr(new Sprite(*this)); +} + void Sprite::set_action(const std::string& name, int loops) { if(action && action->name == name) return; - SpriteData::Action* newaction = data.get_action(name); + const SpriteData::Action* newaction = data.get_action(name); if(!newaction) { log_debug << "Action '" << name << "' not found." << std::endl; return; @@ -61,6 +75,7 @@ Sprite::set_action(const std::string& name, int loops) action = newaction; animation_loops = loops; frame = 0; + frameidx = 0; } void @@ -69,20 +84,14 @@ Sprite::set_action_continued(const std::string& name) if(action && action->name == name) return; - SpriteData::Action* newaction = data.get_action(name); + const SpriteData::Action* newaction = data.get_action(name); if(!newaction) { log_debug << "Action '" << name << "' not found." << std::endl; return; } action = newaction; - if(frame >= get_frames()) { - frame = fmodf(frame, get_frames()); - - if (animation_loops > 0) animation_loops--; - if(animation_done()) - frame = get_frames()-1; - } + update(); } bool @@ -94,38 +103,46 @@ Sprite::animation_done() void Sprite::update() { - if(animation_done()) - return; - float frame_inc = action->fps * (game_time - last_ticks); last_ticks = game_time; frame += frame_inc; - if(frame >= get_frames()) { - frame = fmodf(frame, get_frames()); + while(frame >= 1.0f) { + frame -= 1.0f; + frameidx++; + } + while(frameidx >= get_frames()) { + frameidx -= get_frames(); animation_loops--; - if(animation_done()) - frame = get_frames()-1; + if(animation_done()) { + break; + } + } + + if(animation_done()) { + frame = 0; + frameidx = get_frames()-1; } + + assert(frameidx < get_frames()); } void -Sprite::draw(DrawingContext& context, const Vector& pos, int layer) +Sprite::draw(DrawingContext& context, const Vector& pos, int layer, + DrawingEffect effect) { assert(action != 0); update(); - if((int)frame >= get_frames() || (int)frame < 0) - log_warning << "frame out of range: " << (int)frame << "/" << get_frames() << " at " << get_name() << "/" << get_action() << std::endl; - else - context.draw_surface(action->surfaces[(int)frame], - pos - Vector(action->x_offset, action->y_offset), - angle, - color, - blend, - layer + action->z_order); + context.set_drawing_effect(effect); + context.draw_surface(action->surfaces[frameidx], + pos - Vector(action->x_offset, action->y_offset), + angle, + color, + blend, + layer + action->z_order); } void @@ -135,31 +152,24 @@ Sprite::draw_part(DrawingContext& context, const Vector& source, assert(action != 0); update(); - int frameidx = (int) frame; - - if(frameidx >= get_frames() || frameidx < 0) { -#ifndef DEBUG - // in optimized mode we get some small rounding errors in floating point - // number sometimes... - log_warning << "frame out of range: " << frameidx << "/" << get_frames() << " at sprite: " << get_name() << "/" << get_action() << std::endl; -#endif - frameidx = get_frames() - 1; - } - - context.draw_surface_part(action->surfaces[frameidx], source, size, - pos - Vector(action->x_offset, action->y_offset), + context.draw_surface_part(action->surfaces[frameidx], + Rectf(source, Sizef(size)), + Rectf(pos - Vector(action->x_offset, action->y_offset), + Sizef(size)), layer + action->z_order); } int Sprite::get_width() const { + assert(frameidx < get_frames()); return (int) action->surfaces[get_frame()]->get_width(); } int Sprite::get_height() const { + assert(frameidx < get_frames()); return (int) action->surfaces[get_frame()]->get_height(); } @@ -187,16 +197,10 @@ Sprite::get_current_hitbox_height() const return action->hitbox_h; } -Rect +Rectf Sprite::get_current_hitbox() const { - return Rect(action->x_offset, action->y_offset, action->x_offset + action->hitbox_w, action->y_offset + action->hitbox_h); -} - -void -Sprite::set_fps(float new_fps) -{ - action->fps = new_fps; + return Rectf(action->x_offset, action->y_offset, action->x_offset + action->hitbox_w, action->y_offset + action->hitbox_h); } void