diff --git a/game/docs/planning/game_architecture_board.md b/game/docs/planning/game_architecture_board.md index c51fec6..990a4e4 100644 --- a/game/docs/planning/game_architecture_board.md +++ b/game/docs/planning/game_architecture_board.md @@ -178,7 +178,7 @@ mindmap - `scene/whitebox_scene.*` - `scene/camera_controller.*`:玩家跟随、dead zone、平滑和世界边界 clamp。 -- `CameraZoneLock`:玩家进入 battle zone 后摄像机锁定到 zone camera bounds,当前用 `F2` debug 清场解锁。 +- `CameraZoneLock`:玩家进入 battle zone 后摄像机锁定到 zone camera bounds,锁定范围会防御性保证不小于视口,当前用 `F2` 或离开 zone 做 debug 清场解锁。 下一步: diff --git a/game/docs/planning/scene_build_plan.md b/game/docs/planning/scene_build_plan.md index 660c875..c26caf6 100644 --- a/game/docs/planning/scene_build_plan.md +++ b/game/docs/planning/scene_build_plan.md @@ -23,6 +23,7 @@ - `WhiteboxScene` 已支持 `F1` 切换 debug overlay。 - `CameraController` 已接入:修复场景 `OnUpdate()` 不被调用导致摄像机不动的问题,并提供跟随、dead zone、平滑和世界边界 clamp。 - `CameraZoneLock` 已接入:玩家进入 battle zone 后摄像机临时锁定到 zone camera bounds,`F2` 临时清场并恢复全关卡跟随。 +- 已修复 zone camera bounds 小于 1280 视口导致摄像机锁死的问题;所有锁镜头范围必须不小于当前视口,debug 阶段玩家离开 zone 会自动清场解锁。 ## 2. 第一关场景目标 diff --git a/game/src/data/whitebox_level.cpp b/game/src/data/whitebox_level.cpp index 99dc2e2..4d21ce9 100644 --- a/game/src/data/whitebox_level.cpp +++ b/game/src/data/whitebox_level.cpp @@ -112,17 +112,17 @@ LevelDefinition CreateWhiteboxLevel() { level.battleZones = { {"zone_01_intro", frostbite2D::Rect(520.0f, 260.0f, 560.0f, 340.0f), - frostbite2D::Rect(320.0f, 0.0f, 760.0f, 720.0f), + frostbite2D::Rect(320.0f, 0.0f, 1280.0f, 720.0f), {{"zone_01_enemy_a", frostbite2D::Vec2(760.0f, 560.0f)}, {"zone_01_enemy_b", frostbite2D::Vec2(980.0f, 560.0f)}}}, {"zone_02_platform", frostbite2D::Rect(1420.0f, 250.0f, 680.0f, 350.0f), - frostbite2D::Rect(1280.0f, 0.0f, 900.0f, 720.0f), + frostbite2D::Rect(1280.0f, 0.0f, 1280.0f, 720.0f), {{"zone_02_enemy_a", frostbite2D::Vec2(1620.0f, 560.0f)}, {"zone_02_enemy_b", frostbite2D::Vec2(1900.0f, 560.0f)}}}, {"zone_03_exit", frostbite2D::Rect(2380.0f, 250.0f, 720.0f, 350.0f), - frostbite2D::Rect(2240.0f, 0.0f, 960.0f, 720.0f), + frostbite2D::Rect(1920.0f, 0.0f, 1280.0f, 720.0f), {{"zone_03_enemy_a", frostbite2D::Vec2(2580.0f, 560.0f)}, {"zone_03_enemy_b", frostbite2D::Vec2(2860.0f, 560.0f)}}}, }; diff --git a/game/src/scene/camera_controller.cpp b/game/src/scene/camera_controller.cpp index fa7d42e..ec435d9 100644 --- a/game/src/scene/camera_controller.cpp +++ b/game/src/scene/camera_controller.cpp @@ -28,7 +28,10 @@ void CameraController::Configure(const CameraControllerConfig& config) { } void CameraController::SetWorldBounds(const frostbite2D::Rect& worldBounds) { - config_.worldBounds = worldBounds; + const float width = std::max(worldBounds.width(), config_.viewportWidth); + const float height = std::max(worldBounds.height(), config_.viewportHeight); + config_.worldBounds = + frostbite2D::Rect(worldBounds.left(), worldBounds.top(), width, height); } void CameraController::SnapToTarget(frostbite2D::Camera& camera, diff --git a/game/src/scene/whitebox_scene.cpp b/game/src/scene/whitebox_scene.cpp index 8d914c3..8b5844f 100644 --- a/game/src/scene/whitebox_scene.cpp +++ b/game/src/scene/whitebox_scene.cpp @@ -127,11 +127,16 @@ void WhiteboxScene::updateBattleZones() { return; } + const frostbite2D::Rect playerBounds = player_->GetWorldBounds(); if (activeBattleZoneIndex_ >= 0) { + const size_t activeIndex = static_cast(activeBattleZoneIndex_); + if (activeIndex < level_.battleZones.size() && + !level_.battleZones[activeIndex].trigger.intersects(playerBounds)) { + clearActiveBattleZone(); + } return; } - const frostbite2D::Rect playerBounds = player_->GetWorldBounds(); for (size_t i = 0; i < level_.battleZones.size(); ++i) { BattleZoneRuntime& runtime = battleZoneStates_[i]; if (runtime.cleared ||