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

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事件,各自控制定时器间隔,互不干扰:

  1. 定义两个独立事件:
DROP_EVENT = pygame.USEREVENT + 1
MOVE_EVENT = pygame.USEREVENT + 2
  1. 初始化时设置下落定时器(默认间隔600),左右移动定时器默认关闭:
pygame.time.set_timer(DROP_EVENT, 600)
pygame.time.set_timer(MOVE_EVENT, 0)  # 初始不启动移动定时器
  1. 在事件循环中分别处理两个事件:
    • DROP_EVENT负责处理方块下落,按下向下键时调整其定时器间隔为100,松开后恢复600
    • MOVE_EVENT负责处理左右移动,按下左右键时启动该定时器(间隔设为50-100实现快速移动),松开后关闭定时器
  2. 左右移动的逻辑放在MOVE_EVENT的处理分支中,仅响应该事件触发移动

方案2:使用时间戳控制左右移动(推荐)

不依赖定时器,而是在主循环中通过记录上次移动的时间戳,判断是否达到设定的移动间隔,完全独立于下落定时器:

  1. 在循环外初始化时间戳和移动间隔参数:
last_left_time = 0
last_right_time = 0
normal_move_interval = 200  # 普通移动间隔(首次按下或轻按)
fast_move_interval = 50     # 按住时快速移动间隔
  1. 修改主循环逻辑,将左右移动的检测从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:40:38