2025-05-27 17:23:07 +08:00
|
|
|
#include "game_scene.h"
|
2025-06-06 15:27:23 +08:00
|
|
|
#include "../component/player_component.h"
|
2025-05-27 17:23:07 +08:00
|
|
|
#include "../../engine/core/context.h"
|
|
|
|
|
#include "../../engine/object/game_object.h"
|
|
|
|
|
#include "../../engine/component/transform_component.h"
|
|
|
|
|
#include "../../engine/component/sprite_component.h"
|
2025-05-31 09:40:40 +08:00
|
|
|
#include "../../engine/component/physics_component.h"
|
2025-06-02 17:19:02 +08:00
|
|
|
#include "../../engine/component/collider_component.h"
|
2025-06-03 16:06:32 +08:00
|
|
|
#include "../../engine/component/tilelayer_component.h"
|
2025-06-07 10:49:23 +08:00
|
|
|
#include "../../engine/component/animation_component.h"
|
2025-05-31 09:40:40 +08:00
|
|
|
#include "../../engine/physics/physics_engine.h"
|
2025-05-28 18:36:04 +08:00
|
|
|
#include "../../engine/scene/level_loader.h"
|
|
|
|
|
#include "../../engine/input/input_manager.h"
|
|
|
|
|
#include "../../engine/render/camera.h"
|
2025-05-27 17:23:07 +08:00
|
|
|
#include <spdlog/spdlog.h>
|
|
|
|
|
#include <SDL3/SDL_rect.h>
|
|
|
|
|
|
|
|
|
|
namespace game::scene {
|
|
|
|
|
|
|
|
|
|
// 构造函数:调用基类构造函数
|
|
|
|
|
GameScene::GameScene(std::string name, engine::core::Context& context, engine::scene::SceneManager& scene_manager)
|
|
|
|
|
: Scene(name, context, scene_manager) {
|
|
|
|
|
spdlog::trace("GameScene 构造完成。");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameScene::init() {
|
2025-06-06 15:27:23 +08:00
|
|
|
if (is_initialized_) {
|
|
|
|
|
spdlog::warn("GameScene 已经初始化过了,重复调用 init()。");
|
2025-06-04 15:11:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2025-06-06 15:27:23 +08:00
|
|
|
spdlog::trace("GameScene 初始化开始...");
|
|
|
|
|
|
|
|
|
|
if (!initLevel()) {
|
|
|
|
|
spdlog::error("关卡初始化失败,无法继续。");
|
|
|
|
|
context_.getInputManager().setShouldQuit(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!initPlayer()) {
|
|
|
|
|
spdlog::error("玩家初始化失败,无法继续。");
|
|
|
|
|
context_.getInputManager().setShouldQuit(true);
|
|
|
|
|
return;
|
2025-06-05 10:36:20 +08:00
|
|
|
}
|
2025-06-07 10:49:23 +08:00
|
|
|
if (!initEnemyAndItem()) {
|
|
|
|
|
spdlog::error("敌人和道具初始化失败,无法继续。");
|
|
|
|
|
context_.getInputManager().setShouldQuit(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-05-27 17:23:07 +08:00
|
|
|
|
|
|
|
|
Scene::init();
|
|
|
|
|
spdlog::trace("GameScene 初始化完成。");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameScene::update(float delta_time) {
|
|
|
|
|
Scene::update(delta_time);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameScene::render() {
|
|
|
|
|
Scene::render();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameScene::handleInput() {
|
|
|
|
|
Scene::handleInput();
|
2025-06-08 09:19:37 +08:00
|
|
|
testHealth(); // 测试生命值组件
|
2025-05-27 17:23:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameScene::clean() {
|
|
|
|
|
Scene::clean();
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 15:27:23 +08:00
|
|
|
bool GameScene::initLevel()
|
|
|
|
|
{
|
|
|
|
|
// 加载关卡(level_loader通常加载完成后即可销毁,因此不存为成员变量)
|
|
|
|
|
engine::scene::LevelLoader level_loader;
|
|
|
|
|
if (!level_loader.loadLevel("assets/maps/level1.tmj", *this)){
|
|
|
|
|
spdlog::error("关卡加载失败");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-05-27 17:23:07 +08:00
|
|
|
|
2025-06-06 15:27:23 +08:00
|
|
|
// 注册"main"层到物理引擎
|
|
|
|
|
auto* main_layer = findGameObjectByName("main");
|
|
|
|
|
if (!main_layer) {
|
|
|
|
|
spdlog::error("未找到\"main\"层");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
auto* tile_layer = main_layer->getComponent<engine::component::TileLayerComponent>();
|
|
|
|
|
if (!tile_layer) {
|
|
|
|
|
spdlog::error("\"main\"层没有 TileLayerComponent 组件");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
context_.getPhysicsEngine().registerCollisionLayer(tile_layer);
|
|
|
|
|
spdlog::info("注册\"main\"层到物理引擎");
|
|
|
|
|
|
|
|
|
|
// 设置相机边界
|
|
|
|
|
auto world_size = main_layer->getComponent<engine::component::TileLayerComponent>()->getWorldSize();
|
|
|
|
|
context_.getCamera().setLimitBounds(engine::utils::Rect(glm::vec2(0.0f), world_size));
|
|
|
|
|
|
|
|
|
|
// 设置世界边界
|
|
|
|
|
context_.getPhysicsEngine().setWorldBounds(engine::utils::Rect(glm::vec2(0.0f), world_size));
|
|
|
|
|
|
|
|
|
|
spdlog::trace("关卡初始化完成。");
|
|
|
|
|
return true;
|
2025-05-28 18:36:04 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-06 15:27:23 +08:00
|
|
|
bool GameScene::initPlayer()
|
2025-05-31 09:40:40 +08:00
|
|
|
{
|
2025-06-06 15:27:23 +08:00
|
|
|
// 获取玩家对象
|
|
|
|
|
player_ = findGameObjectByName("player");
|
|
|
|
|
if (!player_) {
|
|
|
|
|
spdlog::error("未找到玩家对象");
|
|
|
|
|
return false;
|
2025-05-31 09:40:40 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-06 15:27:23 +08:00
|
|
|
// 添加PlayerComponent到玩家对象
|
|
|
|
|
auto* player_component = player_->addComponent<game::component::PlayerComponent>();
|
|
|
|
|
if (!player_component) {
|
|
|
|
|
spdlog::error("无法添加 PlayerComponent 到玩家对象");
|
|
|
|
|
return false;
|
2025-06-02 17:19:02 +08:00
|
|
|
}
|
2025-06-06 15:27:23 +08:00
|
|
|
|
|
|
|
|
// 相机跟随玩家
|
|
|
|
|
auto* player_transform = player_->getComponent<engine::component::TransformComponent>();
|
|
|
|
|
if (!player_transform) {
|
|
|
|
|
spdlog::error("玩家对象没有 TransformComponent 组件, 无法设置相机目标");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
context_.getCamera().setTarget(player_transform);
|
|
|
|
|
spdlog::trace("Player初始化完成。");
|
|
|
|
|
return true;
|
2025-06-02 17:19:02 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-07 10:49:23 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-08 09:19:37 +08:00
|
|
|
void GameScene::testHealth()
|
|
|
|
|
{
|
|
|
|
|
auto input_manager = context_.getInputManager();
|
|
|
|
|
if (input_manager.isActionPressed("attack")) {
|
|
|
|
|
player_->getComponent<game::component::PlayerComponent>()->takeDamage(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-27 17:23:07 +08:00
|
|
|
} // namespace game::scene
|