首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在kivy中处理多个键盘输入?

如何在kivy中处理多个键盘输入?
EN

Stack Overflow用户
提问于 2021-11-13 12:29:24
回答 1查看 39关注 0票数 0

所以我正在开发这个游戏,它是一个平台,所以我现在正在做动作,问题是:

我可以移动球员到左边和右边,我也可以跳跃,但是我不能同时移动和跳跃,就像,当我向前移动时,我想要能够向前跳跃,这需要我按下前进和向上按钮。我已经尝试了很多方法来获取它,但都没有成功,我还没有发现这个问题在谷歌上到处搜索,所以...以下是帮助解决问题的最小代码。问题是玩家要么跳跃,要么移动,当我按下向上键和前进键时,它不会同时做这两件事。

Main.py

代码语言:javascript
运行
复制
from kivy.core.window import Window
from kivymd.app import MDApp
from kivymd.uix.screen import MDScreen
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.properties import Clock

from Player import PlayerImage

class LevelOneLayout(MDFloatLayout):
    pass


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._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)


    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


class MainApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Red"

        return


MainApp().run()

Main.kv

代码语言:javascript
运行
复制
LevelOne:

    LevelOneLayout:


<LevelOneLayout>:


<PlayerImage>:
    source: "player_77x100.png"
    size_hint: None, None
    size: "77dp", "100dp"
    x: "0dp"
    y: "50dp"

Player.py

代码语言:javascript
运行
复制
from kivy.uix.image import Image
from kivy.animation import Animation
from kivymd.uix.floatlayout import MDFloatLayout


class PlayerImage(Image):

    texture_side = "right"

    def __init__(self):
        super().__init__()

        self.velx = 20

        self.player_gravity_vel = 0
        self.on_air = False


    def move_left(self, state, *args):
        if state: 
            self.x -= self.velx
            self.texture_left()
            self.forced_dash = False
        else:
            return None


    def move_right(self, state, *args):
        if state:
            self.x += self.velx
            self.texture_right()
            self.forced_dash = False
        else:
            return None


    def jump(self, state, *args):
        if not self.on_air and state:
            self.player_gravity_vel = 830
            self.on_air = True
        else:
            return None



    def texture_left(self):
        if self.texture.tex_coords[0] == 0: 
            self.texture.flip_horizontal()
            self.texture.ask_update(self.update_texture)
            self.texture_side = "left"


    def texture_right(self):
        if self.texture.tex_coords[0] == 1: 
            self.texture.flip_horizontal()
            self.texture.ask_update(self.update_texture)
            self.texture_side = "right"


    def update_texture(self, texture):
        self.texture = None
        self.texture = texture

PlayerAction.py

代码语言:javascript
运行
复制
key_state = True


def _keyboard_closed(self):
    self._keyboard.unbind(on_key_down = self._on_keyboard_down)
    self._keyboard = None


def _on_keyboard_down(self, keyboard, keycode, *args):

    if keycode[1] == "up":
        self.player_image.jump(key_state)

    if keycode[1] == "left":
        self.player_image.move_left(key_state)

    elif keycode[1] == "right":
        self.player_image.move_right(key_state)

    return True


def _on_keyboard_up(self, keyboard, keycode, *args):

    key_state = False

    if keycode[1] == "up":
        self.player_image.jump(key_state)

    if keycode[1] == "left":
        self.player_image.move_left(key_state)

    elif keycode[1] == "right":
        self.player_image.move_right(key_state)

    return True

EN

回答 1

Stack Overflow用户

发布于 2021-11-13 22:09:43

所以对于一个管理多个按键的例子,我推荐这个链接:https://groups.google.com/g/kivy-users/c/b0Qmv160GBk

这就是我在kivy group support中提出的这个问题的答案,所以我对代码做了一些修改以适合我的代码,并且通过Mr.inclements帮助我做到了这一点:我将更改放在块引号中。

Main.py文件:

代码语言:javascript
运行
复制
from kivy.core.window import Window
from kivymd.app import MDApp
from kivymd.uix.screen import MDScreen
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.properties import Clock

from Player import PlayerImage

class LevelOneLayout(MDFloatLayout):
    pass


class LevelOne(MDScreen):
    from PlayerAction import _keyboard_closed, _on_keyboard_down, _on_keyboard_up, """process_keys"""

    gravity_force = 1800

    def __init__(self, **kwargs):
        super().__init__(**kwargs)    

 
        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.process_keys, 1/30)"""


    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


class MainApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Red"

        return


MainApp().run()

PlayerAction.py文件:

代码语言:javascript
运行
复制
"""pressed_keys = set()"""


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):    

    """pressed_keys.add(keycode[1])"""

    return True


def _on_keyboard_up(self, keyboard, keycode, *args): 

    """pressed_keys.remove(keycode[1])"""    

    return True

"""
def process_keys(self, dt):

    if pressed_keys.issuperset({'up', 'right'}):

        self.player_image.jump()

        self.player_image.move_right()


    elif pressed_keys.issuperset({'up', 'left'}):

        self.player_image.jump()

        self.player_image.move_left()


    elif pressed_keys.issuperset({'left', 'up'}):

        self.player_image.move_left()

        self.player_image.up()


    elif pressed_keys.issuperset({'right', 'up'}):

        self.player_image.move_right()

        self.player_image.up()


    elif pressed_keys.issuperset({'up'}):

        self.player_image.jump()


    elif pressed_keys.issuperset({'left'}):

        self.player_image.move_left()


    elif pressed_keys.issuperset({'right'}):

        self.player_image.move_right()
"""

Player.py文件:

在player.py文件中,我只删除了"jump“、"move_left”和"move_right“方法中的"state”参数,因为我已经删除了PlayerAction.py文件中的"key_state“变量,所以这里不需要"state”参数。

注意,kivy支持组中提供的多个按键示例并不使用时钟来调用"process_key“方法,而只是从"_on_keyboard_down”方法调用,但是这样做仍然会让您感觉第二个键覆盖了第一个键,所以我尝试使用这里的Mr.inclement先生的答案,通过使用时钟调用"process_key“方法,它是有效的。就是这样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69954244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档