Pygame沿x轴与tile碰撞后滚动异常、y轴滚动正常问题求助
问题根因
- 核心异常原因:碰撞检测函数中,x轴的
rect.x += movement[0]逻辑写在了遍历碰撞tile的for循环内部。当角色沿x轴碰撞到多个堆叠的tile时(比如整面由多个tile拼接而成的墙),移动量会被重复叠加多次,导致角色x坐标出现瞬间跳变,缓动滚动逻辑捕捉到异常坐标后就会出现偏移。y轴场景下几乎不会同时碰撞多个tile,因此不会触发该问题。 - 次要影响因素:x轴碰撞检测使用的临时碰撞盒高度为
atom.height - 1,和y轴检测用的全高碰撞盒不一致,可能会额外提升碰撞误判的概率。
修复方案
- 调整碰撞函数中移动量叠加的位置,将x、y轴的移动量叠加操作从for循环内移到循环外,确保每次碰撞判定仅叠加一次移动量
- (可选)如果没有特殊需求,将x轴碰撞检测用的临时盒高度调整为和y轴一致,避免碰撞判定范围不一致
- (可选)将滚动逻辑的执行顺序调整到碰撞逻辑之后,确保每次计算滚动偏移使用的是碰撞修正后的最终角色坐标
修正后的碰撞函数代码如下:
def collision_move(rect,movement,tiles): collision_types={"Top":False,"Bottom":False,"Left":False,"Right":False} rect_temp=pygame.Rect(rect.x,rect.y,atom.width,atom.height) # 无特殊需求可统一碰撞盒高度 rect_temp.x+=movement[0] hit_list=collision_test(rect_temp,tiles) # 移动量叠加移到循环外,全局仅执行一次 rect.x += movement[0] for tile in hit_list: if movement[0]>0: rect.right=tile.left collision_types["Right"]=True elif movement[0]<0: rect.left=tile.right collision_types["Left"]=True rect_temp=pygame.Rect(rect.x,rect.y,atom.width,atom.height) rect_temp.y+=movement[1] hit_list=collision_test(rect_temp,tiles) # 移动量叠加移到循环外,全局仅执行一次 rect.y += movement[1] for tile in hit_list: if movement[1]>0: rect.bottom=tile.top collision_types["Bottom"]=True elif movement[1]<0: rect.top=tile.bottom collision_types["Top"]=True return rect,collision_types
内容的提问来源于stack exchange,提问作者Dashfast
相关产品推荐
相关产品推荐

