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

Python pygame中如何实现按一次方向键让方块持续移动至撞墙停下?

问题原因

你将移动逻辑写在了KEYDOWN事件的触发回调中,这个事件只会在按键按下的瞬间触发一次,因此方块仅会移动一次。同时你使用同一个swipe变量存储四个方向的移动增量,也会出现方向控制冲突的问题。

修改方案

  1. 新增move_x、move_y两个变量,分别存储水平、垂直方向的移动速度,初始值为0
  2. 按键按下时仅修改对应方向的速度值,不要直接在事件回调中修改方块坐标
  3. 将方块位置更新逻辑移到主循环内,每帧自动执行,实现持续移动效果
  4. 增加墙体碰撞判断,方块碰到墙体后将对应方向的速度重置为0,即可停止移动
  5. 删掉冗余的print(window)、pygame.display.update()代码,pygame.display.flip()已经可以完成全屏刷新操作

修正后完整代码

import pygame

pygame.init()
clock = pygame.time.Clock()
# 窗口配置
window = pygame.display.set_mode((600,600))
pygame.display.set_caption('SwipeIt')
# 加载角色素材
square = pygame.image.load('asset/square.png').convert_alpha()
square_rect = square.get_rect(center = (100,150))
# 加载墙体素材
wall1 = pygame.image.load('asset/wall1.png').convert()
wall2 = pygame.image.load('asset/wall2.png').convert()
screw = pygame.image.load('asset/screw.png').convert()
white = (255,252,252)
# 移动参数配置,可根据需要调整速度大小
move_speed = 2
move_x = 0
move_y = 0
# 墙体边界参数,根据你放置的墙体位置调整
left_bound = 34
right_bound = 565
top_bound = 34
bottom_bound = 566

loop = True
while loop:
    window.fill(white)
    # 绘制墙体
    window.blit(wall1,(0,0))
    window.blit(wall2,(0,0))
    window.blit(wall2,(565,0))
    window.blit(wall1,(0,566))
    window.blit(screw,(0,0))
    window.blit(screw,(0,566))
    window.blit(screw,(565,0))
    window.blit(screw,(565,566))
    # 绘制角色
    window.blit(square,square_rect)

    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            # 按下按键时设置对应方向的速度,每次按键只会触发一次速度赋值
            if event.key == pygame.K_DOWN:
                move_y = move_speed
                move_x = 0
            if event.key == pygame.K_UP:
                move_y = -move_speed
                move_x = 0
            if event.key == pygame.K_RIGHT:
                move_x = move_speed
                move_y = 0
            if event.key == pygame.K_LEFT:
                move_x = -move_speed
                move_y = 0
        if event.type == pygame.QUIT:
            loop = False
    
    # 每帧更新角色位置
    square_rect.centerx += move_x
    square_rect.centery += move_y

    # 碰撞检测,碰到边界后停止移动并修正位置避免卡墙
    if square_rect.left <= left_bound:
        square_rect.left = left_bound
        move_x = 0
    if square_rect.right >= right_bound:
        square_rect.right = right_bound
        move_x = 0
    if square_rect.top <= top_bound:
        square_rect.top = top_bound
        move_y = 0
    if square_rect.bottom >= bottom_bound:
        square_rect.bottom = bottom_bound
        move_y = 0

    pygame.display.flip()
    clock.tick(120)

pygame.quit()

如果需要更精准的不规则墙体碰撞检测,可以把所有墙体都封装成pygame.Rect对象,调用colliderect方法判断方块和墙体的碰撞即可。


内容的提问来源于stack exchange,提问作者Hồ Quang Vinh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:48:01