调整 LightGame 平台碰撞与门尺寸,修复测试编译
- LightPlatform / ShadowPlatform:移除单向板碰撞逻辑,改为完整 tile 碰撞体 - Door:碰撞箱从 32x64 改为 32x32,与单 tile 素材匹配 - 修复 game_engine_tests 编译:补全 LevelData 初始化字段,增加缺失的 include path
This commit is contained in:
parent
48fd7818d7
commit
d49aef8c0f
|
|
@ -159,6 +159,8 @@ if(BUILD_TESTING AND NOT USE_FRAMEBUFFER)
|
|||
target_include_directories(game_engine_tests PRIVATE
|
||||
src/Apps/LightGame/src/engine
|
||||
src/Apps/LightGame/src/systems
|
||||
src/Apps/LightGame/src/levels
|
||||
src/Apps/LightGame/generated
|
||||
${CORE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
|
|
|
|||
21
README.md
21
README.md
|
|
@ -20,7 +20,6 @@
|
|||
- **Linux x86 编译**:验证代码在 GCC/Clang 下有无警告、CMake 配置是否跨平台、系统 SDL2 依赖是否正确。很多嵌入式工具链的问题在 x86 Linux 上就能提前暴露。
|
||||
- **ARM 交叉编译**:最终在 IMX6U 上跑。若目标板使用 SDL2,则 SDL2 仅作为显示/输入适配层,时间由独立 `Platform::ITimeSource` 提供,核心渲染仍按 CPU framebuffer + 一次性提交设计;如需极简依赖,也保留 `/dev/fb0` 后端作为对照。
|
||||
|
||||
|
||||
## 开发规范与性能红线
|
||||
|
||||
IMX6U 运行时性能预算较紧,后续开发必须遵守 `docs/DEVELOPMENT_GUIDELINES.md`。如果目标板使用 SDL2,仍然要把 SDL2 限制在平台适配层,核心逻辑和渲染热路径不直接依赖 SDL:
|
||||
|
|
@ -62,22 +61,26 @@ cmake --build build-win --config Release
|
|||
```
|
||||
|
||||
只构建某个 App:
|
||||
|
||||
```bash
|
||||
cmake --build build-win --config Release --target IMX6U-Game
|
||||
cmake --build build-win --config Release --target IMX6U-Demo
|
||||
```
|
||||
|
||||
构建 `IMX6U-Game` 时会自动重新生成 Tom 的 atlas 头文件;也可以单独执行:
|
||||
|
||||
```bash
|
||||
cmake --build build-win --config Release --target GenerateTomAtlasHeader
|
||||
```
|
||||
|
||||
运行:
|
||||
|
||||
```bash
|
||||
./build-win/Release/IMX6U-Game.exe
|
||||
```
|
||||
|
||||
可选帧率档位:
|
||||
|
||||
```bash
|
||||
./build-win/Release/IMX6U-Game.exe --fps 30
|
||||
./build-win/Release/IMX6U-Game.exe --fps 45
|
||||
|
|
@ -95,23 +98,27 @@ sudo apt-get install libsdl2-dev libsdl2-image-dev cmake g++
|
|||
```
|
||||
|
||||
构建:
|
||||
|
||||
```bash
|
||||
cmake -B build-linux .
|
||||
cmake --build build-linux
|
||||
```
|
||||
|
||||
只构建某个 App:
|
||||
|
||||
```bash
|
||||
cmake --build build-linux --target IMX6U-Game
|
||||
cmake --build build-linux --target IMX6U-Demo
|
||||
```
|
||||
|
||||
构建 `IMX6U-Game` 时会自动重新生成 Tom 的 atlas 头文件;也可以单独执行:
|
||||
|
||||
```bash
|
||||
cmake --build build-linux --target GenerateTomAtlasHeader
|
||||
```
|
||||
|
||||
运行:
|
||||
|
||||
```bash
|
||||
./build-linux/IMX6U-Game
|
||||
```
|
||||
|
|
@ -130,6 +137,7 @@ sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
|
|||
- **Framebuffer 后端**:作为极简依赖和显示通路对照测试。
|
||||
|
||||
构建(Framebuffer 对照后端):
|
||||
|
||||
```bash
|
||||
cmake -B build-arm-fb \
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-linux-gnueabihf.cmake \
|
||||
|
|
@ -142,6 +150,7 @@ cmake --build build-arm-fb
|
|||
注意:Tom 的 atlas 头文件生成工具是主机侧离线工具,依赖 PC/Linux 主机上的 SDL2_image;主机构建 `IMX6U-Game` 时会自动执行,ARM 交叉编译过程不会执行它。如果修改了 `src/Apps/Game/assets/raw/` 里的 PNG,必须先在 Windows 或 Linux x86 构建目录执行 `GenerateTomAtlasHeader` 或构建一次 `IMX6U-Game`,再进行 ARM 交叉编译。ARM 构建只消费已经生成好的 `src/Apps/Game/generated/tom_atlas.h`。
|
||||
|
||||
构建(SDL2 后端,要求工具链/sysroot 可找到目标板 SDL2 开发库):
|
||||
|
||||
```bash
|
||||
cmake -B build-arm-sdl \
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-linux-gnueabihf.cmake \
|
||||
|
|
@ -150,6 +159,7 @@ cmake --build build-arm-sdl
|
|||
```
|
||||
|
||||
部署到开发板:
|
||||
|
||||
```bash
|
||||
scp build-arm-sdl/IMX6U-Game root@imx6u:/tmp/
|
||||
# 或部署 framebuffer 对照版本:
|
||||
|
|
@ -157,6 +167,7 @@ scp build-arm-fb/IMX6U-Game root@imx6u:/tmp/
|
|||
```
|
||||
|
||||
板子上运行:
|
||||
|
||||
```bash
|
||||
/tmp/IMX6U-Game
|
||||
```
|
||||
|
|
@ -315,9 +326,11 @@ IMX6U-Game/
|
|||
## 模块说明
|
||||
|
||||
### Draw2D
|
||||
|
||||
- **DrawContext**:统一绘制入口,封装 FrameBuffer、DepthBuffer、Rasterizer、TriangleRasterizer,对外提供 `clear`、`clear_color`、`clear_depth`、`draw_line`、`draw_triangle`、`draw_sprite`、`draw_sprite_ex`、`draw_text`、`draw_tilemap`、`fill_rect`、`present` 接口
|
||||
|
||||
### RenderData
|
||||
|
||||
- **Image**:通用图像数据结构,持有 `const void* pixels` 和 `PixelFormat`(当前统一 `RGBA5551`),支持 color_key 透明跳过
|
||||
- **Sprite**:描述 atlas 中的子区域,通过 `const Image* atlas` 引用源图,是对外 sprite 绘制单位
|
||||
- **Tilemap**:使用 `uint16_t` tile id 引用 atlas 中的固定大小 tile,`EmptyTile` (`0xFFFF`) 表示空 tile
|
||||
|
|
@ -325,20 +338,24 @@ IMX6U-Game/
|
|||
- **Color**:RGBA8888 颜色值,用于绘制接口参数和调试;sprite 运行时像素格式仍为 RGBA5551
|
||||
|
||||
### Core
|
||||
|
||||
- **FrameBuffer**:CPU 侧 RGB565 颜色缓冲,渲染结果先写在这里
|
||||
- **DepthBuffer**:深度测试用 Z-buffer
|
||||
- **Renderer**:渲染器辅助工具
|
||||
- **Timer**:整数毫秒固定步长 tick 生成器,支持 30/45/60 FPS 档位和每帧剩余时间计算
|
||||
|
||||
### Math
|
||||
|
||||
- 通用数学类型:`Vector2/3/4`、`Matrix4x4`
|
||||
- 纯头文件实现,无动态分配
|
||||
|
||||
### Rasterizer
|
||||
|
||||
- **Rasterizer**:Bresenham 线段光栅化,入口做快速全屏可见性检查,屏幕内走 `set_pixel_unsafe` 快路径,屏幕外走 Cohen-Sutherland 裁剪
|
||||
- **TriangleRasterizer**:扫描线三角形填充 + 定点深度插值(增量式整数边缘函数,内层循环无 float 运算)
|
||||
|
||||
### Platform
|
||||
|
||||
- **IDisplay**:显示后端抽象,解耦渲染与输出
|
||||
- **SDLDisplay**:SDL2 后端,PC 调试和 IMX6U SDL2 目标路径共用这一类适配思想
|
||||
- **FBDisplay**:`/dev/fb0` 对照后端,用于极简显示通路验证
|
||||
|
|
@ -366,6 +383,7 @@ IMX6U-Game/
|
|||
## 当前状态与后续
|
||||
|
||||
**已完成:**
|
||||
|
||||
- 可旋转立方体的 3D 渲染(MVP 变换、背面剔除、扫描线填充、深度测试)
|
||||
- 双平台显示后端(SDL2 / Framebuffer)
|
||||
- 离线资源转换工具:PNG sprite -> RGBA5551 C++ 头文件,像素字体 -> bitmap atlas/header
|
||||
|
|
@ -376,6 +394,7 @@ IMX6U-Game/
|
|||
- CMake 跨平台构建
|
||||
|
||||
**待完成(按优先级):**
|
||||
|
||||
1. FrameBuffer / FBDisplay 性能优化(目标像素格式 backbuffer、dirty rect、专用 tile/sprite 快路径、NEON)
|
||||
2. 应用层拆分(Launcher / GameA / GameB / Shared)和统一 `IApp` 主循环
|
||||
3. SDL2 输入抽象(键盘/触摸/按键状态快照)
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ namespace LightGame
|
|||
|
||||
case GameObjectType::Door:
|
||||
obj.collider = RenderData::BoundingBox2D(
|
||||
Math::Vector2Int(0, 0), Math::Vector2Int(ts, ts * 2));
|
||||
Math::Vector2Int(0, 0), Math::Vector2Int(ts, ts));
|
||||
obj.solid = true;
|
||||
obj.light_threshold = LightThreshold(spawn.light_min, spawn.light_max);
|
||||
obj.sprite = &spr_door_closed;
|
||||
|
|
|
|||
|
|
@ -143,9 +143,6 @@ namespace LightGame
|
|||
continue;
|
||||
}
|
||||
|
||||
const bool is_one_way = (other.type == GameObjectType::LightPlatform ||
|
||||
other.type == GameObjectType::ShadowPlatform);
|
||||
|
||||
const RenderData::BoundingBox2D other_world = other.get_world_collider();
|
||||
world_collider = obj.get_world_collider();
|
||||
|
||||
|
|
@ -154,21 +151,6 @@ namespace LightGame
|
|||
continue;
|
||||
}
|
||||
|
||||
if (is_one_way)
|
||||
{
|
||||
const int32_t obj_bottom = world_collider.max.y;
|
||||
const int32_t other_top = other_world.min.y;
|
||||
const int32_t prev_bottom = obj_bottom - move_y;
|
||||
|
||||
if (prev_bottom > other_top || obj.velocity.y <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
obj.position.y = other_top - (obj.collider.max.y - obj.collider.min.y);
|
||||
obj.velocity.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int32_t overlap_left = world_collider.max.x - other_world.min.x;
|
||||
const int32_t overlap_right = other_world.max.x - world_collider.min.x;
|
||||
|
|
|
|||
|
|
@ -392,6 +392,8 @@ namespace
|
|||
0,
|
||||
spawns,
|
||||
2,
|
||||
nullptr,
|
||||
0,
|
||||
Math::Vector2Int(16, 16),
|
||||
0,
|
||||
0,
|
||||
|
|
|
|||
Loading…
Reference in New Issue