如何使用John Zelle的graphics.py模块检测两个矩形碰撞?
在John Zelle的graphics.py中实现矩形碰撞检测
首先得给你点个赞——你写的collided函数其实是轴对齐矩形(AABB)碰撞检测的标准算法,逻辑完全正确,这种方法的时间复杂度是O(1),本身已经是性能最优的方案了!不过针对graphics.py的特性,我们可以做一些适配性的优化,让代码更贴合模块的设计,也更易用。
1. 适配graphics.py原生Rectangle类的实现
graphics.py中的Rectangle类是通过两个对角Point对象(p1和p2)来定义的,而不是直接存储x、y、width、height。所以我们可以封装一个直接适配原生类的函数:
from graphics import Rectangle, Point def rect_collision(rect1: Rectangle, rect2: Rectangle) -> bool: # 提取第一个矩形的边界值 rect1_left = min(rect1.p1.x, rect1.p2.x) rect1_right = max(rect1.p1.x, rect1.p2.x) rect1_top = min(rect1.p1.y, rect1.p2.y) rect1_bottom = max(rect1.p1.y, rect1.p2.y) # 提取第二个矩形的边界值 rect2_left = min(rect2.p1.x, rect2.p2.x) rect2_right = max(rect2.p1.x, rect2.p2.x) rect2_top = min(rect2.p1.y, rect2.p2.y) rect2_bottom = max(rect2.p1.y, rect2.p2.y) # 标准AABB碰撞检测逻辑 return (rect1_left < rect2_right and rect1_right > rect2_left and rect1_top < rect2_bottom and rect1_bottom > rect2_top)
这个函数直接接收graphics.py的Rectangle实例作为参数,不用手动维护额外的属性,完全贴合模块的使用习惯。
2. 自定义矩形类的简化优化
如果你是自己封装了带x、y、width、height的矩形类,你的原始实现已经很高效了,只需要做一点语法简化就能让代码更清爽:
def collided(self, collider) -> bool: return (self.x < collider.x + collider.width and self.x + self.width > collider.x and self.y < collider.y + collider.height and self.y + self.height > collider.y)
直接返回布尔表达式的结果,省去了冗余的if-return结构,逻辑完全不变,代码更简洁易读。
3. 扩展:矩形与点的碰撞检测(可选)
如果之后需要检测点是否在矩形内,也可以基于同样的逻辑快速实现:
def point_in_rect(point: Point, rect: Rectangle) -> bool: rect_left = min(rect.p1.x, rect.p2.x) rect_right = max(rect.p1.x, rect.p2.x) rect_top = min(rect.p1.y, rect.p2.y) rect_bottom = max(rect.p1.y, rect.p2.y) return (rect_left <= point.x <= rect_right and rect_top <= point.y <= rect_bottom)
总结一下:你最初的实现已经是性能最优的方案了,因为AABB碰撞检测本身就是最快的矩形碰撞判断方式。上面的优化主要是为了更好地适配graphics.py的原生类,或者让代码更简洁易读。
内容的提问来源于stack exchange,提问作者Yawn
相关产品推荐
相关产品推荐

