/** * \brief Draws a specific frame of this animation on a surface. * \param dst_surface the surface on which the sprite will be drawn * \param dst_position coordinates on the destination surface * (the origin point will be drawn at this position) * \param current_direction the direction to show * \param current_frame the frame to show in this direction */ void SpriteAnimation::draw(Surface& dst_surface, const Rectangle& dst_position, int current_direction, int current_frame) { if (src_image != NULL) { if (current_direction < 0 || current_direction >= get_nb_directions()) { Debug::die(StringConcat() << "Invalid sprite direction " << current_direction << ": this sprite has " << get_nb_directions() << " direction(s)"); } directions[current_direction]->draw(dst_surface, dst_position, current_frame, *src_image); } }
/** * \brief Draws a specific frame of this animation on a surface. * \param dst_surface the surface on which the sprite will be drawn * \param dst_position coordinates on the destination surface * (the origin point will be drawn at this position) * \param current_direction the direction to show * \param current_frame the frame to show in this direction */ void SpriteAnimation::draw(Surface& dst_surface, const Point& dst_position, int current_direction, int current_frame) { if (src_image != nullptr) { if (current_direction < 0 || current_direction >= get_nb_directions()) { std::ostringstream oss; oss << "Invalid sprite direction " << current_direction << ": this sprite has " << get_nb_directions() << " direction(s)"; Debug::die(oss.str()); } directions[current_direction].draw(dst_surface, dst_position, current_frame, *src_image); } }
/** * \brief Returns the next frame of the current frame. * \param current_direction the current direction * \param current_frame the current frame * \return the next frame of the current frame in this direction * (or -1 if the animation is over) */ int SpriteAnimation::get_next_frame( int current_direction, int current_frame) const { if (current_direction < 0 || current_direction >= get_nb_directions()) { Debug::die(StringConcat() << "Invalid sprite direction '" << current_direction << "': this sprite has " << get_nb_directions() << " direction(s)"); } int next_frame = current_frame + 1; // if we are on the last frame if (next_frame == directions[current_direction]->get_nb_frames()) { // we loop on the appropriate frame // or -1 if there is no loop next_frame = loop_on_frame; } return next_frame; }
/** * \brief Sets the current direction of the sprite's animation and restarts the animation. * * If the specified direction is the current direction, nothing is done. * * \param current_direction the current direction */ void Sprite::set_current_direction(int current_direction) { if (current_direction != this->current_direction) { Debug::check_assertion(current_direction >= 0 && current_direction < get_nb_directions(), StringConcat() << "Invalid direction " << current_direction << " for sprite '" << get_animation_set_id() << "' in animation '" << current_animation_name << "'"); this->current_direction = current_direction; set_current_frame(0, false); if (lua_context != NULL) { lua_context->sprite_on_direction_changed(*this, current_animation_name, current_direction); lua_context->sprite_on_frame_changed(*this, current_animation_name, 0); } } }
/** * \brief Checks whether the frame has to be changed. * * If the frame changes, next_frame_date is updated. */ void Sprite::update() { Drawable::update(); if (suspended || paused) { return; } frame_changed = false; uint32_t now = System::now(); // update the current frame if (synchronize_to == NULL || current_animation_name != synchronize_to->get_current_animation() || synchronize_to->get_current_direction() > get_nb_directions() || synchronize_to->get_current_frame() > get_nb_frames()) { // update the frames normally (with the time) int next_frame; while (!finished && !suspended && !paused && get_frame_delay() > 0 && now >= next_frame_date) { // we get the next frame next_frame = get_next_frame(); // test whether the animation is finished if (next_frame == -1) { finished = true; if (lua_context != NULL) { lua_context->sprite_on_animation_finished(*this, current_animation_name); } } else { current_frame = next_frame; next_frame_date += get_frame_delay(); } set_frame_changed(true); if (lua_context != NULL) { lua_context->sprite_on_frame_changed(*this, current_animation_name, current_frame); } } } else { // take the same frame as the other sprite if (synchronize_to->is_animation_finished()) { finished = true; if (lua_context != NULL) { lua_context->sprite_on_animation_finished(*this, current_animation_name); } } else { int other_frame = synchronize_to->get_current_frame(); if (other_frame != current_frame) { current_frame = other_frame; next_frame_date = now + get_frame_delay(); set_frame_changed(true); if (lua_context != NULL) { lua_context->sprite_on_frame_changed(*this, current_animation_name, current_frame); } } } } // update the special effects if (is_blinking()) { // the sprite is blinking while (now >= blink_next_change_date) { blink_is_sprite_visible = !blink_is_sprite_visible; blink_next_change_date += blink_delay; } } }