feat: 添加游戏核心模块,包括地图、角色、场景和世界管理

实现游戏基础架构,包含以下主要功能:
- 地图系统:支持地图加载、图层管理和相机控制
- 角色系统:实现角色装备、动画和行为管理
- 场景系统:提供测试场景和世界场景切换
- 世界管理:处理城镇和区域切换逻辑
- 数据加载:添加角色和装备配置加载器

这些改动为游戏开发奠定了基础框架,支持后续功能扩展
This commit is contained in:
2026-04-02 23:32:44 +08:00
parent ec16aeffa6
commit b5c432e77a
23 changed files with 934 additions and 26 deletions

View File

@@ -0,0 +1,193 @@
#include "camera/GameCameraController.h"
#include "map/GameMap.h"
#include <SDL2/SDL.h>
#include <cmath>
#include <frostbite2D/graphics/camera.h>
#include <frostbite2D/graphics/renderer.h>
#include <algorithm>
namespace frostbite2D {
namespace {
constexpr float kScreenWidth = 1280.0f;
constexpr float kScreenHeight = 720.0f;
constexpr int kDebugStickDeadzone = 8000;
float normalizeControllerAxis(int16 value) {
float magnitude = static_cast<float>(value);
if (std::abs(magnitude) <= static_cast<float>(kDebugStickDeadzone)) {
return 0.0f;
}
float sign = magnitude < 0.0f ? -1.0f : 1.0f;
float normalized =
(std::abs(magnitude) - static_cast<float>(kDebugStickDeadzone)) /
(32767.0f - static_cast<float>(kDebugStickDeadzone));
return std::clamp(normalized, 0.0f, 1.0f) * sign;
}
}
GameCameraController::~GameCameraController() {
closeDebugController();
}
void GameCameraController::SetMap(GameMap* map) {
map_ = map;
initialized_ = false;
}
void GameCameraController::SetTarget(Actor* target) {
target_ = target;
}
void GameCameraController::ClearTarget() {
target_ = nullptr;
}
void GameCameraController::SetDebugEnabled(bool enabled) {
debugEnabled_ = enabled;
if (debugEnabled_) {
openDebugController();
} else {
closeDebugController();
}
}
void GameCameraController::SetZoom(float zoom) {
zoom_ = std::max(zoom, 0.01f);
if (map_) {
focus_ = map_->ClampCameraFocus(focus_, zoom_);
}
applyFocus();
}
void GameCameraController::SetFocus(const Vec2& focus) {
focus_ = map_ ? map_->ClampCameraFocus(focus, zoom_) : focus;
initialized_ = true;
applyFocus();
}
void GameCameraController::SnapToDefaultFocus() {
if (!map_) {
return;
}
focus_ = map_->ClampCameraFocus(map_->GetDefaultCameraFocus(), zoom_);
initialized_ = true;
applyFocus();
}
void GameCameraController::Update(float deltaTime) {
if (!map_) {
return;
}
if (!initialized_) {
SnapToDefaultFocus();
}
if (target_) {
Vec2 targetFocus = target_->GetPosition();
float t = std::clamp(deltaTime * followLerpSpeed_, 0.0f, 1.0f);
focus_ = focus_ + (targetFocus - focus_) * t;
} else if (debugEnabled_) {
updateDebugInput(deltaTime);
}
focus_ = map_->ClampCameraFocus(focus_, zoom_);
applyFocus();
}
void GameCameraController::openDebugController() {
if (debugController_ && SDL_GameControllerGetAttached(debugController_)) {
return;
}
closeDebugController();
int joystickCount = SDL_NumJoysticks();
for (int i = 0; i < joystickCount; ++i) {
if (!SDL_IsGameController(i)) {
continue;
}
debugController_ = SDL_GameControllerOpen(i);
if (debugController_) {
return;
}
}
}
void GameCameraController::closeDebugController() {
if (!debugController_) {
return;
}
SDL_GameControllerClose(debugController_);
debugController_ = nullptr;
}
void GameCameraController::updateDebugInput(float deltaTime) {
const uint8* keyboardState = SDL_GetKeyboardState(nullptr);
float moveX = 0.0f;
float moveY = 0.0f;
if (keyboardState) {
if (keyboardState[SDL_SCANCODE_A]) {
moveX -= 1.0f;
}
if (keyboardState[SDL_SCANCODE_D]) {
moveX += 1.0f;
}
if (keyboardState[SDL_SCANCODE_W]) {
moveY -= 1.0f;
}
if (keyboardState[SDL_SCANCODE_S]) {
moveY += 1.0f;
}
}
if (debugEnabled_ && !debugController_) {
openDebugController();
}
if (debugController_ && !SDL_GameControllerGetAttached(debugController_)) {
closeDebugController();
openDebugController();
}
if (debugController_ && SDL_GameControllerGetAttached(debugController_)) {
moveX += normalizeControllerAxis(
SDL_GameControllerGetAxis(debugController_, SDL_CONTROLLER_AXIS_LEFTX));
moveY += normalizeControllerAxis(
SDL_GameControllerGetAxis(debugController_, SDL_CONTROLLER_AXIS_LEFTY));
}
moveX = std::clamp(moveX, -1.0f, 1.0f);
moveY = std::clamp(moveY, -1.0f, 1.0f);
if (moveX == 0.0f && moveY == 0.0f) {
return;
}
focus_.x += moveX * debugMoveSpeed_ * deltaTime;
focus_.y += moveY * debugMoveSpeed_ * deltaTime;
}
void GameCameraController::applyFocus() const {
Camera* camera = Renderer::get().getCamera();
if (!camera || !map_) {
return;
}
float halfWidth = kScreenWidth * 0.5f / zoom_;
float halfHeight = kScreenHeight * 0.5f / zoom_;
Vec2 cameraPos(focus_.x - halfWidth, focus_.y - halfHeight);
camera->setZoom(zoom_);
camera->setPosition(cameraPos);
map_->ApplyCameraFocus(focus_);
}
} // namespace frostbite2D