bool unit_animation_component::invalidate (const display & disp) { bool result = false; // Very early calls, anim not initialized yet if(get_animation()) { frame_parameters params; const gamemap & map = disp.get_map(); const t_translation::t_terrain terrain = map.get_terrain(u_.loc_); const terrain_type& terrain_info = map.get_terrain_info(terrain); int height_adjust = static_cast<int>(terrain_info.unit_height_adjust() * disp.get_zoom_factor()); if (u_.is_flying() && height_adjust < 0) { height_adjust = 0; } params.y -= height_adjust; params.halo_y -= height_adjust; params.image_mod = u_.image_mods(); params.halo_mod = u_.TC_image_mods(); params.image= u_.absolute_image(); result |= get_animation()->invalidate(params); } return result; }
/** * @brief Returns whether is the source image of an animation is a tileset. * @param index An animation index. * @return \c true if the animation's source image is a tileset. */ bool SpriteModel::is_animation_image_is_tileset(const Index& index) const { if (!animation_exists(index)) { return false; } return get_animation(index).src_image_is_tileset(); }
/** * @brief Returns the source image of an animation. * @param index An animation index. * @return The animation's source image. */ QString SpriteModel::get_animation_source_image(const Index& index) const { if (!animation_exists(index)) { return ""; } return get_animation(index).get_src_image().c_str(); }
/** * @brief Returns an animation data. * @param index An animation index. * @return The animation data. */ SpriteAnimationData SpriteModel::get_animation_data(const Index& index) const { if (!animation_exists(index)) { return SpriteAnimationData(); } return get_animation(index); }
/** * @brief Returns the number of directions in an animation. * @param index An animation index. * @return The animation's number of directions. */ int SpriteModel::get_animation_num_directions(const Index& index) const { if (!animation_exists(index)) { return 0; } return get_animation(index).get_num_directions(); }
/** * @brief Returns the frame delay of an animation. * @param index An animation index. * @return The animation's frame delay. */ uint32_t SpriteModel::get_animation_frame_delay(const Index& index) const { if (!animation_exists(index)) { return 0; } return get_animation(index).get_frame_delay(); }
/** * @brief Returns the loop on frame of an animation. * @param index An animation index. * @return The animation's loop on frame. */ int SpriteModel::get_animation_loop_on_frame(const Index& index) const { if (!animation_exists(index)) { return -1; } return get_animation(index).get_loop_on_frame(); }
/** * \brief Do one iteration in the progression of the item. */ void bear::decorative_item::progress( universe::time_type elapsed_time ) { super::progress(elapsed_time); if ( m_kill_on_contact && has_contact() ) kill(); else if ( m_kill_when_finished && get_animation().is_finished() ) kill(); } // decorative_item::progress()
static void change_to_laser(Bat *bat) { remove_from_canvas((Entity *) bat); bat->animation = get_animation(ANIM_BAT_LASER); add_to_canvas((Entity *) bat); bat->num_lasers = 0; bat->num_lasers_allowed = 1; bat->type = BAT_LASER; }
static void reset_from_laser(Bat *bat) { destroy_children_laser(bat); bat->num_lasers_allowed = 0; remove_from_canvas((Entity *) bat); bat->animation = get_animation(ANIM_BAT_DEFAULT); add_to_canvas((Entity *) bat); bat->type = BAT_DEFAULT; }
static void reset_from_wide(Bat *bat) { bat->width = BAT_WIDTH; bat->geometry.x1 += (BAT_WIDE_WIDTH - BAT_WIDTH) / 2; bat->geometry.x2 = bat->geometry.x1 + bat->width; bat->type = BAT_DEFAULT; remove_from_canvas((Entity *) bat); bat->animation = get_animation(ANIM_BAT_DEFAULT); add_to_canvas((Entity *) bat); }
/** * @brief Moves a direction. * @param index Index of the direction to move. * @param new_direction_nb The new number of the direction. * @throws EditorException in case of error. */ void SpriteModel::move_direction(const Index& index, int new_direction_nb) { if (new_direction_nb == index.direction_nb) { // Nothing to do. return; } // Make some checks first. if (!direction_exists(index)) { QString nb = std::to_string(index.direction_nb).c_str(); throw EditorException( tr("Direction %1 don't exists in animation '%2'").arg( nb, index.animation_name)); } // Save and clear the selection. Index selection = get_selected_index(); clear_selection(); // Move the direction in the sprite file. get_animation(index).move_direction(index.direction_nb, new_direction_nb); // Call beginMoveRows() as requested by QAbstractItemModel. int above_row = new_direction_nb; if (new_direction_nb > index.direction_nb) { ++above_row; } QModelIndex model_index = get_model_index(Index(index.animation_name)); beginMoveRows(model_index, index.direction_nb, index.direction_nb, model_index, above_row); // Update our animation model list. int animation_nb = get_animation_nb(index); animations[animation_nb].directions.move(index.direction_nb, new_direction_nb); // Update direction model indexes. int num_dir = animations[animation_nb].directions.size(); for (int nb = 0; nb < num_dir; nb++) { animations[animation_nb].directions[nb].index->direction_nb = nb; } endMoveRows(); // Notify people before restoring the selection, so that they have a // chance to know new indexes before receiving selection signals. emit direction_deleted(index); // Restore the selection. if (selection.direction_nb == index.direction_nb) { selection.direction_nb = new_direction_nb; } set_selected_index(selection); }
bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name == "playback/speed") { //bw compatibility r_ret = speed_scale; } else if (name == "playback/active") { r_ret = is_active(); } else if (name == "playback/play") { if (is_active() && is_playing()) r_ret = playback.assigned; else r_ret = "[stop]"; } else if (name.begins_with("anims/")) { String which = name.get_slicec('/', 1); r_ret = get_animation(which).get_ref_ptr(); } else if (name.begins_with("next/")) { String which = name.get_slicec('/', 1); r_ret = animation_get_next(which); } else if (name == "blend_times") { Vector<BlendKey> keys; for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) { keys.ordered_insert(E->key()); } Array array; for (int i = 0; i < keys.size(); i++) { array.push_back(keys[i].from); array.push_back(keys[i].to); array.push_back(blend_times[keys[i]]); } r_ret = array; } else if (name == "autoplay") { r_ret = autoplay; } else return false; return true; }
static void change_to_wide(Bat *bat) { bat->width = BAT_WIDE_WIDTH; bat->geometry.x1 -= (BAT_WIDE_WIDTH - BAT_WIDTH) / 2; if(bat->geometry.x1 < 0) bat->geometry.x1 = 0; bat->geometry.x2 = bat->geometry.x1 + bat->width; bat->type = BAT_WIDE; remove_from_canvas((Entity *) bat); bat->animation = get_animation(ANIM_BAT_WIDE); add_to_canvas((Entity *) bat); }
bool AnimationPlayer::_get(const StringName& p_name,Variant &r_ret) const { String name=p_name; if (name=="playback/speed") { //bw compatibility r_ret=speed_scale; } else if (name=="playback/active") { r_ret=is_active(); } else if (name=="playback/play") { if (is_active() && is_playing()) r_ret=playback.assigned; else r_ret="[stop]"; } else if (name.begins_with("anims/")) { String which=name.get_slicec('/',1); r_ret= get_animation(which).get_ref_ptr(); } else if (name.begins_with("next/")) { String which=name.get_slicec('/',1); r_ret= animation_get_next(which); } else if (name=="blend_times") { Array array; array.resize(blend_times.size()*3); int idx=0; for(Map<BlendKey, float >::Element *E=blend_times.front();E;E=E->next()) { array.set(idx*3+0,E->key().from); array.set(idx*3+1,E->key().to); array.set(idx*3+2,E->get()); idx++; } r_ret=array; } else if (name=="autoplay") { r_ret=autoplay; } else return false; return true; }
void Active::set_animation(int value) { if (value == animation) return; value = get_animation(value); if (value == animation) return; animation = value; if (forced_animation >= 0) return; animation_frame = 0; current_animation = animation; update_direction(); }
/** * @brief Sets the loop on frame of an animation. * * Emits animation_loop_on_frame_changed() if there is a change. * * @param index An animation index. * @param loop_on_frame The loop on frame to set. */ void SpriteModel::set_animation_loop_on_frame( const Index& index, int loop_on_frame) { if (!animation_exists(index)) { return; } SpriteAnimationData& animation = get_animation(index); if (animation.get_loop_on_frame() == loop_on_frame) { return; } animation.set_loop_on_frame(loop_on_frame); emit animation_loop_on_frame_changed(index, loop_on_frame); }
/** * @brief Sets the frame delay of an animation. * * Emits animation_frame_delay_changed() if there is a change. * * @param index An animation index. * @param frame_delay The frame delay to set. */ void SpriteModel::set_animation_frame_delay( const Index& index, uint32_t frame_delay) { if (!animation_exists(index)) { return; } SpriteAnimationData& animation = get_animation(index); if (animation.get_frame_delay() == frame_delay) { return; } animation.set_frame_delay(frame_delay); emit animation_frame_delay_changed(index, frame_delay); }
/** * @brief Inserts a direction in an animation of this sprite. * @param index Index of the direction to insert. * @param data The direction data to insert. * @return Index of the inserted direction. * @throws EditorException in case of error. */ int SpriteModel::insert_direction( const Index& index, const SpriteAnimationDirectionData& data) { // Make some checks first. if (!animation_exists(index)) { throw EditorException( tr("Animation '%1' don't exists").arg(index.animation_name)); } // Save and clear the selection. Index selection = get_selected_index(); clear_selection(); // Insert the direction to the sprite file. SpriteAnimationData& animation_data = get_animation(index); animation_data.add_direction(data); int last_dir = animation_data.get_num_directions() - 1; animation_data.move_direction(last_dir, index.direction_nb); int direction_nb = std::min(index.direction_nb, last_dir); // Call beginInsertRows() as requested by QAbstractItemModel. QModelIndex model_index = get_model_index(Index(index.animation_name)); beginInsertRows(model_index, direction_nb, direction_nb); // Update our animation model list. int animation_nb = get_animation_nb(index); auto& directions = animations[animation_nb].directions; directions.insert( direction_nb, DirectionModel(index.animation_name, direction_nb)); // Update direction model indexes. for (int nb = direction_nb + 1; nb < directions.size(); nb++) { directions[nb].index->direction_nb = nb; } // Notify people before restoring the selection, so that they have a // chance to know new indexes before receiving selection signals. endInsertRows(); emit direction_added(Index(index.animation_name, direction_nb)); // Restore the selection. set_selected_index(selection); return direction_nb; }
bool play_seq( const std::vector<unsigned> &new_playlist ) { auto filtered = filter( new_playlist ); if( filtered.empty() ) { return false; } if( playlist != filtered || ( !get_animation().loopable && has_playlist_finished() ) ) { factor = {1}; frame = 0; selected = 0; playlist = filtered; return true; } else { factor = {1}; playlist = filtered; return false; } }
static void iterate_bat_laser(Game *game) { gboolean kill_laser = FALSE; gint bat_center; Block *block; GList *children; Entity *laser; children = game->bat->children; while(children) { laser = (Entity *) children->data; children = g_list_next(children); laser->geometry.y1 -= LASER_SPEED; laser->geometry.y2 -= LASER_SPEED; if(laser->geometry.y1 < 0) { kill_laser = TRUE; } else if((block = find_block_from_position(game, laser))) { if(block->type != BLOCK_DEAD) { hit_block(game, block); kill_laser = TRUE; } } if(kill_laser) { remove_child_laser(game->bat, laser); } else { update_canvas_position(laser); } } if(game->fire1_pressed && game->bat->num_lasers_allowed > game->bat->num_lasers ) { bat_center = game->bat->geometry.x1 + game->bat->width / 2; laser = g_malloc(sizeof(Entity)); laser->geometry.x1 = bat_center - LASER_WIDTH / 2; laser->geometry.x2 = laser->geometry.x1 + LASER_WIDTH; laser->geometry.y2 = game->bat->geometry.y1; laser->geometry.y1 = laser->geometry.y2 - LASER_HEIGHT; laser->animation = get_animation(ANIM_LASER); add_to_canvas(laser); game->bat->num_lasers++; game->bat->children = g_list_prepend(game->bat->children, laser); } }
/** * @brief Sets the source image of an animation. * * Emits animation_image_changed() if there is a change. * * @param index An animation index. * @param src_image The source image to set. */ void SpriteModel::set_animation_source_image( const Index& index, const QString& src_image) { if (!animation_exists(index)) { return; } SpriteAnimationData& animation = get_animation(index); if (animation.get_src_image() == src_image.toStdString()) { return; } animation.set_src_image(src_image.toStdString()); set_animation_image_dirty(index); emit animation_image_changed(index, src_image); }
void Active::force_animation(int value) { if (value == forced_animation) return; value = get_animation(value); if (value == forced_animation) return; if (flags & FADEOUT) { FrameObject::destroy(); return; } forced_animation = value; if (value == current_animation) return; animation_frame = 0; current_animation = value; update_direction(); }
/** * @brief Deletes a direction. * @param index Index of the direction to delete. * @throws EditorException in case of error. */ void SpriteModel::delete_direction(const Index &index) { // Make some checks first. if (!direction_exists(index)) { QString nb = std::to_string(index.direction_nb).c_str(); throw EditorException( tr("Direction %1 don't exists in animation '%2'").arg( nb, index.animation_name)); } // Save and clear the selection. Index selection = get_selected_index(); if (selection.animation_name == index.animation_name && selection.direction_nb == index.direction_nb) { selection.direction_nb = -1; } clear_selection(); // Delete the direction in the sprite file. get_animation(index).remove_direction(index.direction_nb); // Call beginRemoveRows() as requested by QAbstractItemModel. QModelIndex model_index = get_model_index(Index(index.animation_name)); beginRemoveRows(model_index, index.direction_nb, index.direction_nb); // Update our direction model list. int animation_nb = get_animation_nb(index); auto& directions = animations[animation_nb].directions; directions.removeAt(index.direction_nb); // Update direction model indexes. for (int nb = index.direction_nb; nb < directions.size(); nb++) { directions[nb].index->direction_nb = nb; } // Notify people before restoring the selection, so that they have a // chance to know new indexes before receiving selection signals. endRemoveRows(); emit direction_deleted(index); // Restore the selection. set_selected_index(selection); }
/** * @brief Adds a direction in an animation of this sprite. * @param index Index of the animation to add the direction. * @param frame The first frame of the direction to create. * @return Index of the created direction. * @throws EditorException in case of error. */ int SpriteModel::add_direction(const Index& index, const QRect& frame) { // Make some checks first. if (!animation_exists(index)) { throw EditorException( tr("Animation '%1' don't exists").arg(index.animation_name)); } // Save and clear the selection. Index selection = get_selected_index(); clear_selection(); // Add the direction to the sprite file. SpriteAnimationData& animation_data = get_animation(index); SpriteAnimationDirectionData direction( Point::to_solarus_point(frame.topLeft()), Size::to_solarus_size(frame.size())); animation_data.add_direction(direction); // Rebuild indexes in the list model (indexes were shifted). int direction_nb = animation_data.get_num_directions() - 1; // Call beginInsertRows() as requested by QAbstractItemModel. QModelIndex model_index = get_model_index(Index(index.animation_name)); beginInsertRows(model_index, direction_nb, direction_nb); // Update our animation model list. int animation_nb = get_animation_nb(index); animations[animation_nb].directions.append( DirectionModel(index.animation_name, direction_nb)); // Notify people before restoring the selection, so that they have a // chance to know new indexes before receiving selection signals. endInsertRows(); emit direction_added(Index(index.animation_name, direction_nb)); // Restore the selection. set_selected_index(selection); return direction_nb; }
void DisplayObject::draw(const int_32 & _std_x , const int_32 & _std_y) { int_32 _x = m_x - _std_x; int_32 _y = m_y - _std_y; if(m_animation_table.size() == 0) { return; } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, get_animation()->get_frame()); glBegin(GL_POLYGON); glTexCoord2f(0.0f, 1.0f);glVertex2d(_x, _y); glTexCoord2f(1.0f, 1.0f);glVertex2d(_x + m_width, _y); glTexCoord2f(1.0f, 0.0f);glVertex2d(_x + m_width, _y + m_height); glTexCoord2f(0.0f, 0.0f);glVertex2d(_x, _y + m_height); glEnd(); glDisable(GL_BLEND); }
/** * @brief Creates a sprite model. * @param quest The quest. * @param sprite_id Id of the sprite to manage. * @param parent The parent object or nullptr. * @throws EditorException If the file could not be opened. */ SpriteModel::SpriteModel( Quest& quest, const QString& sprite_id, QObject* parent) : QAbstractItemModel(parent), quest(quest), sprite_id(sprite_id), selection_model(this) { // Load the sprite data file. QString path = quest.get_sprite_path(sprite_id); if (!sprite.import_from_file(path.toStdString())) { throw EditorException(tr("Cannot open sprite '%1'").arg(path)); } // Build the index map of animations. build_index_map(); // Create animations and directions models. for (const auto& kvp : names_to_indexes) { const QString& animation_name = kvp.first; AnimationModel animation(animation_name); int num_dir = get_animation(animation_name).get_num_directions(); for (int nb = 0; nb < num_dir; nb++) { animation.directions.append(DirectionModel(animation_name, nb)); } animations.append(animation); } // use the first tileset of the quest QStringList tilesets = quest.get_resources().get_elements(ResourceType::TILESET); if (tilesets.size() > 0) { tileset_id = tilesets[0]; } }
void update() { const auto &anim = get_animation(); // exec events, if any anim.execute(frame); // check status if( !has_animation_finished() ) { frame = floor( frame + factor.back() ); } else { if( anim.loopable ) { frame = 0; //-= get_animation().frames(); return; } pop_factor(); // change to next animation if( !has_playlist_finished() ) { selected++; frame = 0; } else { // keep anim & pose selected = selected; frame = frame; } } }
bool has_animation_finished() const { return get_animation().has_finished(frame); }
std::string str() const { return wire::string("[\1%] \2 \3/\4", int(progress()), get_animation().name, get_frame(), get_animation().end); }