Python 现代开发学习笔记

(九)高速移动造成的碰撞穿透

1. 两个端点没有重叠,途中仍可能穿过

玩家在 (100, 110, 48, 24)。一个高 12 的障碍从 y=60 一次走到 y=160:起点在玩家上方,终点在下方,两次 colliderect 都为 False,但它实际经过了玩家。

只把这一帧末尾的矩形拿来比较,丢掉了中途的位置。先用已经学过的 Rect 比较三个位置:

# 项目文件:demos/tunnel_endpoints.py
# 起点、终点、中点都使用已经会用的Rect比较,先看见只检查两端会漏掉的运动。
import pygame

player = pygame.Rect(100, 110, 48, 24)
old = pygame.Rect(100, 60, 40, 12)
new = old.move(0, 100)
middle = old.move(0, 50)
print("起点", player.colliderect(old))
print("终点", player.colliderect(new))
print("中点", player.colliderect(middle))

输出 起点 False、终点 False、中点 True。中点的障碍已经到 y=110,覆盖了玩家内部的一段区域。要找整段运动中的接触位置,需要把两端之间的变化也保留下来。

障碍从y60跨到160,两个端点均不重叠,中点y110已经与玩家重叠

2. 用移动过程中的比例描述时间

把这一小步的开始记为 t=0,结束记为 t=1;t=0.5 就对应刚才的中点,完成本步位移的 50%。t 记录的是本步比例,实际经过时间再由比例乘本步秒数得到。

障碍移动时,也可以先把障碍固定在旧位置,让玩家按相对位移移动。玩家本步不动、障碍向下 100,就变成玩家相对向上 100;这样两个正在动的矩形可以用同一个区间判断。

笔记正文与全部题解 · Ctrl / ⌘ K