feat: 添加游戏核心模块,包括地图、角色、场景和世界管理
实现游戏基础架构,包含以下主要功能: - 地图系统:支持地图加载、图层管理和相机控制 - 角色系统:实现角色装备、动画和行为管理 - 场景系统:提供测试场景和世界场景切换 - 世界管理:处理城镇和区域切换逻辑 - 数据加载:添加角色和装备配置加载器 这些改动为游戏开发奠定了基础框架,支持后续功能扩展
This commit is contained in:
117
Game/src/world/GameTown.cpp
Normal file
117
Game/src/world/GameTown.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "world/GameTown.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace frostbite2D {
|
||||
|
||||
GameTown::GameTown() = default;
|
||||
|
||||
bool GameTown::Init(int index, const std::string& townPath) {
|
||||
game::TownConfig config;
|
||||
if (!game::loadTownConfig(townPath, config)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "GameTown: failed to init town %d (%s)",
|
||||
index, townPath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
name_ = config.townName;
|
||||
enteringTitle_ = config.enteringTitle;
|
||||
enteringCutscene_ = config.enteringCutscene;
|
||||
needQuestId_ = config.needQuestId;
|
||||
needLevel_ = config.needLevel;
|
||||
mapList_.clear();
|
||||
curMapIndex_ = -1;
|
||||
sariaRoomId_ = -1;
|
||||
sariaRoomPos_ = Vec2(-1.0f, -1.0f);
|
||||
|
||||
for (const auto& [areaId, areaConfig] : config.areas) {
|
||||
auto map = MakePtr<GameMap>();
|
||||
if (!map->LoadMap(areaConfig.mapPath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MapInfo info;
|
||||
info.areaId = areaId;
|
||||
info.map = map;
|
||||
info.type = areaConfig.mapType;
|
||||
info.generatePos = areaConfig.generatePos;
|
||||
mapList_.push_back(info);
|
||||
|
||||
if (info.type == "gate") {
|
||||
sariaRoomId_ = areaId;
|
||||
sariaRoomPos_ = areaConfig.generatePos;
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(mapList_.begin(), mapList_.end(),
|
||||
[](const MapInfo& a, const MapInfo& b) { return a.areaId < b.areaId; });
|
||||
return !mapList_.empty();
|
||||
}
|
||||
|
||||
RefPtr<GameMap> GameTown::GetArea(int index) const {
|
||||
auto it = std::find_if(mapList_.begin(), mapList_.end(),
|
||||
[index](const MapInfo& info) { return info.areaId == index; });
|
||||
if (it == mapList_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->map;
|
||||
}
|
||||
|
||||
void GameTown::AddCharacter(RefPtr<Actor> actor, int areaIndex) {
|
||||
int targetMapIndex = areaIndex;
|
||||
if (areaIndex == -2) {
|
||||
targetMapIndex = sariaRoomId_ != -1 ? sariaRoomId_ : (mapList_.empty() ? -1 : mapList_.front().areaId);
|
||||
}
|
||||
|
||||
auto mapIt = std::find_if(mapList_.begin(), mapList_.end(),
|
||||
[targetMapIndex](const MapInfo& info) {
|
||||
return info.areaId == targetMapIndex;
|
||||
});
|
||||
if (mapIt == mapList_.end()) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"GameTown: target area %d not found, fallback to first map", targetMapIndex);
|
||||
if (mapList_.empty()) {
|
||||
return;
|
||||
}
|
||||
mapIt = mapList_.begin();
|
||||
}
|
||||
|
||||
if (curMapIndex_ != -1) {
|
||||
auto oldMap = GetArea(curMapIndex_);
|
||||
if (oldMap) {
|
||||
RemoveChild(oldMap);
|
||||
}
|
||||
}
|
||||
|
||||
if (actor && actor->GetParent()) {
|
||||
actor->GetParent()->RemoveChild(actor);
|
||||
}
|
||||
|
||||
AddChild(mapIt->map);
|
||||
cameraController_.SetMap(mapIt->map.Get());
|
||||
cameraController_.SetZoom(1.2f);
|
||||
cameraController_.SetTarget(actor.Get());
|
||||
cameraController_.SnapToDefaultFocus();
|
||||
|
||||
if (actor) {
|
||||
cameraController_.SetDebugEnabled(false);
|
||||
if (areaIndex == -2 && sariaRoomPos_.x >= 0.0f && sariaRoomPos_.y >= 0.0f) {
|
||||
actor->SetPosition(sariaRoomPos_);
|
||||
}
|
||||
mapIt->map->AddObject(actor);
|
||||
cameraController_.SetFocus(actor->GetPosition());
|
||||
} else {
|
||||
cameraController_.SetDebugEnabled(true);
|
||||
}
|
||||
|
||||
mapIt->map->Enter();
|
||||
|
||||
curMapIndex_ = mapIt->areaId;
|
||||
}
|
||||
|
||||
void GameTown::Update(float deltaTime) {
|
||||
Actor::Update(deltaTime);
|
||||
cameraController_.Update(deltaTime);
|
||||
}
|
||||
|
||||
} // namespace frostbite2D
|
||||
Reference in New Issue
Block a user