如何在Kivy中处理多键盘输入实现平台游戏同时移动与跳跃
你的代码存在两个核心问题,导致无法同时触发移动和跳跃:
- 按键事件逻辑存在缺陷
- 你通过事件触发的方式执行移动逻辑,仅在按键按下的瞬间执行一次移动操作,无法支持长按持续移动
- 左右按键的判断混用了
if和elif,且没有维护全局的按键状态表,无法同时识别多个按键的按下状态 - 你定义的
key_state是全局变量,按键松开时的赋值仅作用于函数局部作用域,逻辑完全不生效
- 移动逻辑的执行时机错误
角色的持续移动应该放在帧更新循环中执行,而不是绑定在按键按下事件上
修复方案
步骤1:修改Main.py中的LevelOne类
首先在__init__方法中新增按键状态存储,同时新增帧更新的移动调度逻辑:
class LevelOne(MDScreen): from PlayerAction import _keyboard_closed, _on_keyboard_down, _on_keyboard_up gravity_force = 1800 def __init__(self, **kwargs): super().__init__(**kwargs) # 新增:存储当前按下的按键状态 self.pressed_keys = set() self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self._keyboard.bind(on_key_down = self._on_keyboard_down) self._keyboard.bind(on_key_up = self._on_keyboard_up) Clock.schedule_once(self.setup, 1/60) def setup(self, dt): self.player_image = PlayerImage() self.add_widget(self.player_image) Clock.schedule_interval(self.game_gravity, 1/30) # 新增:每帧更新角色移动状态 Clock.schedule_interval(self.update_movement, 1/30) # 新增:每帧根据按键状态执行移动 def update_movement(self, dt): if "left" in self.pressed_keys: self.player_image.move_left(True) if "right" in self.pressed_keys: self.player_image.move_right(True) # 原有game_gravity方法保持不变 def game_gravity(self, dt): if self.player_image.on_air: self.player_image.player_gravity_vel -= self.gravity_force * 1/30 self.player_image.y += self.player_image.player_gravity_vel * 1/30 if self.player_image.y <= 60: self.player_image.y = 60 self.player_image.player_gravity_vel = 0 self.player_image.on_air = False
步骤2:重写PlayerAction.py的全部逻辑
def _keyboard_closed(self): self._keyboard.unbind(on_key_down = self._on_keyboard_down) self._keyboard.unbind(on_key_up = self._on_keyboard_up) self._keyboard = None def _on_keyboard_down(self, keyboard, keycode, *args): key = keycode[1] # 将按下的按键存入状态集合 if key in ("up", "left", "right"): self.pressed_keys.add(key) # 跳跃仅在按下瞬间触发 if key == "up": self.player_image.jump(True) return True def _on_keyboard_up(self, keyboard, keycode, *args): key = keycode[1] # 将松开的按键从状态集合移除 if key in self.pressed_keys: self.pressed_keys.remove(key) return True
修改完成后,按住方向键的同时按下跳跃键,就会每帧同时执行移动和重力更新,实现预期的向前跳跃效果。
内容的提问来源于stack exchange,提问作者Stoicism
相关产品推荐
相关产品推荐

