0454-Bomb-墙壁碰撞检测
环境
- Time 2024-03-20
- Zig 0.12.0-dev.3152+90c1a2c41
- WSL-Ubuntu 22.04.3 LTS
- raylib 5.0
前言
说明
参考资料:
- 《游戏开发:世嘉新人培训教材》
- 图片素材:https://www.ituring.com.cn/book/1742
目标
对于玩家来说,墙壁不可以通行,需要实现碰撞检测。
isCollision
在引擎层的 backend.zig 中,新增了一个方法来进行碰撞的检测。
pub fn isCollision(rec1: basic.Rectangle, rec2: basic.Rectangle) bool {
return ray.CheckCollisionRecs(toRayRec(rec1), toRayRec(rec2));
}
map.zig
地图层提供了对于碰撞检测的方法,遇到墙则不可以进行移动。
pub fn isCollisionX(self: WorldMap, x: usize, y: usize, role: Role) bool {
for (0..3) |i| {
if (self.isCollision(x, y + i -| 1, role)) return true;
} else return false;
}
pub fn isCollisionY(self: WorldMap, x: usize, y: usize, role: Role) bool {
for (0..3) |i| {
if (self.isCollision(x + i - 1, y, role)) return true;
} else return false;
}
pub fn isCollision(self: WorldMap, x: usize, y: usize, role: Role) bool {
const cell = self.data[x + y * width];
if (!cell.contains(.wall)) return false;
const rec = engine.Rectangle{
.x = x * tileMap.unit,
.y = y * tileMap.unit,
.width = tileMap.unit,
.height = tileMap.unit,
};
return engine.isCollision(rec, role.toCollisionRec());
play.zig
玩法模块中新增了键盘的控制。
fn controlPlayer(self: Gameplay) void {
const speed = engine.frameTime() * roleSpeed;
var p1 = self.map.player1().*;
if (engine.isDown(engine.Key.a)) {
p1.x -|= speed;
const cell = p1.getCell();
if (!self.map.isCollisionX(cell.x -| 1, cell.y, p1))
self.map.player1().*.x = p1.x;
}
if (engine.isDown(engine.Key.d)) {
p1.x += speed;
const cell = p1.getCell();
if (!self.map.isCollisionX(cell.x + 1, cell.y, p1))
self.map.player1().*.x = p1.x;
}
p1 = self.map.player1().*;
if (engine.isDown(engine.Key.w)) {
p1.y -|= speed;
const cell = p1.getCell();
if (!self.map.isCollisionY(cell.x, cell.y -| 1, p1))
self.map.player1().*.y = p1.y;
}
if (engine.isDown(engine.Key.s)) {
p1.y += speed;
const cell = p1.getCell();
if (!self.map.isCollisionY(cell.x, cell.y + 1, p1))
self.map.player1().*.y = p1.y;
}
}
碰撞盒
fn toCollisionRec(self: Role) engine.Rectangle {
return engine.Rectangle{
.x = self.x / speedUnit + 5,
.y = self.y / speedUnit + 5,
.width = tileMap.unit - 10,
.height = tileMap.unit - 7,
};
}
效果
和之前差不多,只是不能通过墙壁。
总结
实现了角色和墙壁的碰撞检测,增加了碰撞盒子的实现。

浙公网安备 33010602011771号