Build first scene skeleton
This commit is contained in:
@@ -168,12 +168,14 @@ mindmap
|
|||||||
- `data/whitebox_level.cpp`
|
- `data/whitebox_level.cpp`
|
||||||
- `movement/platform_world.*`
|
- `movement/platform_world.*`
|
||||||
- `stage/stage_renderer.*`
|
- `stage/stage_renderer.*`
|
||||||
|
- `StageLayer` 灰盒数据已接入:远景、中景、地面/平台、后景 props 先用色块占位。
|
||||||
|
- 第一关宽度已扩展到 3200 像素,并加入 3 个 battle zone 占位与敌人出生点。
|
||||||
|
|
||||||
下一步:
|
下一步:
|
||||||
|
|
||||||
- 增加 `StageLayer` 数据结构。
|
- 将 `StageLayer` 色块替换为 tileset、背景图和 props 素材。
|
||||||
- 关卡宽度扩展到 2400 到 3200 像素。
|
- 将 battle zone 占位升级为触发、锁镜头、清场解锁逻辑。
|
||||||
- 引入远景/中景/地面三层绘制。
|
- 将敌人出生点接入 `EnemyActor`。
|
||||||
|
|
||||||
### 4. Actor
|
### 4. Actor
|
||||||
|
|
||||||
@@ -297,9 +299,7 @@ mindmap
|
|||||||
|
|
||||||
- `debug/debug_overlay.*` 已经提供碰撞和玩家包围盒绘制。
|
- `debug/debug_overlay.*` 已经提供碰撞和玩家包围盒绘制。
|
||||||
- `F1` 切换 debug overlay。
|
- `F1` 切换 debug overlay。
|
||||||
- 绘制平台碰撞。
|
- 绘制平台碰撞、battle zone、camera lock 和 spawn point。
|
||||||
- 绘制 battle zone。
|
|
||||||
- 绘制 spawn point。
|
|
||||||
- 绘制 hitbox / hurtbox。
|
- 绘制 hitbox / hurtbox。
|
||||||
- 输出当前场景、角色状态、FPS。
|
- 输出当前场景、角色状态、FPS。
|
||||||
|
|
||||||
@@ -408,15 +408,12 @@ mindmap
|
|||||||
|
|
||||||
下一步建议按这个顺序做:
|
下一步建议按这个顺序做:
|
||||||
|
|
||||||
1. `StageLayer`:把白盒视觉层扩展为背景、地面、平台和 props。
|
1. `StageAssets`:把灰盒 `StageLayer` 替换为 `stage_01` 背景、tiles 和 props 素材。
|
||||||
2. `LevelDefinition`:补齐世界尺寸、玩家出生点、镜头限制、敌人出生点和 battle zone 数据。
|
2. `BattleZone`:在现有 zone 数据上做触发、锁镜头、清场解锁。
|
||||||
3. `StageRenderer`:支持远景/中景/地面/props 分层绘制,先用色块或占位图也可以。
|
3. `EnemyActor`:做第一个敌人占位,接入出生点。
|
||||||
4. `SceneDebug`:显示碰撞、出生点、battle zone、镜头锁定范围,补 `F1` 开关。
|
4. `CombatSystem`:把 hitbox/hurtbox 真正跑起来。
|
||||||
5. `BattleZone`:在场景数据稳定后做触发、锁镜头、清场解锁。
|
5. `SpriteAnimator`:把玩家动画从硬编码改成组件。
|
||||||
6. `EnemyActor`:做第一个敌人占位,接入出生点。
|
6. `InputConfig`:把默认键位/手柄映射迁移到可配置数据。
|
||||||
7. `CombatSystem`:把 hitbox/hurtbox 真正跑起来。
|
|
||||||
8. `SpriteAnimator`:把玩家动画从硬编码改成组件。
|
|
||||||
9. `InputConfig`:把默认键位/手柄映射迁移到可配置数据。
|
|
||||||
|
|
||||||
## 素材协作提示
|
## 素材协作提示
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,14 @@
|
|||||||
|
|
||||||
当前白盒只解决“能跑、能跳、能看到关卡结构”。下一步要把场景拆成数据层、视觉层和玩法层。
|
当前白盒只解决“能跑、能跳、能看到关卡结构”。下一步要把场景拆成数据层、视觉层和玩法层。
|
||||||
|
|
||||||
|
第一轮场景骨架进度:
|
||||||
|
|
||||||
|
- `LevelDefinition` 已扩展世界尺寸、玩家出生点、镜头范围、分层视觉、battle zone 和敌人出生点数据。
|
||||||
|
- 第一关灰盒宽度已扩展到 3200 像素。
|
||||||
|
- `StageRenderer` 已支持远景、中景、地面/平台、后景 props 分层绘制,当前先用色块占位。
|
||||||
|
- `DebugOverlay` 已能显示碰撞、玩家框、battle zone、camera lock 范围和 spawn point。
|
||||||
|
- `WhiteboxScene` 已支持 `F1` 切换 debug overlay。
|
||||||
|
|
||||||
## 2. 第一关场景目标
|
## 2. 第一关场景目标
|
||||||
|
|
||||||
第一关不急着做最终题材,先做通用 ACT 测试关:
|
第一关不急着做最终题材,先做通用 ACT 测试关:
|
||||||
@@ -205,12 +213,12 @@ game/assets/stage/stage_01/
|
|||||||
|
|
||||||
### 先做工程骨架
|
### 先做工程骨架
|
||||||
|
|
||||||
1. 扩展 `LevelDefinition`:加入世界尺寸、玩家出生点、镜头限制、敌人出生点、battle zone 占位数据。
|
1. 已完成:扩展 `LevelDefinition`,加入世界尺寸、玩家出生点、镜头限制、敌人出生点、battle zone 占位数据。
|
||||||
2. 扩展 `StageRenderer`:支持背景层、地面/平台视觉层、后景 props,第一版可以继续用色块。
|
2. 已完成:扩展 `StageRenderer`,支持背景层、地面/平台视觉层、后景 props,第一版继续用色块。
|
||||||
3. 扩展白盒关卡宽度到 2400 到 3200 像素,并整理成 3 段推进节奏。
|
3. 已完成:扩展白盒关卡宽度到 3200 像素,并整理成 3 段推进节奏。
|
||||||
4. 加入 3 个 battle zone debug 标记,但暂不做锁镜头和刷敌逻辑。
|
4. 已完成:加入 3 个 battle zone debug 标记,但暂不做锁镜头和刷敌逻辑。
|
||||||
5. 加入 spawn point debug 标记,用于后续接 `EnemyActor`。
|
5. 已完成:加入 spawn point debug 标记,用于后续接 `EnemyActor`。
|
||||||
6. 补 `F1` debug 开关,至少能切换碰撞、battle zone、spawn point。
|
6. 已完成:补 `F1` debug 开关,可切换碰撞、battle zone、spawn point。
|
||||||
|
|
||||||
### 素材回来后再替换
|
### 素材回来后再替换
|
||||||
|
|
||||||
@@ -225,8 +233,6 @@ game/assets/stage/stage_01/
|
|||||||
|
|
||||||
下一轮优先做:
|
下一轮优先做:
|
||||||
|
|
||||||
- 扩展 `LevelDefinition`。
|
- 如果素材已准备:创建 `game/assets/stage/stage_01/`,接入背景、tiles 和 props,替换灰盒色块。
|
||||||
- 扩展 `StageRenderer`。
|
- 如果素材未准备:先做 `BattleZone` 运行时逻辑,让现有 debug zone 可以触发、锁镜头、清场解锁。
|
||||||
- 将第一关扩到 2400 到 3200 像素。
|
- 保持 debug 碰撞、battle zone、spawn point 显示可用。
|
||||||
- 加入 battle zone / spawn point debug 数据。
|
|
||||||
- 保留 debug 碰撞显示。
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ struct DebugFlags {
|
|||||||
bool showStageGrid = true;
|
bool showStageGrid = true;
|
||||||
bool showCollision = true;
|
bool showCollision = true;
|
||||||
bool showActorBounds = true;
|
bool showActorBounds = true;
|
||||||
|
bool showBattleZones = true;
|
||||||
|
bool showSpawnPoints = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ns_game
|
} // namespace ns_game
|
||||||
|
|||||||
@@ -3,18 +3,58 @@
|
|||||||
#include "../movement/platform_world.h"
|
#include "../movement/platform_world.h"
|
||||||
#include <frostbite2D/types/type_color.h>
|
#include <frostbite2D/types/type_color.h>
|
||||||
#include <frostbite2D/types/type_math.h>
|
#include <frostbite2D/types/type_math.h>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace ns_game {
|
namespace ns_game {
|
||||||
|
|
||||||
|
enum class StageLayerRole {
|
||||||
|
BackgroundFar,
|
||||||
|
BackgroundMid,
|
||||||
|
LevelVisual,
|
||||||
|
PropsBack,
|
||||||
|
PropsFront
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StageRect {
|
||||||
|
frostbite2D::Rect bounds;
|
||||||
|
frostbite2D::Color color;
|
||||||
|
StageLayerRole layer = StageLayerRole::PropsBack;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpawnPoint {
|
||||||
|
std::string id;
|
||||||
|
frostbite2D::Vec2 position;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BattleZoneDefinition {
|
||||||
|
std::string id;
|
||||||
|
frostbite2D::Rect trigger;
|
||||||
|
frostbite2D::Rect cameraBounds;
|
||||||
|
std::vector<SpawnPoint> enemySpawns;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StageLayer {
|
||||||
|
std::string id;
|
||||||
|
StageLayerRole role = StageLayerRole::LevelVisual;
|
||||||
|
float parallax = 1.0f;
|
||||||
|
std::vector<StageRect> rects;
|
||||||
|
};
|
||||||
|
|
||||||
struct WhiteboxProp {
|
struct WhiteboxProp {
|
||||||
frostbite2D::Rect bounds;
|
frostbite2D::Rect bounds;
|
||||||
frostbite2D::Color color;
|
frostbite2D::Color color;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LevelDefinition {
|
struct LevelDefinition {
|
||||||
|
float worldWidth = 0.0f;
|
||||||
|
float worldHeight = 0.0f;
|
||||||
|
frostbite2D::Vec2 playerSpawn;
|
||||||
|
frostbite2D::Rect cameraBounds;
|
||||||
PlatformWorld collision;
|
PlatformWorld collision;
|
||||||
|
std::vector<StageLayer> layers;
|
||||||
std::vector<WhiteboxProp> props;
|
std::vector<WhiteboxProp> props;
|
||||||
|
std::vector<BattleZoneDefinition> battleZones;
|
||||||
};
|
};
|
||||||
|
|
||||||
LevelDefinition CreateWhiteboxLevel();
|
LevelDefinition CreateWhiteboxLevel();
|
||||||
|
|||||||
@@ -4,14 +4,102 @@ namespace ns_game {
|
|||||||
|
|
||||||
LevelDefinition CreateWhiteboxLevel() {
|
LevelDefinition CreateWhiteboxLevel() {
|
||||||
LevelDefinition level;
|
LevelDefinition level;
|
||||||
|
level.worldWidth = 3200.0f;
|
||||||
|
level.worldHeight = 720.0f;
|
||||||
|
level.playerSpawn = frostbite2D::Vec2(160.0f, 380.0f);
|
||||||
|
level.cameraBounds = frostbite2D::Rect(0.0f, 0.0f, level.worldWidth,
|
||||||
|
level.worldHeight);
|
||||||
level.collision.levelLeft = 0.0f;
|
level.collision.levelLeft = 0.0f;
|
||||||
level.collision.levelRight = 1600.0f;
|
level.collision.levelRight = level.worldWidth;
|
||||||
level.collision.platforms = {
|
level.collision.platforms = {
|
||||||
frostbite2D::Rect(0.0f, 600.0f, 1600.0f, 80.0f),
|
frostbite2D::Rect(0.0f, 600.0f, 3200.0f, 80.0f),
|
||||||
frostbite2D::Rect(230.0f, 500.0f, 220.0f, 28.0f),
|
frostbite2D::Rect(230.0f, 500.0f, 220.0f, 28.0f),
|
||||||
frostbite2D::Rect(560.0f, 430.0f, 260.0f, 28.0f),
|
frostbite2D::Rect(560.0f, 430.0f, 260.0f, 28.0f),
|
||||||
frostbite2D::Rect(930.0f, 510.0f, 260.0f, 28.0f),
|
frostbite2D::Rect(930.0f, 510.0f, 260.0f, 28.0f),
|
||||||
frostbite2D::Rect(1250.0f, 420.0f, 230.0f, 28.0f),
|
frostbite2D::Rect(1250.0f, 420.0f, 230.0f, 28.0f),
|
||||||
|
frostbite2D::Rect(1760.0f, 500.0f, 300.0f, 28.0f),
|
||||||
|
frostbite2D::Rect(2180.0f, 455.0f, 260.0f, 28.0f),
|
||||||
|
frostbite2D::Rect(2650.0f, 515.0f, 360.0f, 28.0f),
|
||||||
|
};
|
||||||
|
level.layers = {
|
||||||
|
{"background_far",
|
||||||
|
StageLayerRole::BackgroundFar,
|
||||||
|
0.25f,
|
||||||
|
{{frostbite2D::Rect(0.0f, 0.0f, 3200.0f, 720.0f),
|
||||||
|
frostbite2D::Color(0.08f, 0.10f, 0.14f, 1.0f),
|
||||||
|
StageLayerRole::BackgroundFar},
|
||||||
|
{frostbite2D::Rect(360.0f, 120.0f, 420.0f, 220.0f),
|
||||||
|
frostbite2D::Color(0.13f, 0.16f, 0.21f, 1.0f),
|
||||||
|
StageLayerRole::BackgroundFar},
|
||||||
|
{frostbite2D::Rect(1380.0f, 90.0f, 560.0f, 260.0f),
|
||||||
|
frostbite2D::Color(0.12f, 0.15f, 0.20f, 1.0f),
|
||||||
|
StageLayerRole::BackgroundFar},
|
||||||
|
{frostbite2D::Rect(2440.0f, 140.0f, 520.0f, 210.0f),
|
||||||
|
frostbite2D::Color(0.13f, 0.16f, 0.21f, 1.0f),
|
||||||
|
StageLayerRole::BackgroundFar}}},
|
||||||
|
{"background_mid",
|
||||||
|
StageLayerRole::BackgroundMid,
|
||||||
|
0.55f,
|
||||||
|
{{frostbite2D::Rect(80.0f, 360.0f, 280.0f, 240.0f),
|
||||||
|
frostbite2D::Color(0.18f, 0.22f, 0.27f, 1.0f),
|
||||||
|
StageLayerRole::BackgroundMid},
|
||||||
|
{frostbite2D::Rect(1020.0f, 310.0f, 340.0f, 290.0f),
|
||||||
|
frostbite2D::Color(0.18f, 0.22f, 0.27f, 1.0f),
|
||||||
|
StageLayerRole::BackgroundMid},
|
||||||
|
{frostbite2D::Rect(2020.0f, 330.0f, 360.0f, 270.0f),
|
||||||
|
frostbite2D::Color(0.18f, 0.22f, 0.27f, 1.0f),
|
||||||
|
StageLayerRole::BackgroundMid},
|
||||||
|
{frostbite2D::Rect(2860.0f, 280.0f, 260.0f, 320.0f),
|
||||||
|
frostbite2D::Color(0.18f, 0.22f, 0.27f, 1.0f),
|
||||||
|
StageLayerRole::BackgroundMid}}},
|
||||||
|
{"level_visual",
|
||||||
|
StageLayerRole::LevelVisual,
|
||||||
|
1.0f,
|
||||||
|
{{frostbite2D::Rect(0.0f, 600.0f, 3200.0f, 80.0f),
|
||||||
|
frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f),
|
||||||
|
StageLayerRole::LevelVisual},
|
||||||
|
{frostbite2D::Rect(230.0f, 500.0f, 220.0f, 28.0f),
|
||||||
|
frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f),
|
||||||
|
StageLayerRole::LevelVisual},
|
||||||
|
{frostbite2D::Rect(560.0f, 430.0f, 260.0f, 28.0f),
|
||||||
|
frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f),
|
||||||
|
StageLayerRole::LevelVisual},
|
||||||
|
{frostbite2D::Rect(930.0f, 510.0f, 260.0f, 28.0f),
|
||||||
|
frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f),
|
||||||
|
StageLayerRole::LevelVisual},
|
||||||
|
{frostbite2D::Rect(1250.0f, 420.0f, 230.0f, 28.0f),
|
||||||
|
frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f),
|
||||||
|
StageLayerRole::LevelVisual},
|
||||||
|
{frostbite2D::Rect(1760.0f, 500.0f, 300.0f, 28.0f),
|
||||||
|
frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f),
|
||||||
|
StageLayerRole::LevelVisual},
|
||||||
|
{frostbite2D::Rect(2180.0f, 455.0f, 260.0f, 28.0f),
|
||||||
|
frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f),
|
||||||
|
StageLayerRole::LevelVisual},
|
||||||
|
{frostbite2D::Rect(2650.0f, 515.0f, 360.0f, 28.0f),
|
||||||
|
frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f),
|
||||||
|
StageLayerRole::LevelVisual}}},
|
||||||
|
{"props_back",
|
||||||
|
StageLayerRole::PropsBack,
|
||||||
|
1.0f,
|
||||||
|
{{frostbite2D::Rect(118.0f, 392.0f, 88.0f, 208.0f),
|
||||||
|
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f),
|
||||||
|
StageLayerRole::PropsBack},
|
||||||
|
{frostbite2D::Rect(780.0f, 250.0f, 72.0f, 180.0f),
|
||||||
|
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f),
|
||||||
|
StageLayerRole::PropsBack},
|
||||||
|
{frostbite2D::Rect(1440.0f, 300.0f, 80.0f, 300.0f),
|
||||||
|
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f),
|
||||||
|
StageLayerRole::PropsBack},
|
||||||
|
{frostbite2D::Rect(1880.0f, 360.0f, 110.0f, 240.0f),
|
||||||
|
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f),
|
||||||
|
StageLayerRole::PropsBack},
|
||||||
|
{frostbite2D::Rect(2520.0f, 390.0f, 92.0f, 210.0f),
|
||||||
|
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f),
|
||||||
|
StageLayerRole::PropsBack},
|
||||||
|
{frostbite2D::Rect(3040.0f, 315.0f, 82.0f, 285.0f),
|
||||||
|
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f),
|
||||||
|
StageLayerRole::PropsBack}}},
|
||||||
};
|
};
|
||||||
level.props = {
|
level.props = {
|
||||||
{frostbite2D::Rect(118.0f, 392.0f, 88.0f, 208.0f),
|
{frostbite2D::Rect(118.0f, 392.0f, 88.0f, 208.0f),
|
||||||
@@ -21,6 +109,23 @@ LevelDefinition CreateWhiteboxLevel() {
|
|||||||
{frostbite2D::Rect(1440.0f, 300.0f, 80.0f, 300.0f),
|
{frostbite2D::Rect(1440.0f, 300.0f, 80.0f, 300.0f),
|
||||||
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f)},
|
frostbite2D::Color(0.26f, 0.30f, 0.34f, 1.0f)},
|
||||||
};
|
};
|
||||||
|
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),
|
||||||
|
{{"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),
|
||||||
|
{{"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),
|
||||||
|
{{"zone_03_enemy_a", frostbite2D::Vec2(2580.0f, 560.0f)},
|
||||||
|
{"zone_03_enemy_b", frostbite2D::Vec2(2860.0f, 560.0f)}}},
|
||||||
|
};
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,19 @@ void drawOutline(const frostbite2D::Rect& rect, const frostbite2D::Color& color,
|
|||||||
color);
|
color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawCross(const frostbite2D::Vec2& position,
|
||||||
|
const frostbite2D::Color& color) {
|
||||||
|
constexpr float kSize = 18.0f;
|
||||||
|
constexpr float kThickness = 3.0f;
|
||||||
|
drawRect(frostbite2D::Rect(position.x - kSize * 0.5f,
|
||||||
|
position.y - kThickness * 0.5f, kSize,
|
||||||
|
kThickness),
|
||||||
|
color);
|
||||||
|
drawRect(frostbite2D::Rect(position.x - kThickness * 0.5f,
|
||||||
|
position.y - kSize * 0.5f, kThickness, kSize),
|
||||||
|
color);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void DebugOverlay::Render(const LevelDefinition& level, const DebugFlags& flags,
|
void DebugOverlay::Render(const LevelDefinition& level, const DebugFlags& flags,
|
||||||
@@ -31,6 +44,12 @@ void DebugOverlay::Render(const LevelDefinition& level, const DebugFlags& flags,
|
|||||||
if (flags.showCollision) {
|
if (flags.showCollision) {
|
||||||
drawCollision(level);
|
drawCollision(level);
|
||||||
}
|
}
|
||||||
|
if (flags.showBattleZones) {
|
||||||
|
drawBattleZones(level);
|
||||||
|
}
|
||||||
|
if (flags.showSpawnPoints) {
|
||||||
|
drawSpawnPoints(level);
|
||||||
|
}
|
||||||
if (flags.showActorBounds && playerBounds) {
|
if (flags.showActorBounds && playerBounds) {
|
||||||
drawActorBounds(*playerBounds);
|
drawActorBounds(*playerBounds);
|
||||||
}
|
}
|
||||||
@@ -46,4 +65,21 @@ void DebugOverlay::drawActorBounds(const frostbite2D::Rect& bounds) const {
|
|||||||
drawOutline(bounds, frostbite2D::Color(1.0f, 0.78f, 0.1f, 0.9f));
|
drawOutline(bounds, frostbite2D::Color(1.0f, 0.78f, 0.1f, 0.9f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugOverlay::drawBattleZones(const LevelDefinition& level) const {
|
||||||
|
for (const BattleZoneDefinition& zone : level.battleZones) {
|
||||||
|
drawOutline(zone.trigger, frostbite2D::Color(0.95f, 0.25f, 0.25f, 0.9f),
|
||||||
|
3.0f);
|
||||||
|
drawOutline(zone.cameraBounds,
|
||||||
|
frostbite2D::Color(0.25f, 0.55f, 1.0f, 0.75f), 2.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugOverlay::drawSpawnPoints(const LevelDefinition& level) const {
|
||||||
|
for (const BattleZoneDefinition& zone : level.battleZones) {
|
||||||
|
for (const SpawnPoint& spawn : zone.enemySpawns) {
|
||||||
|
drawCross(spawn.position, frostbite2D::Color(1.0f, 0.2f, 0.9f, 0.95f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ns_game
|
} // namespace ns_game
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void drawCollision(const LevelDefinition& level) const;
|
void drawCollision(const LevelDefinition& level) const;
|
||||||
void drawActorBounds(const frostbite2D::Rect& bounds) const;
|
void drawActorBounds(const frostbite2D::Rect& bounds) const;
|
||||||
|
void drawBattleZones(const LevelDefinition& level) const;
|
||||||
|
void drawSpawnPoints(const LevelDefinition& level) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ns_game
|
} // namespace ns_game
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "../core/game_config.h"
|
#include "../core/game_config.h"
|
||||||
|
|
||||||
#include <frostbite2D/core/application.h>
|
#include <frostbite2D/core/application.h>
|
||||||
|
#include <frostbite2D/event/key_event.h>
|
||||||
#include <frostbite2D/graphics/camera.h>
|
#include <frostbite2D/graphics/camera.h>
|
||||||
#include <frostbite2D/graphics/renderer.h>
|
#include <frostbite2D/graphics/renderer.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -14,6 +15,7 @@ void WhiteboxScene::onEnter() {
|
|||||||
level_ = CreateWhiteboxLevel();
|
level_ = CreateWhiteboxLevel();
|
||||||
|
|
||||||
player_ = frostbite2D::MakePtr<PlayerActor>();
|
player_ = frostbite2D::MakePtr<PlayerActor>();
|
||||||
|
player_->SetTopLeftPosition(level_.playerSpawn);
|
||||||
player_->SetMovementWorld(&level_.collision);
|
player_->SetMovementWorld(&level_.collision);
|
||||||
AddChild(player_);
|
AddChild(player_);
|
||||||
}
|
}
|
||||||
@@ -23,6 +25,19 @@ void WhiteboxScene::OnUpdate(float deltaTime) {
|
|||||||
updateCamera();
|
updateCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WhiteboxScene::OnEvent(const frostbite2D::Event& event) {
|
||||||
|
if (event.getType() == frostbite2D::EventType::KeyDown) {
|
||||||
|
const auto& keyEvent = static_cast<const frostbite2D::KeyEvent&>(event);
|
||||||
|
if (!keyEvent.isRepeat() &&
|
||||||
|
keyEvent.getKeyCode() == frostbite2D::KeyCode::F1) {
|
||||||
|
toggleDebugOverlay();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frostbite2D::Scene::OnEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void WhiteboxScene::Render() {
|
void WhiteboxScene::Render() {
|
||||||
stageRenderer_.Render(level_, debugFlags_);
|
stageRenderer_.Render(level_, debugFlags_);
|
||||||
frostbite2D::Scene::Render();
|
frostbite2D::Scene::Render();
|
||||||
@@ -31,6 +46,18 @@ void WhiteboxScene::Render() {
|
|||||||
debugOverlay_.Render(level_, debugFlags_, player_ ? &playerBounds : nullptr);
|
debugOverlay_.Render(level_, debugFlags_, player_ ? &playerBounds : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WhiteboxScene::toggleDebugOverlay() {
|
||||||
|
const bool enabled = !(debugFlags_.showStageGrid || debugFlags_.showCollision ||
|
||||||
|
debugFlags_.showActorBounds ||
|
||||||
|
debugFlags_.showBattleZones ||
|
||||||
|
debugFlags_.showSpawnPoints);
|
||||||
|
debugFlags_.showStageGrid = enabled;
|
||||||
|
debugFlags_.showCollision = enabled;
|
||||||
|
debugFlags_.showActorBounds = enabled;
|
||||||
|
debugFlags_.showBattleZones = enabled;
|
||||||
|
debugFlags_.showSpawnPoints = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void WhiteboxScene::updateCamera() {
|
void WhiteboxScene::updateCamera() {
|
||||||
if (!player_) {
|
if (!player_) {
|
||||||
return;
|
return;
|
||||||
@@ -43,8 +70,8 @@ void WhiteboxScene::updateCamera() {
|
|||||||
|
|
||||||
const auto playerPos = player_->GetTopLeftPosition();
|
const auto playerPos = player_->GetTopLeftPosition();
|
||||||
const float targetX = std::clamp(playerPos.x - 420.0f,
|
const float targetX = std::clamp(playerPos.x - 420.0f,
|
||||||
level_.collision.levelLeft,
|
level_.cameraBounds.left(),
|
||||||
level_.collision.levelRight -
|
level_.cameraBounds.right() -
|
||||||
static_cast<float>(config::kVirtualWidth));
|
static_cast<float>(config::kVirtualWidth));
|
||||||
renderer->getCamera()->setPosition(frostbite2D::Vec2(targetX, 0.0f));
|
renderer->getCamera()->setPosition(frostbite2D::Vec2(targetX, 0.0f));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ class WhiteboxScene : public frostbite2D::Scene {
|
|||||||
public:
|
public:
|
||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void OnUpdate(float deltaTime) override;
|
void OnUpdate(float deltaTime) override;
|
||||||
|
bool OnEvent(const frostbite2D::Event& event) override;
|
||||||
void Render() override;
|
void Render() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void toggleDebugOverlay();
|
||||||
void updateCamera();
|
void updateCamera();
|
||||||
|
|
||||||
LevelDefinition level_;
|
LevelDefinition level_;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "../core/game_config.h"
|
#include "../core/game_config.h"
|
||||||
|
|
||||||
|
#include <frostbite2D/graphics/camera.h>
|
||||||
#include <frostbite2D/graphics/renderer.h>
|
#include <frostbite2D/graphics/renderer.h>
|
||||||
|
|
||||||
namespace ns_game {
|
namespace ns_game {
|
||||||
@@ -21,11 +22,12 @@ float worldWidthOf(const LevelDefinition& level) {
|
|||||||
void StageRenderer::Render(const LevelDefinition& level,
|
void StageRenderer::Render(const LevelDefinition& level,
|
||||||
const DebugFlags& debugFlags) const {
|
const DebugFlags& debugFlags) const {
|
||||||
drawBackground(level);
|
drawBackground(level);
|
||||||
|
for (const StageLayer& layer : level.layers) {
|
||||||
|
drawLayer(level, layer);
|
||||||
|
}
|
||||||
if (debugFlags.showStageGrid) {
|
if (debugFlags.showStageGrid) {
|
||||||
drawGrid(level);
|
drawGrid(level);
|
||||||
}
|
}
|
||||||
drawProps(level);
|
|
||||||
drawPlatforms(level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StageRenderer::drawBackground(const LevelDefinition& level) const {
|
void StageRenderer::drawBackground(const LevelDefinition& level) const {
|
||||||
@@ -47,19 +49,27 @@ void StageRenderer::drawGrid(const LevelDefinition& level) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StageRenderer::drawProps(const LevelDefinition& level) const {
|
void StageRenderer::drawLayer(const LevelDefinition& level,
|
||||||
for (const auto& prop : level.props) {
|
const StageLayer& layer) const {
|
||||||
drawRect(prop.bounds, prop.color);
|
(void)level;
|
||||||
|
frostbite2D::Vec2 parallaxOffset;
|
||||||
|
if (auto* camera = frostbite2D::Renderer::get().getCamera()) {
|
||||||
|
const frostbite2D::Vec2 cameraPos = camera->getPosition();
|
||||||
|
parallaxOffset.x = cameraPos.x * (1.0f - layer.parallax);
|
||||||
|
parallaxOffset.y = cameraPos.y * (1.0f - layer.parallax);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void StageRenderer::drawPlatforms(const LevelDefinition& level) const {
|
for (const StageRect& rect : layer.rects) {
|
||||||
for (const auto& platform : level.collision.platforms) {
|
frostbite2D::Rect bounds(rect.bounds.left() + parallaxOffset.x,
|
||||||
drawRect(platform, frostbite2D::Color(0.62f, 0.68f, 0.73f, 1.0f));
|
rect.bounds.top() + parallaxOffset.y,
|
||||||
drawRect(frostbite2D::Rect(platform.left(), platform.top(),
|
rect.bounds.width(), rect.bounds.height());
|
||||||
platform.width(), 4.0f),
|
drawRect(bounds, rect.color);
|
||||||
|
if (layer.role == StageLayerRole::LevelVisual) {
|
||||||
|
drawRect(frostbite2D::Rect(bounds.left(), bounds.top(), bounds.width(),
|
||||||
|
4.0f),
|
||||||
frostbite2D::Color(0.91f, 0.95f, 0.98f, 1.0f));
|
frostbite2D::Color(0.91f, 0.95f, 0.98f, 1.0f));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ns_game
|
} // namespace ns_game
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void drawBackground(const LevelDefinition& level) const;
|
void drawBackground(const LevelDefinition& level) const;
|
||||||
void drawGrid(const LevelDefinition& level) const;
|
void drawGrid(const LevelDefinition& level) const;
|
||||||
void drawProps(const LevelDefinition& level) const;
|
void drawLayer(const LevelDefinition& level, const StageLayer& layer) const;
|
||||||
void drawPlatforms(const LevelDefinition& level) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ns_game
|
} // namespace ns_game
|
||||||
|
|||||||
Reference in New Issue
Block a user