Pygame碰撞检测失效,同时按下两个方向键时玩家出现穿墙问题
问题原因
- 你用
last_key仅记录最后一个触发的方向,同时按下两个方向键时,只会对最后记录的方向做位移抵消,另一个方向的穿模位移不会被修正 - 逻辑顺序错误:你先绘制了玩家和墙体的当前帧,再修正坐标,修正后的坐标要等到下一帧才会渲染,碰撞检测的实时性失效
修复方案
把x轴和y轴的移动、碰撞检测分开处理,不要依赖最后按键判断修正方向,调整运算顺序保证修正后再渲染。
修复后完整代码
import pygame import random # 初始化屏幕 pygame.init() screen = pygame.display.set_mode((800, 600)) pygame.display.set_caption("collision test") # 定义墙体参数 wall_height, wall_width = 200, 20 wall_x, wall_y = 400, 300 wall = pygame.Rect(wall_x, wall_y, wall_width, wall_height) # 定义玩家参数 x = 400 y = 300 width = 40 height = 60 vel = 5 run = True while run: pygame.time.delay(50) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() # 先处理x轴移动和碰撞 dx = 0 if keys[pygame.K_LEFT] and x > vel: dx -= vel if keys[pygame.K_RIGHT] and x < 800 - width: dx += vel x += dx # 校验x轴碰撞 player_rect = pygame.Rect(x, y, width, height) if player_rect.colliderect(wall): x -= dx # 再处理y轴移动和碰撞 dy = 0 if keys[pygame.K_UP] and y > vel: dy -= vel if keys[pygame.K_DOWN] and y < 600 - height - vel: dy += vel y += dy # 校验y轴碰撞 player_rect = pygame.Rect(x, y, width, height) if player_rect.colliderect(wall): y -= dy # 所有坐标计算完成后再渲染 screen.fill((0,0,0)) pygame.draw.rect(screen, (244, 247, 30), wall) pygame.draw.rect(screen, (255, 255, 255), (x, y, width, height)) pygame.display.update() pygame.quit()
核心改动说明
- 拆分x、y轴的移动和碰撞校验:x轴移动完立刻做x方向的碰撞修正,再处理y轴的逻辑,两个轴的碰撞互不干扰,同时按两个方向键也能分别修正
- 调整逻辑顺序:所有坐标计算、碰撞修正完成后再执行渲染操作,保证当前帧显示的就是碰撞修正后的正确位置
- 移除了没用的
last_key变量,避免多按键时的判断冲突
内容的提问来源于stack exchange,提问作者hashdankhog
相关产品推荐
相关产品推荐

