You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:33:00