HarmonyOS应用开发实战:猫猫大作战-碰撞检测与重力下落
·


前言
在「猫猫大作战」中,猫咪从棋盘顶部落下,碰到已停落的猫咪或棋盘底部时停止。碰撞检测决定了猫咪的下落路径和最终位置,是物理模拟的核心。
一、重力下落
private readonly GRAVITY_SPEED = 1; // 每帧下落 1 行
updateCatPosition(cat: Cat): void {
if (!cat.falling) return;
const targetY = this.findLandingY(cat.x, cat.y);
if (cat.y < targetY) {
cat.y += this.GRAVITY_SPEED; // 下落
} else {
cat.falling = false; // 着陆
}
}
二、碰撞检测算法
private findLandingY(x: number, startY: number): number {
// 从 startY 开始向下查找第一个空位
for (let y = startY; y < GameConfig.BOARD_HEIGHT; y++) {
if (this.board[y][x] !== null) {
return y - 1; // 被挡住,停在上一行
}
}
return GameConfig.BOARD_HEIGHT - 1; // 到底部
}
// 水平碰撞(合并检测)
private findSameLevelNeighbors(x: number, y: number, level: CatLevel): { x: number; y: number }[] {
const neighbors: { x: number; y: number }[] = [];
const directions = [[-1,0], [1,0], [0,-1], [0,1]]; // 上下左右
for (const [dx, dy] of directions) {
const nx = x + dx;
const ny = y + dy;
if (nx >= 0 && nx < 5 && ny >= 0 && ny < 8) {
const cat = this.board[ny][nx];
if (cat && cat.level === level) {
neighbors.push({ x: nx, y: ny });
}
}
}
return neighbors;
}
三、配置参数
| 参数 | 值 | 说明 |
|---|---|---|
| GRAVITY_SPEED | 1 | 每 100ms 下落 1 行 |
| BOARD_WIDTH | 5 | 棋盘宽度(列) |
| BOARD_HEIGHT | 8 | 棋盘高度(行) |
| CELL_SIZE | 60vp | 每格像素大小 |
| UPDATE_INTERVAL | 100ms | 物理更新周期 |
四、四种碰撞场景
| 场景 | 检测结果 | 行为 |
|---|---|---|
| 底部空 | y === HEIGHT-1 | 停在底部 |
| 下方有猫 | board[y+1][x] !== null | 停在当前行 |
| 左右同级 | 邻居 level 相同 | 触发合并 |
| 已在行内 | board[y][x] !== null | 游戏结束 |
五、优化建议
- 从下往上扫描:碰撞检测从下往上更快
- 缓存落点:同一列多次计算落点时缓存结果
- 只更新移动中的猫咪:已着陆的猫跳过物理计算
总结
碰撞检测通过从当前位置向下查找空位,确定猫咪的最终着陆位置。核心要点:findLandingY 查找落点、 GRAVITY_SPEED=1 逐行下落、 四方向邻居检测合并、 着陆后 falling=false。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
更多推荐



所有评论(0)