地图就是一个 100x100 的棋盘,每一个格子有一个 世界ID,这样有碰撞的实体碰到切换开关的时候,应用 BFS/DFS 算法,更新联通的格子(世界ID相同的视为联通)。
然后看渲染内容,我们只需要渲染 100x100 个格子就可以,每一个格子的可能性无非是预制的 5x5 贴图中的一种。传统渲染时确定每一个像素点的颜色,我们这里的渲染是确定每一个格子是什么贴图。唯一特殊一点的是,这个游戏分了三层,玩家层始终在最上方,背景层始终在最下方,墙壁、箱子则是在中间。
其中玩家的位置好处理,单独记录,然后渲染在最上层就可以。
墙壁和空白背景都是静态的,放在一起处理。
然后是“箱子”,他的位置和交互由规则系统处理。
一套统一的移动求解器,和 6 个世界的规则模块。
World_Id :: enum u8 {
NONE;
ONE;
TWO;
THREE;
FOUR;
FIVE;
SIX;
}
Tile_Type :: enum u8 {
FLOOR;
WALL;
}
Tell :: struct {
world : World_Id;
tile : Tile_Type;
entity : Entity_Id; // 0 = none
}
map: [100][100]Tile;
渲染的时候发现 world(x,y) != world(x+1,y) 就绘制一套竖向的边界,横向同理。
Entity_Type :: enum {
PLAYER;
BOX;
}
Entity :: struct {
type: Entity_Type;
pos: Vector2i;
// 临时状态
move_dir: Direction;
moving: bool;
flags: Entity_Flags;
}
Move_Intent :: struct {
entity: Entity_Id;
dir: Direction;
}
例如,玩家按下 RIGHT,首先只是产生 Intent(Player, RIGHT) 然后进入 movement solver。
规则系统计算哪些移动成功,最后统一修改坐标。


(one)
[> p 1 | o ...] -> [> p 1 | > o]