完成动画组件与动画载入
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
#include "animation_component.h"
|
||||
#include "sprite_component.h"
|
||||
#include "../object/game_object.h"
|
||||
#include "../render/animation.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace engine::component {
|
||||
|
||||
AnimationComponent::~AnimationComponent() = default;
|
||||
|
||||
void AnimationComponent::init() {
|
||||
if (!owner_) {
|
||||
spdlog::error("AnimationComponent 没有所有者 GameObject!");
|
||||
return;
|
||||
}
|
||||
sprite_component_ = owner_->getComponent<SpriteComponent>();
|
||||
if (!sprite_component_) {
|
||||
spdlog::error("GameObject '{}' 的 AnimationComponent 需要 SpriteComponent,但未找到。", owner_->getName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationComponent::update(float delta_time, engine::core::Context&) {
|
||||
// 如果没有正在播放的动画,或者没有当前动画,或者没有精灵组件,或者当前动画没有帧,则直接返回
|
||||
if (!is_playing_ || !current_animation_ || !sprite_component_ || current_animation_->isEmpty()) {
|
||||
spdlog::trace("AnimationComponent 更新时没有正在播放的动画或精灵组件为空。");
|
||||
return;
|
||||
}
|
||||
|
||||
// 推进计时器
|
||||
animation_timer_ += delta_time;
|
||||
|
||||
// 根据时间获取当前帧
|
||||
const auto& current_frame = current_animation_->getFrame(animation_timer_);
|
||||
|
||||
// 更新精灵组件的源矩形 (使用 SpriteComponent 的新方法)
|
||||
sprite_component_->setSourceRect(current_frame.source_rect);
|
||||
|
||||
// 检查非循环动画是否已结束
|
||||
if (!current_animation_->isLooping() && animation_timer_ >= current_animation_->getTotalDuration()) {
|
||||
is_playing_ = false;
|
||||
animation_timer_ = current_animation_->getTotalDuration(); // 将时间限制在结束点
|
||||
if (is_one_shot_removal_) { // 如果 is_one_shot_removal_ 为 true,则删除整个 GameObject
|
||||
owner_->setNeedRemove(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationComponent::addAnimation(std::unique_ptr<engine::render::Animation> animation) {
|
||||
if (!animation) return;
|
||||
std::string name = animation->getName(); // 获取名称
|
||||
animations_[name] = std::move(animation);
|
||||
spdlog::debug("已将动画 '{}' 添加到 GameObject '{}'", name, owner_ ? owner_->getName() : "未知");
|
||||
}
|
||||
|
||||
void AnimationComponent::playAnimation(const std::string& name) {
|
||||
auto it = animations_.find(name);
|
||||
if (it == animations_.end() || !it->second) {
|
||||
spdlog::warn("未找到 GameObject '{}' 的动画 '{}'", name, owner_ ? owner_->getName() : "未知");
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果已经在播放相同的动画,不重新开始(注释这一段则重新开始播放)
|
||||
if (current_animation_ == it->second.get() && is_playing_) {
|
||||
return;
|
||||
}
|
||||
|
||||
current_animation_ = it->second.get();
|
||||
animation_timer_ = 0.0f;
|
||||
is_playing_ = true;
|
||||
|
||||
// 立即将精灵更新到第一帧
|
||||
if (sprite_component_ && !current_animation_->isEmpty()) {
|
||||
const auto& first_frame = current_animation_->getFrame(0.0f);
|
||||
sprite_component_->setSourceRect(first_frame.source_rect);
|
||||
spdlog::debug("GameObject '{}' 播放动画 '{}'", owner_ ? owner_->getName() : "未知", name);
|
||||
}
|
||||
}
|
||||
|
||||
std::string AnimationComponent::getCurrentAnimationName() const {
|
||||
if (current_animation_) {
|
||||
return current_animation_->getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool AnimationComponent::isAnimationFinished() const {
|
||||
// 如果没有当前动画(说明从未调用过playAnimation),或者当前动画是循环的,则返回 false
|
||||
if (!current_animation_ || current_animation_->isLooping()) {
|
||||
return false;
|
||||
}
|
||||
return animation_timer_ >= current_animation_->getTotalDuration();
|
||||
}
|
||||
|
||||
} // namespace engine::component
|
||||
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
#include "./component.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
namespace engine::render {
|
||||
class Animation;
|
||||
}
|
||||
namespace engine::component {
|
||||
class SpriteComponent;
|
||||
}
|
||||
|
||||
namespace engine::component {
|
||||
|
||||
/**
|
||||
* @brief GameObject的动画组件。
|
||||
*
|
||||
* 持有一组Animation对象并控制其播放,
|
||||
* 根据当前帧更新关联的SpriteComponent。
|
||||
*/
|
||||
class AnimationComponent : public Component {
|
||||
friend class engine::object::GameObject;
|
||||
private:
|
||||
/// @brief 动画名称到Animation对象的映射。
|
||||
std::unordered_map<std::string, std::unique_ptr<engine::render::Animation>> animations_;
|
||||
SpriteComponent* sprite_component_ = nullptr; ///< @brief 指向必需的SpriteComponent的指针
|
||||
engine::render::Animation* current_animation_ = nullptr; ///< @brief 指向当前播放动画的原始指针
|
||||
|
||||
float animation_timer_ = 0.0f; ///< @brief 动画播放中的计时器
|
||||
bool is_playing_ = false; ///< @brief 当前是否有动画正在播放
|
||||
bool is_one_shot_removal_ = false; ///< @brief 是否在动画结束后删除整个GameObject
|
||||
|
||||
public:
|
||||
AnimationComponent() = default;
|
||||
~AnimationComponent() override;
|
||||
|
||||
// 删除复制/移动操作
|
||||
AnimationComponent(const AnimationComponent&) = delete;
|
||||
AnimationComponent& operator=(const AnimationComponent&) = delete;
|
||||
AnimationComponent(AnimationComponent&&) = delete;
|
||||
AnimationComponent& operator=(AnimationComponent&&) = delete;
|
||||
|
||||
void addAnimation(std::unique_ptr<engine::render::Animation> animation); ///< @brief 向 animations_ map容器中添加一个动画。
|
||||
void playAnimation(const std::string& name); ///< @brief 播放指定名称的动画。
|
||||
void stopAnimation() { is_playing_ = false; } ///< @brief 停止当前动画播放。
|
||||
|
||||
// --- Getters and Setters ---
|
||||
std::string getCurrentAnimationName() const;
|
||||
bool isPlaying() const { return is_playing_; }
|
||||
bool isAnimationFinished() const;
|
||||
bool isOneShotRemoval() const { return is_one_shot_removal_; }
|
||||
void setOneShotRemoval(bool is_one_shot_removal) { is_one_shot_removal_ = is_one_shot_removal; }
|
||||
|
||||
protected:
|
||||
// 核心循环方法
|
||||
void init() override;
|
||||
void update(float, engine::core::Context&) override;
|
||||
};
|
||||
|
||||
} // namespace engine::component
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "animation.h"
|
||||
#include <glm/common.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace engine::render {
|
||||
|
||||
Animation::Animation(const std::string& name, bool loop)
|
||||
: name_(name), loop_(loop) {}
|
||||
|
||||
void Animation::addFrame(const SDL_FRect& source_rect, float duration) {
|
||||
if (duration <= 0.0f) {
|
||||
spdlog::warn("尝试向动画 '{}' 添加无效持续时间的帧", name_);
|
||||
return;
|
||||
}
|
||||
frames_.push_back({source_rect, duration});
|
||||
total_duration_ += duration;
|
||||
}
|
||||
|
||||
const AnimationFrame& Animation::getFrame(float time) const {
|
||||
if (frames_.empty()) {
|
||||
spdlog::error("动画 '{}' 没有帧,无法获取帧", name_);
|
||||
return frames_.back(); // 返回最后一帧(空的)
|
||||
}
|
||||
|
||||
float current_time = time;
|
||||
|
||||
if (loop_ && total_duration_ > 0.0f) {
|
||||
// 对循环动画使用模运算获取有效时间
|
||||
current_time = glm::mod(time, total_duration_);
|
||||
} else {
|
||||
// 对于非循环动画,如果时间超过总时长,则停留在最后一帧
|
||||
if (current_time >= total_duration_) {
|
||||
return frames_.back();
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历帧以找到正确的帧
|
||||
float accumulated_time = 0.0f;
|
||||
for (const auto& frame : frames_) {
|
||||
accumulated_time += frame.duration;
|
||||
if (current_time < accumulated_time) {
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
|
||||
// 理论上在不应到达这里,但为了安全起见,返回最后一帧
|
||||
spdlog::warn("动画 '{}' 在获取帧信息时出现错误。", name_);
|
||||
return frames_.back();
|
||||
}
|
||||
|
||||
} // namespace engine::render
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
#include <SDL3/SDL_rect.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace engine::render {
|
||||
|
||||
/**
|
||||
* @brief 代表动画中的单个帧。
|
||||
*
|
||||
* 包含纹理图集上的源矩形和该帧的显示持续时间。
|
||||
*/
|
||||
struct AnimationFrame {
|
||||
SDL_FRect source_rect; ///< @brief 纹理图集上此帧的区域
|
||||
float duration; ///< @brief 此帧显示的持续时间(秒)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 管理一系列动画帧。
|
||||
*
|
||||
* 存储动画的帧、总时长、名称和循环行为。
|
||||
*/
|
||||
class Animation final {
|
||||
private:
|
||||
std::string name_; ///< @brief 动画的名称 (例如, "walk", "idle")。
|
||||
std::vector<AnimationFrame> frames_; ///< @brief 动画帧列表
|
||||
float total_duration_ = 0.0f; ///< @brief 动画的总持续时间(秒)
|
||||
bool loop_ = true; ///< @brief 默认动画是循环的
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数
|
||||
* @param name 动画的名称。
|
||||
* @param loop 动画是否应该循环播放。
|
||||
*/
|
||||
Animation(const std::string& name = "default", bool loop = true);
|
||||
~Animation() = default;
|
||||
|
||||
// 禁止拷贝和移动,因为 Animation 通常由管理器持有,不应随意拷贝
|
||||
Animation(const Animation&) = delete;
|
||||
Animation& operator=(const Animation&) = delete;
|
||||
Animation(Animation&&) = delete;
|
||||
Animation& operator=(Animation&&) = delete;
|
||||
|
||||
/**
|
||||
* @brief 向动画添加一帧。
|
||||
*
|
||||
* @param source_rect 纹理图集上此帧的区域。
|
||||
* @param duration 此帧应显示的持续时间(秒)。
|
||||
*/
|
||||
void addFrame(const SDL_FRect& source_rect, float duration);
|
||||
|
||||
/**
|
||||
* @brief 获取在给定时间点应该显示的动画帧。
|
||||
* @param time 当前时间(秒)。如果动画循环,则可以超过总持续时间。
|
||||
* @return 对应时间点的动画帧。
|
||||
*/
|
||||
const AnimationFrame& getFrame(float time) const;
|
||||
|
||||
// --- Setters and Getters ---
|
||||
const std::string& getName() const { return name_; } ///< @brief 获取动画名称。
|
||||
const std::vector<AnimationFrame>& getFrames() const { return frames_; } ///< @brief 获取动画帧列表。
|
||||
size_t getFrameCount() const { return frames_.size(); } ///< @brief 获取帧数量。
|
||||
float getTotalDuration() const { return total_duration_; } ///< @brief 获取动画的总持续时间(秒)。
|
||||
bool isLooping() const { return loop_; } ///< @brief 检查动画是否循环播放。
|
||||
bool isEmpty() const { return frames_.empty(); } ///< @brief 检查动画是否没有帧。
|
||||
|
||||
void setName(const std::string& name) { name_ = name; } ///< @brief 设置动画名称。
|
||||
void setLooping(bool loop) { loop_ = loop; } ///< @brief 设置动画是否循环播放。
|
||||
|
||||
};
|
||||
|
||||
} // namespace engine::render
|
||||
@@ -5,11 +5,13 @@
|
||||
#include "../component/sprite_component.h"
|
||||
#include "../component/collider_component.h"
|
||||
#include "../component/physics_component.h"
|
||||
#include "../component/animation_component.h"
|
||||
#include "../object/game_object.h"
|
||||
#include "../scene/scene.h"
|
||||
#include "../core/context.h"
|
||||
#include "../resource/resource_manager.h"
|
||||
#include "../render/sprite.h"
|
||||
#include "../render/animation.h"
|
||||
#include "../utils/math.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <fstream>
|
||||
@@ -229,6 +231,23 @@ void LevelLoader::loadObjectLayer(const nlohmann::json& layer_json, Scene& scene
|
||||
}
|
||||
}
|
||||
|
||||
// 获取动画信息并设置
|
||||
auto anim_string = getTileProperty<std::string>(tile_json, "animation");
|
||||
if (anim_string) {
|
||||
// 解析string为JSON对象
|
||||
nlohmann::json anim_json;
|
||||
try {
|
||||
anim_json = nlohmann::json::parse(anim_string.value());
|
||||
} catch (const nlohmann::json::parse_error& e) {
|
||||
spdlog::error("解析动画 JSON 字符串失败: {}", e.what());
|
||||
continue; // 跳过此对象
|
||||
}
|
||||
// 添加AnimationComponent
|
||||
auto* ac = game_object->addComponent<engine::component::AnimationComponent>();
|
||||
// 添加动画到 AnimationComponent
|
||||
addAnimation(anim_json, ac, src_size);
|
||||
}
|
||||
|
||||
// 添加到场景中
|
||||
scene.addGameObject(std::move(game_object));
|
||||
spdlog::info("加载对象: '{}' 完成", object_name);
|
||||
@@ -236,6 +255,55 @@ void LevelLoader::loadObjectLayer(const nlohmann::json& layer_json, Scene& scene
|
||||
}
|
||||
}
|
||||
|
||||
void LevelLoader::addAnimation(const nlohmann::json& anim_json, engine::component::AnimationComponent *ac, const glm::vec2& sprite_size)
|
||||
{
|
||||
// 检查 anim_json 必须是一个对象,并且 ac 不能为 nullptr
|
||||
if (!anim_json.is_object() || !ac) {
|
||||
spdlog::error("无效的动画 JSON 或 AnimationComponent 指针。");
|
||||
return;
|
||||
}
|
||||
// 遍历动画 JSON 对象中的每个键值对(动画名称 : 动画信息)
|
||||
for (const auto& anim : anim_json.items()) {
|
||||
const std::string& anim_name = anim.key();
|
||||
const auto& anim_info = anim.value();
|
||||
if (!anim_info.is_object()) {
|
||||
spdlog::warn("动画 '{}' 的信息无效或为空。", anim_name);
|
||||
continue;
|
||||
}
|
||||
// 获取可能存在的动画帧信息
|
||||
auto duration_ms = anim_info.value("duration", 100); // 默认持续时间为100毫秒
|
||||
auto duration = static_cast<float>(duration_ms) / 1000.0f; // 转换为秒
|
||||
auto row = anim_info.value("row", 0); // 默认行数为0
|
||||
// 帧信息(数组)是必须存在的
|
||||
if (!anim_info.contains("frames") || !anim_info["frames"].is_array()) {
|
||||
spdlog::warn("动画 '{}' 缺少 'frames' 数组。", anim_name);
|
||||
continue;
|
||||
}
|
||||
// 创建一个Animation对象 (默认为循环播放)
|
||||
auto animation = std::make_unique<engine::render::Animation>(anim_name);
|
||||
|
||||
// 遍历数组并进行添加帧信息到animation对象
|
||||
for (const auto& frame : anim_info["frames"]) {
|
||||
if (!frame.is_number_integer()) {
|
||||
spdlog::warn("动画 {} 中 frames 数组格式错误!", anim_name);
|
||||
continue;;
|
||||
}
|
||||
auto column = frame.get<int>();
|
||||
// 计算源矩形
|
||||
SDL_FRect src_rect = {
|
||||
column * sprite_size.x,
|
||||
row * sprite_size.y,
|
||||
sprite_size.x,
|
||||
sprite_size.y
|
||||
};
|
||||
// 添加动画帧到 Animation
|
||||
animation->addFrame(src_rect, duration);
|
||||
}
|
||||
// 将 Animation 对象添加到 AnimationComponent 中
|
||||
ac->addAnimation(std::move(animation));
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<engine::utils::Rect> LevelLoader::getColliderRect(const nlohmann::json &tile_json)
|
||||
{
|
||||
if (!tile_json.contains("objectgroup")) return std::nullopt;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../utils/math.h"
|
||||
|
||||
namespace engine::component {
|
||||
class AnimationComponent;
|
||||
struct TileInfo;
|
||||
enum class TileType;
|
||||
}
|
||||
@@ -39,6 +40,14 @@ private:
|
||||
void loadTileLayer(const nlohmann::json& layer_json, Scene& scene); ///< @brief 加载瓦片图层
|
||||
void loadObjectLayer(const nlohmann::json& layer_json, Scene& scene); ///< @brief 加载对象图层
|
||||
|
||||
/**
|
||||
* @brief 添加动画到指定的 AnimationComponent。
|
||||
* @param anim_json 动画json数据(自定义)
|
||||
* @param ac AnimationComponent 指针(动画添加到此组件)
|
||||
* @param sprite_size 每一帧动画的尺寸
|
||||
*/
|
||||
void addAnimation(const nlohmann::json& anim_json, engine::component::AnimationComponent* ac, const glm::vec2& sprite_size);
|
||||
|
||||
/**
|
||||
* @brief 获取瓦片属性
|
||||
* @tparam T 属性类型
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../../engine/component/transform_component.h"
|
||||
#include "../../engine/component/physics_component.h"
|
||||
#include "../../engine/component/sprite_component.h"
|
||||
#include "../../engine/component/animation_component.h"
|
||||
#include "../../engine/object/game_object.h"
|
||||
#include "../../engine/input/input_manager.h"
|
||||
#include <utility>
|
||||
@@ -21,9 +22,10 @@ void PlayerComponent::init() {
|
||||
transform_component_ = owner_->getComponent<engine::component::TransformComponent>();
|
||||
physics_component_ = owner_->getComponent<engine::component::PhysicsComponent>();
|
||||
sprite_component_ = owner_->getComponent<engine::component::SpriteComponent>();
|
||||
animation_component_ = owner_->getComponent<engine::component::AnimationComponent>();
|
||||
|
||||
// 检查必要组件是否存在
|
||||
if (!transform_component_ || !physics_component_ || !sprite_component_) {
|
||||
if (!transform_component_ || !physics_component_ || !sprite_component_ || !animation_component_) {
|
||||
spdlog::error("Player 对象缺少必要组件!");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace engine::component {
|
||||
class TransformComponent;
|
||||
class PhysicsComponent;
|
||||
class SpriteComponent;
|
||||
class AnimationComponent;
|
||||
}
|
||||
|
||||
namespace game::component::state {
|
||||
@@ -28,6 +29,7 @@ private:
|
||||
engine::component::TransformComponent* transform_component_ = nullptr; // 指向 TransformComponent 的非拥有指针
|
||||
engine::component::SpriteComponent* sprite_component_ = nullptr;
|
||||
engine::component::PhysicsComponent* physics_component_ = nullptr;
|
||||
engine::component::AnimationComponent* animation_component_ = nullptr;
|
||||
|
||||
std::unique_ptr<state::PlayerState> current_state_;
|
||||
bool is_dead_ = false;
|
||||
@@ -52,6 +54,7 @@ public:
|
||||
engine::component::TransformComponent* getTransformComponent() const { return transform_component_; }
|
||||
engine::component::SpriteComponent* getSpriteComponent() const { return sprite_component_; }
|
||||
engine::component::PhysicsComponent* getPhysicsComponent() const { return physics_component_; }
|
||||
engine::component::AnimationComponent* getAnimationComponent() const { return animation_component_; }
|
||||
|
||||
void setIsDead(bool is_dead) { is_dead_ = is_dead; } ///< @brief 设置玩家是否死亡
|
||||
bool isDead() const { return is_dead_; } ///< @brief 获取玩家是否死亡
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace game::component::state {
|
||||
|
||||
void FallState::enter() {
|
||||
|
||||
playAnimation("fall"); // 播放下落动画
|
||||
}
|
||||
|
||||
void FallState::exit() {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace game::component::state {
|
||||
|
||||
void IdleState::enter() {
|
||||
|
||||
playAnimation("idle"); // 播放待机动画
|
||||
}
|
||||
|
||||
void IdleState::exit() {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
namespace game::component::state {
|
||||
|
||||
void JumpState::enter() {
|
||||
playAnimation("jump"); // 播放跳跃动画
|
||||
auto physics_component = player_component_->getPhysicsComponent();
|
||||
physics_component->velocity_.y = -player_component_->getJumpForce(); // 向上跳跃
|
||||
spdlog::debug("PlayerComponent 进入 JumpState,设置初始垂直速度为: {}", physics_component->velocity_.y);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "player_state.h"
|
||||
#include "../player_component.h"
|
||||
#include "../../../engine/component/animation_component.h"
|
||||
#include "../../../engine/object/game_object.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace game::component::state {
|
||||
|
||||
void PlayerState::playAnimation(const std::string& animation_name) {
|
||||
if (!player_component_) {
|
||||
spdlog::error("PlayerState 没有关联的 PlayerComponent,无法播放动画 '{}'", animation_name);
|
||||
return;
|
||||
}
|
||||
|
||||
auto animation_component = player_component_->getAnimationComponent();
|
||||
if (!animation_component) {
|
||||
spdlog::error("PlayerComponent '{}' 没有 AnimationComponent,无法播放动画 '{}'",
|
||||
player_component_->getOwner()->getName(), animation_name);
|
||||
return;
|
||||
}
|
||||
|
||||
animation_component->playAnimation(animation_name);
|
||||
}
|
||||
|
||||
} // namespace game::component::state
|
||||
@@ -30,6 +30,8 @@ public:
|
||||
PlayerState(PlayerState&&) = delete;
|
||||
PlayerState& operator=(PlayerState&&) = delete;
|
||||
|
||||
void playAnimation(const std::string& animation_name); ///< @brief 播放指定名称的动画,使用 AnimationComponent 的方法
|
||||
|
||||
protected:
|
||||
// 核心状态方法
|
||||
virtual void enter() = 0; ///< @brief 进入
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace game::component::state {
|
||||
|
||||
void WalkState::enter() {
|
||||
|
||||
playAnimation("walk"); // 播放步行动画
|
||||
}
|
||||
|
||||
void WalkState::exit() {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../../engine/component/physics_component.h"
|
||||
#include "../../engine/component/collider_component.h"
|
||||
#include "../../engine/component/tilelayer_component.h"
|
||||
#include "../../engine/component/animation_component.h"
|
||||
#include "../../engine/physics/physics_engine.h"
|
||||
#include "../../engine/scene/level_loader.h"
|
||||
#include "../../engine/input/input_manager.h"
|
||||
@@ -39,6 +40,11 @@ void GameScene::init() {
|
||||
context_.getInputManager().setShouldQuit(true);
|
||||
return;
|
||||
}
|
||||
if (!initEnemyAndItem()) {
|
||||
spdlog::error("敌人和道具初始化失败,无法继续。");
|
||||
context_.getInputManager().setShouldQuit(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Scene::init();
|
||||
spdlog::trace("GameScene 初始化完成。");
|
||||
@@ -121,4 +127,44 @@ bool GameScene::initPlayer()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameScene::initEnemyAndItem()
|
||||
{
|
||||
bool success = true;
|
||||
for (auto& game_object : game_objects_){
|
||||
if (game_object->getName() == "eagle"){
|
||||
if (auto* ac = game_object->getComponent<engine::component::AnimationComponent>(); ac){
|
||||
ac->playAnimation("fly");
|
||||
} else {
|
||||
spdlog::error("Eagle对象缺少 AnimationComponent,无法播放动画。");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (game_object->getName() == "frog"){
|
||||
if (auto* ac = game_object->getComponent<engine::component::AnimationComponent>(); ac){
|
||||
ac->playAnimation("idle");
|
||||
} else {
|
||||
spdlog::error("Frog对象缺少 AnimationComponent,无法播放动画。");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (game_object->getName() == "opossum"){
|
||||
if (auto* ac = game_object->getComponent<engine::component::AnimationComponent>(); ac){
|
||||
ac->playAnimation("walk");
|
||||
} else {
|
||||
spdlog::error("Opossum对象缺少 AnimationComponent,无法播放动画。");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (game_object->getTag() == "item"){
|
||||
if (auto* ac = game_object->getComponent<engine::component::AnimationComponent>(); ac){
|
||||
ac->playAnimation("idle");
|
||||
} else {
|
||||
spdlog::error("Item对象缺少 AnimationComponent,无法播放动画。");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
} // namespace game::scene
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
private:
|
||||
[[nodiscard]] bool initLevel(); ///< @brief 初始化关卡
|
||||
[[nodiscard]] bool initPlayer(); ///< @brief 初始化玩家
|
||||
[[nodiscard]] bool initEnemyAndItem(); ///< @brief 初始化敌人和道具
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user