feat: 添加游戏数学工具类并重构相关代码

refactor: 将数学工具函数移至GameMath类
feat(音频): 实现地图音频控制器
feat(调试): 添加游戏调试UI组件
feat(地图): 增加移动区域边界获取方法
fix(角色): 修复角色移动区域抑制逻辑
refactor(世界): 重构游戏世界场景初始化
docs(音频): 完善音频数据库注释
This commit is contained in:
2026-04-06 22:22:40 +08:00
parent f86ce35b68
commit 35c80247b3
21 changed files with 893 additions and 215 deletions

View File

@@ -0,0 +1,171 @@
#include "common/debug/GameDebugActor.h"
#include "character/CharacterObject.h"
#include "map/GameMap.h"
#include "ui/NineSliceActor.h"
#include <SDL2/SDL.h>
#include <frostbite2D/2d/text_sprite.h>
#include <frostbite2D/scene/scene.h>
#include <limits>
namespace frostbite2D {
namespace {
constexpr float kDebugHudMarginX = 12.0f;
constexpr float kDebugHudMarginY = 12.0f;
constexpr float kDebugHudPaddingX = 8.0f;
constexpr float kDebugHudPaddingY = 6.0f;
constexpr char kDebugHudPopupImg[] = "sprite/interface/newstyle/windows/popup/popup.img";
void ConfigureTextLine(RefPtr<TextSprite> textSprite, const char* name,
int zOrder) {
if (!textSprite) {
return;
}
textSprite->SetName(name);
textSprite->SetFont("default");
textSprite->SetTextColor(1.0f, 1.0f, 1.0f, 1.0f);
textSprite->SetZOrder(zOrder);
}
} // namespace
GameDebugActor::GameDebugActor() {
SetName("GameDebugActor");
SetZOrder(std::numeric_limits<int>::max());
initOverlay();
}
GameDebugActor& GameDebugActor::get() {
return *getPtr();
}
Ptr<GameDebugActor> GameDebugActor::getPtr() {
static Ptr<GameDebugActor> instance(new GameDebugActor());
return instance;
}
bool GameDebugActor::AttachToScene(Scene* scene) {
return AttachToParent(scene);
}
bool GameDebugActor::AttachToParent(Actor* parent) {
if (!parent || parent == this) {
return false;
}
Ptr<GameDebugActor> self = getPtr();
if (GetParent() == parent) {
return true;
}
if (GetParent()) {
GetParent()->RemoveChild(self);
}
parent->AddChild(self);
return GetParent() == parent;
}
void GameDebugActor::DetachFromParent() {
Ptr<GameDebugActor> self = getPtr();
if (GetParent()) {
GetParent()->RemoveChild(self);
}
}
void GameDebugActor::SetDebugMap(GameMap* map) {
if (debugMap_ && debugMap_ != map) {
debugMap_->SetDebugHighlightedMoveAreaIndex(GameMap::kInvalidMoveAreaIndex);
}
debugMap_ = map;
updateOverlay();
}
void GameDebugActor::SetTrackedCharacter(CharacterObject* character) {
trackedCharacter_ = character;
updateOverlay();
}
void GameDebugActor::ClearDebugContext() {
if (debugMap_) {
debugMap_->SetDebugHighlightedMoveAreaIndex(GameMap::kInvalidMoveAreaIndex);
}
debugMap_ = nullptr;
trackedCharacter_ = nullptr;
setOverlayVisible(false);
}
void GameDebugActor::OnUpdate(float deltaTime) {
(void)deltaTime;
updateOverlay();
}
void GameDebugActor::initOverlay() {
if (background_ || coordText_) {
return;
}
background_ = NineSliceActor::createFromNpk(kDebugHudPopupImg, 0);
if (background_) {
background_->SetName("debugHudBackground");
AddChild(background_);
} else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"GameDebugActor: failed to load HUD background from %s",
kDebugHudPopupImg);
}
coordText_ = TextSprite::create();
ConfigureTextLine(coordText_, "debugCoordText", 1);
AddChild(coordText_);
setOverlayVisible(false);
}
void GameDebugActor::updateOverlay() {
if (!coordText_ || !debugMap_ || !trackedCharacter_ ||
!debugMap_->IsDebugModeEnabled()) {
if (debugMap_) {
debugMap_->SetDebugHighlightedMoveAreaIndex(GameMap::kInvalidMoveAreaIndex);
}
setOverlayVisible(false);
return;
}
const CharacterWorldPosition& worldPosition = trackedCharacter_->GetWorldPosition();
Vec3 currentWorldPos(static_cast<float>(worldPosition.x),
static_cast<float>(worldPosition.y),
static_cast<float>(worldPosition.z));
size_t moveAreaIndex = debugMap_->FindMoveAreaIndex(currentWorldPos);
debugMap_->SetDebugHighlightedMoveAreaIndex(moveAreaIndex);
char coordTextBuffer[96];
SDL_snprintf(coordTextBuffer, sizeof(coordTextBuffer), "角色坐标: (%d, %d, %d)",
worldPosition.x, worldPosition.y, worldPosition.z);
coordText_->SetText(coordTextBuffer);
Vec2 coordTextSize = coordText_->GetTextSize();
float panelWidth = coordTextSize.x + kDebugHudPaddingX * 2.0f;
float panelHeight = coordTextSize.y + kDebugHudPaddingY * 2.0f;
Vec2 panelSize(panelWidth, panelHeight);
if (background_) {
background_->SetSize(panelSize);
}
SetPosition(kDebugHudMarginX, kDebugHudMarginY);
SetScale(1.0f);
coordText_->SetPosition(kDebugHudPaddingX, kDebugHudPaddingY);
setOverlayVisible(true);
}
void GameDebugActor::setOverlayVisible(bool visible) {
if (background_) {
background_->SetVisible(visible);
}
if (coordText_) {
coordText_->SetVisible(visible);
}
}
} // namespace frostbite2D