Python pygame中如何实现按一次方向键让方块持续移动至撞墙停下?
问题原因
你将移动逻辑写在了KEYDOWN事件的触发回调中,这个事件只会在按键按下的瞬间触发一次,因此方块仅会移动一次。同时你使用同一个swipe变量存储四个方向的移动增量,也会出现方向控制冲突的问题。
修改方案
- 新增
move_x、move_y两个变量,分别存储水平、垂直方向的移动速度,初始值为0 - 按键按下时仅修改对应方向的速度值,不要直接在事件回调中修改方块坐标
- 将方块位置更新逻辑移到主循环内,每帧自动执行,实现持续移动效果
- 增加墙体碰撞判断,方块碰到墙体后将对应方向的速度重置为0,即可停止移动
- 删掉冗余的
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
相关产品推荐
相关产品推荐

