X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=lib%2Fspecial%2Fsprite.cpp;h=6659c48cddc4ffcef1ce40f2beee0f09b50fcc10;hb=08b7ca0cfedba1e9fa904162fa79d3a00d2188f7;hp=d9134885e8ac8471518c1397d14349d2a9184a94;hpb=70f26d626c6e0f7717be209438341987ae38ddfc;p=supertux.git diff --git a/lib/special/sprite.cpp b/lib/special/sprite.cpp index d9134885e..6659c48cd 100644 --- a/lib/special/sprite.cpp +++ b/lib/special/sprite.cpp @@ -92,22 +92,31 @@ Sprite::init_defaults(Action* act) act->y_hotspot = 0; act->fps = 10; - animation_loops = -1; - last_tick = 0; + start_animation(-1); } void Sprite::set_action(std::string act) { +if(!next_action.empty() && animation_loops > 0) + { + next_action = act; + return; + } Actions::iterator i = actions.find(act); +if(i == actions.end()) + { + std::cerr << "Warning: Action '" << act << "' not found on Sprite '" << name << "'\n"; + return; + } action = i->second; } void Sprite::start_animation(int loops) { -animation_loops = loops; reset(); +animation_loops = loops; } void @@ -116,6 +125,7 @@ Sprite::reset() frame = 0; last_tick = SDL_GetTicks(); animation_reversed = false; +next_action.clear(); } bool @@ -125,9 +135,9 @@ return animation_loops; } void -Sprite::reverse_animation() +Sprite::reverse_animation(bool reverse) { -animation_reversed = !animation_reversed; +animation_reversed = reverse; if(animation_reversed) frame = get_frames()-1; @@ -141,31 +151,52 @@ Sprite::update() if(animation_loops == 0) return; -float inc_frame = (action->fps/1000) * (SDL_GetTicks() - last_tick); +float frame_inc = (action->fps/1000.0) * (SDL_GetTicks() - last_tick); +last_tick = SDL_GetTicks(); if(animation_reversed) - frame -= inc_frame; + frame -= frame_inc; else - frame += inc_frame; - -last_tick = SDL_GetTicks(); + frame += frame_inc; -if(!animation_reversed) +if(animation_reversed) { - if((unsigned int)frame >= action->surfaces.size()) - { - frame = 0; + float excedent = frame - 0; + if((int)excedent < 0 || excedent >= get_frames()) + { // last case can happen when not used reverse_animation() + frame = get_frames() - 1; if(animation_loops > 0) + { animation_loops--; + if(animation_loops == 0 && !next_action.empty()) + { + set_action(next_action); + start_animation(-1); + } + } + + if(fabsf(excedent) < get_frames()) + frame += excedent; } } else { - if((unsigned int)frame < 0) + float excedent = frame - action->surfaces.size(); + if((int)excedent >= 0) { - frame = get_frames()-1; + frame = 0; if(animation_loops > 0) + { animation_loops--; + if(animation_loops == 0 && !next_action.empty()) + { + set_action(next_action); + start_animation(-1); + } + } + + if(excedent < get_frames()) + frame += excedent; } } } @@ -176,8 +207,10 @@ Sprite::draw(DrawingContext& context, const Vector& pos, int layer, { update(); - if((int)frame >= get_frames()) - std::cerr << "Warning: frame higher than total frames!\n"; + if((int)frame >= get_frames() || (int)frame < 0) + std::cerr << "Warning: frame out of range: " << (int)frame + << "/" << get_frames() << " at sprite: " << get_name() + << "/" << get_action_name() << std::endl; else context.draw_surface(action->surfaces[(int)frame], pos - Vector(action->x_hotspot, action->y_hotspot), layer, drawing_effect);