Day 090 — 碰撞检测与动画 · 图解
AABB 碰撞检测原理
两个矩形不碰撞的情况 (共4种):
情况1: A 在 B 左边
┌───┐ ┌───┐
│ A │ │ B │
└───┘ └───┘
A.right < B.left
情况2: A 在 B 右边
┌───┐ ┌───┐
│ B │ │ A │
└───┘ └───┘
A.left > B.right
情况3: A 在 B 上边
┌───┐
│ A │
└───┘
┌───┐
│ B │
└───┘
A.bottom < B.top
情况4: A 在 B 下边
┌───┐
│ B │
└───┘
┌───┐
│ A │
└───┘
A.top > B.bottom
碰撞条件: 以上4种情况都不发生
圆形碰撞检测
●───────── r_a (圆A半径)
\
\ 距离 d
\
●───────── r_b (圆B半径)
碰撞条件: d <= r_a + r_b
无碰撞: 碰撞: 刚好接触:
● ● ●● ●─●
d > r_a+r_b d < r_a+r_b d = r_a+r_b
碰撞响应类型
┌─────────────────────────────────────────┐
│ 碰撞响应类型 │
├──────────┬──────────────────────────────┤
│ 弹性碰撞 │ 🏀 → 🧱 → 🏀 │
│ │ 速度反转,动能守恒 │
├──────────┼──────────────────────────────┤
│ 非弹性 │ 🏀 → 🧱 → 💥 (停止) │
│ 碰撞 │ 物体粘在一起 │
├──────────┼──────────────────────────────┤
│ 反射碰撞 │ 🏀 ↗ │
│ │ 按法线方向反射 │
├──────────┼──────────────────────────────┤
│ 穿透碰撞 │ 🔫 → 🧱 → 🔫 (穿过) │
│ │ 子弹穿过薄墙 │
└──────────┴──────────────────────────────┘
帧动画原理
时间轴:
0ms 100ms 200ms 300ms 400ms
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐
│ 🧑 │ │ 🧑 │ │ 🧑 │ │ 🧑 │ │ 🧑 │
│ 站立│ │ 抬腿│ │ 跨步│ │ 落地│ │ 站立│
└────┘ └────┘ └────┘ └────┘ └────┘
帧1 帧2 帧3 帧4 帧1(循环)
帧率 = 100ms/帧 = 10fps (每秒10帧)
动画状态机
┌──────────┐
┌────→│ 空闲 │←────┐
│ │ idle │ │
│ └────┬─────┘ │
│ │ 按键 │ 松开
│ ↓ │
│ ┌──────────┐ │
└─────│ 行走 │─────┘
│ walk │
└────┬─────┘
│ 速度>阈值
↓
┌──────────┐
│ 跑步 │
│ run │
└────┬─────┘
│ 跳跃
↓
┌──────────┐
│ 跳跃 │
│ jump │
└──────────┘
缓动函数对比
线性 (linear):
████████████████████ 匀速
二次加速 (ease-in):
█ 先慢
██
███
█████
████████████████████ 后快
二次减速 (ease-out):
████████████████████ 先快
██████████
█████
██
█ 后慢
弹跳 (bounce):
████████████████████
███
█
██
███
████████████████████ 到达后弹跳
四叉树空间分区
初始状态 (一个区域):
┌─────────────────┐
│ · · · · · · · · │
│ · · · · · · · · │
│ · · · · · · · · │
│ · · · · · · · · │
└─────────────────┘
插入4个点后分裂:
┌────────┬────────┐
│ · · │ · │
│ │ │
├────────┼────────┤
│ │ · │
│ · │ │
└────────┴────────┘
查询范围:
┌────────┬────────┐
│ · ┌──┐ │ · │
│ │▓▓│ │ │
├────│▓▓┼────────┤
│ │▓▓│ · │
│ └──┘ · │
└────────┴────────┘
只检测 ▓▓ 区域内的点,跳过其他区域!
碰撞检测流程
游戏循环:
┌─────────────────────────────────────┐
│ 游戏帧 │
│ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │ 处理 │ │ 移动 │ │ 碰撞 │ │
│ │ 输入 │→│ 物体 │→│ 检测 │ │
│ └───────┘ └───────┘ └───┬───┘ │
│ │ │
│ ┌────────┴───┐ │
│ ↓ ↓ │
│ ┌──────────┐ ┌────────┐
│ │ 子弹-敌人 │ │敌人-玩家│
│ │ 碰撞 │ │ 碰撞 │
│ └────┬─────┘ └───┬────┘
│ ↓ ↓ │
│ ┌──────────────────┐ │
│ │ 碰撞响应 │ │
│ │ (扣血/爆炸) │ │
│ └──────────────────┘ │
└─────────────────────────────────────┘