X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=lib%2Fspecial%2Fsprite.cpp;h=82639166ed99f5b72abfe25a9f9c1e337f6bb186;hb=e4db6eb50cd6bcba607858b5e6c4c5d53531ed1f;hp=c6a3289a840d51a588282ac0b90ccceafdfaf0f7;hpb=5c83b03e600a26076dc2aecc9fe51fcd845b224a;p=supertux.git diff --git a/lib/special/sprite.cpp b/lib/special/sprite.cpp index c6a3289a8..82639166e 100644 --- a/lib/special/sprite.cpp +++ b/lib/special/sprite.cpp @@ -55,7 +55,10 @@ Sprite::~Sprite() { for(std::vector::iterator i_sur = i_act->second->surfaces.begin(); i_sur != i_act->second->surfaces.end(); ++i_sur) - delete *i_sur; + { + if(!i_act->second->mirror) + delete *i_sur; + } delete i_act->second; } } @@ -75,19 +78,53 @@ Sprite::parse_action(LispReader& lispreader) lispreader.read_int("z-order", action->z_order); lispreader.read_float("fps", action->fps); - std::vector images; - if(!lispreader.read_string_vector("images", images)) - Termination::abort("Sprite contains no images: ", action->name.c_str()); + /* TODO: add a top filter entry */ + std::vector mask_color; + lispreader.read_int_vector("apply-mask", mask_color); + if(mask_color.size() == 4) + { + for(std::vector::iterator i = action->surfaces.begin(); + i < action->surfaces.end(); i++) + { + (*i)->apply_mask(Color(mask_color)); + } + } - for(std::vector::size_type i = 0; i < images.size(); ++i) + action->mirror = false; + std::string mirror_action; + lispreader.read_string("mirror-action", mirror_action); + if(!mirror_action.empty()) { + action->mirror = true; + Action* act_tmp = get_action(mirror_action); + if(act_tmp == NULL) + std::cerr << "Warning: Could not mirror action. Action not found\n" + "Mirror actions must be defined after the real one!\n"; + else + action->surfaces = act_tmp->surfaces; + } + + // Load images + if(!action->mirror) + { + std::vector images; + if(!lispreader.read_string_vector("images", images)) + Termination::abort("Sprite contains no images: ", action->name); + + for(std::vector::size_type i = 0; i < images.size(); i++) + { action->surfaces.push_back( new Surface(datadir + "/images/" + images[i], true)); - } - + } + } actions[action->name] = action; } +/*void Sprite::parse_filter(LispReader& lispreader) +{ + +}*/ + void Sprite::init_defaults(Action* act) { @@ -116,6 +153,18 @@ if(i == actions.end()) action = i->second; } +Sprite::Action* +Sprite::get_action(std::string act) +{ +Actions::iterator i = actions.find(act); +if(i == actions.end()) + { + std::cerr << "Warning: Action '" << act << "' not found on Sprite '" << name << "'\n"; + return NULL; + } +return i->second; +} + void Sprite::start_animation(int loops) { @@ -153,7 +202,11 @@ void Sprite::update() { if(animation_loops == 0) + { + if(frame >= get_frames() || frame < 0) + frame = 0; return; + } float frame_inc = (action->fps/1000.0) * (SDL_GetTicks() - last_tick); last_tick = SDL_GetTicks(); @@ -165,9 +218,9 @@ else if(animation_reversed) { - float excedent = frame - 0; - if((int)excedent < 0 || excedent >= get_frames()) + if(frame < 0 || frame >= (float)get_frames()) { // last case can happen when not used reverse_animation() + float excedent = frame - 0; frame = get_frames() - 1; if(animation_loops > 0) { @@ -185,9 +238,9 @@ if(animation_reversed) } else { - float excedent = frame - action->surfaces.size(); - if((int)excedent >= 0) + if(frame >= (float)get_frames()) { + float excedent = frame - get_frames(); frame = 0; if(animation_loops > 0) { @@ -213,12 +266,12 @@ Sprite::draw(DrawingContext& context, const Vector& pos, int layer, if((int)frame >= get_frames() || (int)frame < 0) std::cerr << "Warning: frame out of range: " << (int)frame - << "/" << get_frames() << " at sprite: " << get_name() + << "/" << 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); + action->mirror ? drawing_effect | HORIZONTAL_FLIP : drawing_effect); } void @@ -234,7 +287,7 @@ Sprite::draw_part(DrawingContext& context, const Vector& source, const Vector& s 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); + action->mirror ? drawing_effect | HORIZONTAL_FLIP : drawing_effect); } int