PyGame开发俄罗斯方块:如何实现左右移动加速且不影响下落速度?
问题描述
开发俄罗斯方块游戏时,需要实现以下功能:
- 按下向下键时方块快速下落
- 按下左右键时方块快速移动
当前通过pygame.key.get_pressed()检测按键,用pygame.time.set_timer()调整速度:游戏默认定时器间隔为600,按下向下键时改为100实现快速下落。但为左右方向键实现快速移动时,pygame.time.set_timer()会改变全局游戏速度,导致左右移动加速的同时下落速度也变快,需要在不影响其他速度的前提下单独加速左右移动。
当前代码
elif start: for event in pygame.event.get(): attack_stack = 0 pos = pygame.mouse.get_pos() if event.type == QUIT: done = True elif event.type == USEREVENT: # Set speed if not game_over: keys_pressed = pygame.key.get_pressed() # Soft drop if keys_pressed[K_DOWN]: pygame.time.set_timer(pygame.USEREVENT, 100) elif keys_pressed[K_RIGHT]: pygame.time.set_timer(pygame.USEREVENT, 100) if not is_rightedge1(dx, dy, mino_en, rotation, matrix): ui_variables.move_sound.play() dx += 1 elif keys_pressed[K_LEFT]: pygame.time.set_timer(pygame.USEREVENT, 100) if not is_leftedge1(dx, dy, mino_en, rotation, matrix): ui_variables.move_sound.play() dx -= 1 else: pygame.time.set_timer(pygame.USEREVENT, 600)
解决方案
核心思路是将下落和左右移动的速度控制完全分离,避免共用一个全局定时器,以下是两种可行方案:
方案1:使用独立定时器事件
为下落和左右移动分别创建不同的Pygame事件,各自控制定时器间隔,互不干扰:
- 定义两个独立事件:
DROP_EVENT = pygame.USEREVENT + 1 MOVE_EVENT = pygame.USEREVENT + 2
- 初始化时设置下落定时器(默认间隔600),左右移动定时器默认关闭:
pygame.time.set_timer(DROP_EVENT, 600) pygame.time.set_timer(MOVE_EVENT, 0) # 初始不启动移动定时器
- 在事件循环中分别处理两个事件:
DROP_EVENT负责处理方块下落,按下向下键时调整其定时器间隔为100,松开后恢复600MOVE_EVENT负责处理左右移动,按下左右键时启动该定时器(间隔设为50-100实现快速移动),松开后关闭定时器
- 左右移动的逻辑放在
MOVE_EVENT的处理分支中,仅响应该事件触发移动
方案2:使用时间戳控制左右移动(推荐)
不依赖定时器,而是在主循环中通过记录上次移动的时间戳,判断是否达到设定的移动间隔,完全独立于下落定时器:
- 在循环外初始化时间戳和移动间隔参数:
last_left_time = 0 last_right_time = 0 normal_move_interval = 200 # 普通移动间隔(首次按下或轻按) fast_move_interval = 50 # 按住时快速移动间隔
- 修改主循环逻辑,将左右移动的检测从
USEREVENT分支中移出,放到主循环的每帧检测中:
elif start: current_time = pygame.time.get_ticks() keys_pressed = pygame.key.get_pressed() # 处理右移 if keys_pressed[K_RIGHT]: if current_time - last_right_time >= fast_move_interval: if not is_rightedge1(dx, dy, mino_en, rotation, matrix): ui_variables.move_sound.play() dx += 1 last_right_time = current_time else: last_right_time = current_time # 松开右键重置时间戳 # 处理左移 if keys_pressed[K_LEFT]: if current_time - last_left_time >= fast_move_interval: if not is_leftedge1(dx, dy, mino_en, rotation, matrix): ui_variables.move_sound.play() dx -= 1 last_left_time = current_time else: last_left_time = current_time # 松开左键重置时间戳 # 处理事件(仅负责下落和退出等逻辑) for event in pygame.event.get(): attack_stack = 0 pos = pygame.mouse.get_pos() if event.type == QUIT: done = True elif event.type == USEREVENT: if not game_over: # 处理方块下落逻辑 dy += 1 # 此处可添加落地检测、消除行等原有逻辑 # 处理软降(仅调整下落定时器) if keys_pressed[K_DOWN]: pygame.time.set_timer(pygame.USEREVENT, 100) else: pygame.time.set_timer(pygame.USEREVENT, 600)
这种方案完全解耦了下落和左右移动的速度控制,左右移动的速度调整不会影响下落节奏,同时逻辑更清晰,避免了多事件的管理复杂度。
内容的提问来源于stack exchange,提问作者MontaKr
相关产品推荐
相关产品推荐

