Unify stage prop layers

This commit is contained in:
2026-06-09 15:08:17 +08:00
parent cf7b7dfb5a
commit 0a59d20ffa
7 changed files with 30 additions and 17 deletions
@@ -203,12 +203,13 @@ mindmap
- `StageLayer` 灰盒数据已接入:远景、中景、地面/平台、后景 props 先用色块占位。 - `StageLayer` 灰盒数据已接入:远景、中景、地面/平台、后景 props 先用色块占位。
- `StageLayerSource` 已接入:每个 `StageRect` 可选择色块占位或 sprite 资源路径,加载失败时回退色块。 - `StageLayerSource` 已接入:每个 `StageRect` 可选择色块占位或 sprite 资源路径,加载失败时回退色块。
- `StageAssetSlots` 已建立:`stage_01` 资源目录和素材来源记录已预留,素材回来后可直接落位。 - `StageAssetSlots` 已建立:`stage_01` 资源目录和素材来源记录已预留,素材回来后可直接落位。
- `StageProps` 已统一:后景/前景 props 都走 `StageLayer`,前景层在 actor 之后绘制,可用于近景遮挡。
- 第一关宽度已扩展到 3200 像素,并加入 3 个 battle zone 占位与敌人出生点。 - 第一关宽度已扩展到 3200 像素,并加入 3 个 battle zone 占位与敌人出生点。
下一步: 下一步:
-`StageLayer` 色块逐步替换为 tileset、背景图和 props 素材。 -`StageLayer` 色块逐步替换为 tileset、背景图和 props 素材。
- 将后景/前景 props 统一到 `StageLayer` 数据 - 补齐分项 debug 开关和场景验收跑图标准
- 将 battle zone 占位升级为触发、锁镜头、清场解锁逻辑。 - 将 battle zone 占位升级为触发、锁镜头、清场解锁逻辑。
- 将敌人出生点接入 `EnemyActor` - 将敌人出生点接入 `EnemyActor`
@@ -585,7 +586,7 @@ mindmap
1. 已完成:`StageLayerSource``StageLayer` 同时支持色块占位和 sprite 资源路径。 1. 已完成:`StageLayerSource``StageLayer` 同时支持色块占位和 sprite 资源路径。
2. 已完成:`StageAssetSlots` 建立 `stage_01` 资源槽位和素材来源记录,做到素材可直接落位。 2. 已完成:`StageAssetSlots` 建立 `stage_01` 资源槽位和素材来源记录,做到素材可直接落位。
3. `StageProps`把后景/前景 props 统一到 layer 数据。 3. 已完成:`StageProps` 把后景/前景 props 统一到 layer 数据。
4. `BattleZone`:把 `F2` debug 清场替换为敌人清空自动解锁。 4. `BattleZone`:把 `F2` debug 清场替换为敌人清空自动解锁。
5. `EnemyActor`:做第一个敌人占位,接入出生点。 5. `EnemyActor`:做第一个敌人占位,接入出生点。
6. `CombatSystem`:把 hitbox/hurtbox 真正跑起来。 6. `CombatSystem`:把 hitbox/hurtbox 真正跑起来。
+2 -1
View File
@@ -27,6 +27,7 @@
- 已修复进入 battle zone 时摄像机硬切的问题;zone camera bounds 表示摄像机可移动范围,进入/离开 zone 都通过短过渡平滑切换约束。 - 已修复进入 battle zone 时摄像机硬切的问题;zone camera bounds 表示摄像机可移动范围,进入/离开 zone 都通过短过渡平滑切换约束。
- `StageLayerSource` 已接入:`StageRect` 支持色块占位或 sprite 资源路径,资源不存在时回退色块。 - `StageLayerSource` 已接入:`StageRect` 支持色块占位或 sprite 资源路径,资源不存在时回退色块。
- `StageAssetSlots` 已建立:`game/assets/stage/stage_01/` 已预留 background、tiles、props、effects、audio 目录和素材来源记录。 - `StageAssetSlots` 已建立:`game/assets/stage/stage_01/` 已预留 background、tiles、props、effects、audio 目录和素材来源记录。
- `StageProps` 已统一:旧 `WhiteboxProp` 已移除,后景/前景 props 都走 `StageLayer`,其中 `props_front` 在角色之后绘制用于遮挡。
## 2. 第一关场景目标 ## 2. 第一关场景目标
@@ -258,7 +259,7 @@ game/assets/stage/stage_01/
2. 已完成:`CameraZoneLock` 让 battle zone 可以锁定摄像机范围,先用 `F2` 做 debug 清场和解锁占位。 2. 已完成:`CameraZoneLock` 让 battle zone 可以锁定摄像机范围,先用 `F2` 做 debug 清场和解锁占位。
3. 已完成:`StageLayerSource` 扩展 `StageLayer`,让每个 rect 支持色块占位或 sprite 资源路径。 3. 已完成:`StageLayerSource` 扩展 `StageLayer`,让每个 rect 支持色块占位或 sprite 资源路径。
4. 已完成:`StageAssetSlots` 创建并记录 `stage_01` 资源槽位,不要求已有最终素材。 4. 已完成:`StageAssetSlots` 创建并记录 `stage_01` 资源槽位,不要求已有最终素材。
5. `StageProps`把 props 从旧 `WhiteboxProp` 迁移到统一 layer 数据,支持 back/front 两层。 5. 已完成:`StageProps` 把 props 从旧 `WhiteboxProp` 迁移到统一 layer 数据,支持 back/front 两层。
6. `SceneDebug`:补齐 F1 debug 总开关,并预留分项开关。 6. `SceneDebug`:补齐 F1 debug 总开关,并预留分项开关。
7. `SceneAcceptanceRun`PC 和 Switch 都构建通过,PC 能从起点移动到终点并看到相机推进。 7. `SceneAcceptanceRun`PC 和 Switch 都构建通过,PC 能从起点移动到终点并看到相机推进。
-6
View File
@@ -62,11 +62,6 @@ struct StageLayer {
std::vector<StageRect> rects; std::vector<StageRect> rects;
}; };
struct WhiteboxProp {
frostbite2D::Rect bounds;
frostbite2D::Color color;
};
struct LevelDefinition { struct LevelDefinition {
float worldWidth = 0.0f; float worldWidth = 0.0f;
float worldHeight = 0.0f; float worldHeight = 0.0f;
@@ -74,7 +69,6 @@ struct LevelDefinition {
frostbite2D::Rect cameraBounds; frostbite2D::Rect cameraBounds;
PlatformWorld collision; PlatformWorld collision;
std::vector<StageLayer> layers; std::vector<StageLayer> layers;
std::vector<WhiteboxProp> props;
std::vector<BattleZoneDefinition> battleZones; std::vector<BattleZoneDefinition> battleZones;
}; };
+12 -8
View File
@@ -100,14 +100,18 @@ LevelDefinition CreateWhiteboxLevel() {
{frostbite2D::Rect(3040.0f, 315.0f, 82.0f, 285.0f), {frostbite2D::Rect(3040.0f, 315.0f, 82.0f, 285.0f),
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f), frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f),
StageLayerRole::PropsBack}}}, StageLayerRole::PropsBack}}},
}; {"props_front",
level.props = { StageLayerRole::PropsFront,
{frostbite2D::Rect(118.0f, 392.0f, 88.0f, 208.0f), 1.0f,
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f)}, {{frostbite2D::Rect(520.0f, 580.0f, 220.0f, 34.0f),
{frostbite2D::Rect(780.0f, 250.0f, 72.0f, 180.0f), frostbite2D::Color(0.14f, 0.17f, 0.18f, 0.90f),
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f)}, StageLayerRole::PropsFront},
{frostbite2D::Rect(1440.0f, 300.0f, 80.0f, 300.0f), {frostbite2D::Rect(1510.0f, 570.0f, 280.0f, 42.0f),
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f)}, frostbite2D::Color(0.14f, 0.17f, 0.18f, 0.90f),
StageLayerRole::PropsFront},
{frostbite2D::Rect(2580.0f, 572.0f, 260.0f, 38.0f),
frostbite2D::Color(0.14f, 0.17f, 0.18f, 0.90f),
StageLayerRole::PropsFront}}},
}; };
level.battleZones = { level.battleZones = {
{"zone_01_intro", {"zone_01_intro",
+1
View File
@@ -52,6 +52,7 @@ bool WhiteboxScene::OnEvent(const frostbite2D::Event& event) {
void WhiteboxScene::Render() { void WhiteboxScene::Render() {
stageRenderer_.Render(level_, debugFlags_); stageRenderer_.Render(level_, debugFlags_);
frostbite2D::Scene::Render(); frostbite2D::Scene::Render();
stageRenderer_.RenderForeground(level_);
const frostbite2D::Rect playerBounds = const frostbite2D::Rect playerBounds =
player_ ? player_->GetWorldBounds() : frostbite2D::Rect::Zero(); player_ ? player_->GetWorldBounds() : frostbite2D::Rect::Zero();
const std::vector<BattleZoneDebugInfo> battleZoneDebug = const std::vector<BattleZoneDebugInfo> battleZoneDebug =
+11
View File
@@ -44,6 +44,9 @@ void StageRenderer::Render(const LevelDefinition& level,
const DebugFlags& debugFlags) const { const DebugFlags& debugFlags) const {
drawBackground(level); drawBackground(level);
for (const StageLayer& layer : level.layers) { for (const StageLayer& layer : level.layers) {
if (layer.role == StageLayerRole::PropsFront) {
continue;
}
drawLayer(level, layer); drawLayer(level, layer);
} }
if (debugFlags.showStageGrid) { if (debugFlags.showStageGrid) {
@@ -51,6 +54,14 @@ void StageRenderer::Render(const LevelDefinition& level,
} }
} }
void StageRenderer::RenderForeground(const LevelDefinition& level) const {
for (const StageLayer& layer : level.layers) {
if (layer.role == StageLayerRole::PropsFront) {
drawLayer(level, layer);
}
}
}
void StageRenderer::drawBackground(const LevelDefinition& level) const { void StageRenderer::drawBackground(const LevelDefinition& level) const {
drawRect(frostbite2D::Rect(level.collision.levelLeft, 0.0f, drawRect(frostbite2D::Rect(level.collision.levelLeft, 0.0f,
worldWidthOf(level), config::kVirtualHeight), worldWidthOf(level), config::kVirtualHeight),
+1
View File
@@ -12,6 +12,7 @@ namespace ns_game {
class StageRenderer { class StageRenderer {
public: public:
void Render(const LevelDefinition& level, const DebugFlags& debugFlags) const; void Render(const LevelDefinition& level, const DebugFlags& debugFlags) const;
void RenderForeground(const LevelDefinition& level) const;
private: private:
void drawBackground(const LevelDefinition& level) const; void drawBackground(const LevelDefinition& level) const;