X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=lib%2Fspecial%2Fsprite.cpp;h=f07cfc1efb18f5f7d4d0f3a9643af1f5bf24db33;hb=40e6e7cdc59c09befbd2595aea0c6e10428315d4;hp=75e6e5459f23f69dcbd26b4c1af885fddd9633e8;hpb=4b476ec30e7dd62249328054402d6493c20a685d;p=supertux.git diff --git a/lib/special/sprite.cpp b/lib/special/sprite.cpp index 75e6e5459..f07cfc1ef 100644 --- a/lib/special/sprite.cpp +++ b/lib/special/sprite.cpp @@ -16,116 +16,131 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include #include #include +#include +#include -#include "../app/globals.h" -#include "../app/setup.h" -#include "../special/sprite.h" -#include "../video/drawing_context.h" +#include "app/globals.h" +#include "app/setup.h" +#include "sprite.h" +#include "video/drawing_context.h" -using namespace SuperTux; - -Sprite::Sprite(lisp_object_t* cur) +namespace SuperTux { - init_defaults(); - - LispReader reader(cur); - - if(!reader.read_string("name", name)) - st_abort("Sprite wihtout name", ""); - reader.read_int("x-hotspot", x_hotspot); - reader.read_int("y-hotspot", y_hotspot); - reader.read_float("fps", fps); - - std::vector images; - if(!reader.read_string_vector("images", images)) - st_abort("Sprite contains no images: ", name.c_str()); - for(std::vector::size_type i = 0; i < images.size(); ++i) - { - surfaces.push_back( - new Surface(datadir + "/images/" + images[i], true)); - } +Sprite::Sprite(SpriteData& newdata) + : data(newdata), frame(0), animation_loops(-1) +{ + action = data.actions.begin()->second; + last_ticks = SDL_GetTicks(); +} - frame_delay = 1000.0f/fps; +Sprite::Sprite(const Sprite& other) + : data(other.data), frame(other.frame), + animation_loops(other.animation_loops), + action(other.action) +{ + last_ticks = SDL_GetTicks(); } Sprite::~Sprite() { - for(std::vector::iterator i = surfaces.begin(); i != surfaces.end(); - ++i) - delete *i; } void -Sprite::init_defaults() +Sprite::set_action(std::string name, int loops) { - x_hotspot = 0; - y_hotspot = 0; - fps = 10; - time = 0; - frame_delay = 1000.0f/fps; + if(action && action->name == name) + return; + + SpriteData::Action* newaction = data.get_action(name); + if(!newaction) { +#ifdef DEBUG + std::cerr << "Action '" << name << "' not found.\n"; +#endif + return; + } + + action = newaction; + animation_loops = loops; + frame = 0; } -void -Sprite::update(float /*delta*/) +bool +Sprite::check_animation() { - //time += 10*delta; - //std::cout << "Delta: " << delta << std::endl; + return animation_loops == 0; } void -Sprite::draw(DrawingContext& context, const Vector& pos, int layer, - Uint32 drawing_effect) +Sprite::update() { - time = SDL_GetTicks(); - unsigned int frame = get_current_frame(); + if(animation_loops == 0) + return; + + Uint32 ticks = SDL_GetTicks(); + float frame_inc = action->fps * float(ticks - last_ticks)/1000.0; + last_ticks = ticks; - if (frame < surfaces.size()) - { - Surface* surface = surfaces[frame]; + frame += frame_inc; + + if(frame >= get_frames()) { + frame = fmodf(frame+get_frames(), get_frames()); - context.draw_surface(surface, pos - Vector(x_hotspot, y_hotspot), layer, drawing_effect); + animation_loops--; + if(animation_loops == 0) + frame = 0; } } -#if 0 void -Sprite::draw_part(float sx, float sy, float x, float y, float w, float h) +Sprite::draw(DrawingContext& context, const Vector& pos, int layer, + Uint32 drawing_effect) { - time = SDL_GetTicks(); - unsigned int frame = get_current_frame(); - - if (frame < surfaces.size()) - surfaces[frame]->draw_part(sx, sy, x - x_hotspot, y - y_hotspot, w, h); + assert(action != 0); + update(); + + if((int)frame >= get_frames() || (int)frame < 0) + std::cerr << "Warning: frame out of range: " << (int)frame + << "/" << get_frames() << " at " << get_name() + << "/" << get_action_name() << std::endl; + else + context.draw_surface(action->surfaces[(int)frame], + pos - Vector(action->x_offset, action->y_offset), + layer + action->z_order, drawing_effect); } -#endif void -Sprite::reset() +Sprite::draw_part(DrawingContext& context, const Vector& source, + const Vector& size, const Vector& pos, int layer, Uint32 drawing_effect) { - time = 0; -} - -int -Sprite::get_current_frame() const -{ - unsigned int frame = static_cast(fmodf(time, surfaces.size()*frame_delay)/frame_delay); - return frame % surfaces.size(); + assert(action != 0); + update(); + + 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_part(action->surfaces[(int)frame], source, size, + pos - Vector(action->x_offset, action->y_offset), + layer + action->z_order, drawing_effect); } int Sprite::get_width() const { - return surfaces[get_current_frame()]->w; + return action->surfaces[get_frame()]->w; } int Sprite::get_height() const { - return surfaces[get_current_frame()]->h; + return action->surfaces[get_frame()]->h; +} + } -/* EOF */