Python Kivy-如何对多个按键做出反应?

Python Kivy-如何对多个按键做出反应?,python,kivy,keyboard-events,keydown,Python,Kivy,Keyboard Events,Keydown,所以我读了这篇文章: 我在Kivy网站()上的教程中实现了乒乓球游戏。 我的PongGame小部件具有以下方法: def __init__(self): super(PongGame, self).__init__() self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self._keyboard.bind(on_key_down = self._on_keyboard_down)

所以我读了这篇文章:

我在Kivy网站()上的教程中实现了乒乓球游戏。 我的PongGame小部件具有以下方法:

def __init__(self):
    super(PongGame, self).__init__()
    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)

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

def _on_keyboard_down (self, keyboard, keycode, text, modifiers):
    print('### ----------------------------------- ###')
    print('The keys', keycode, 'have been pressed down')
    print('You pressed the key', keycode[1], '.', sep=' ', end='\n')
    #print(' - text is %r' % text)
    print(' - modifiers are %r' % modifiers)

    if keycode[1] == 'w':
        if self.player1.center_y + 20 < self.height-85:
            self.player1.center_y += 20
    elif keycode[1] == 's':
        self.player1.center_y -= 20
    elif keycode[1] == 'up':
        self.player2.center_y += 20
    elif keycode[1] == 'down':
        self.player2.center_y -= 20

    return True
"""
def _on_keyboard_up (self, keyboard, keycode, text, modifiers):
    print('### ----------------------------------- ###')
    print('The keys', keycode, 'have been released.')
    print('You pressed the key', keycode[1], '.', sep=' ', end='\n')
    #print(' - text is %r' % text)
    print(' - modifiers are %r' % modifiers)

    return True
"""

def _on_keyboard_up(self, *args):
    print('up', args)
def\uuuu初始化(自):
超级(PongGame,self)。\uuuu init\uuuuu()
self.\u-keyboard=Window.request\u-keyboard(self.\u-keyboard\u-closed,self)
self.\u keyboard.bind(按键盘上下=按键盘上下)
self.\u keyboard.bind(在键盘上=self.\u在键盘上)
def_键盘_关闭(自身):
self.\u keyboard.unbind(按键盘上下=self.\u键盘上下)
self.\u键盘=无
键盘上下定义(self、键盘、键码、文本、修改器):
打印(“######---------------------------------------###”)
打印('按键'、按键代码'已按下')
打印('您按了键',键码[1],'。,sep='',end='\n')
#打印('-text为%r'%text)
打印('-modifiers是%r'%modifiers)
如果键码[1]=“w”:
如果self.player1.center_y+20
有了这个,我可以用“w”、“s”、“向上”和“向下”来控制两个玩家。但是,仅执行上次按下按钮的操作。这是一个问题,因为当其他玩家想要移动他们的球拍时,他们可能会一直按下按钮来干扰彼此的输入

我该如何实现,让两个玩家同时控制,这样他们就不会互相妨碍,除非键盘不能再按任何键(硬件限制)


目前我想用Kivy开发桌面游戏,而不是智能手机,所以我想用一个真正的键盘来控制角色。

我现在找到了一个解决方案,但我不知道这是否是我们能拥有的最好的解决方案。 以下是pong应用程序的完整代码,它使玩家能够独立地移动他们的球拍

from random import randint
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock


class PongPaddle(Widget):
    score = NumericProperty(0)


    def bounce_ball (self, ball):
        if self.collide_widget(ball):
            vx, vy = ball.velocity
            offset = (ball.center_y - self.center_y) / (self.height / 2)
            bounced = Vector(-1 * vx, vy)
            vel = bounced * 1.1
            ball.velocity = vel.x, vel.y + offset


class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)


    def move (self):
        self.pos = Vector(*self.velocity) + self.pos


class PongGame(Widget):
    ball = ObjectProperty(None)
    player1 = ObjectProperty(None)
    player2 = ObjectProperty(None)

    pressed_keys = {
        'w': False,
        's': False,
        'up': False,
        'down': False
    }


    def __init__(self):
        super(PongGame, self).__init__()
        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)


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


    def _on_keyboard_down (self, keyboard, keycode, text, modifiers):
        #pressed_key = self._keyboard.keycode_to_string(keycode) # this does not work somehow
        pressed_key = keycode[1]
        print('You pressed the key', pressed_key, '.', sep=' ', end='\n')

        self.pressed_keys[pressed_key] = True

        return True


    def _on_keyboard_up (self, keyboard, keycode):
        released_key = keycode[1]
        print('You released the key', released_key, '.', sep=' ', end='\n')
        self.pressed_keys[released_key] = False
        return True


    def serve_ball (self, vel=(4, 0)):
        self.ball.center = self.center
        self.ball.velocity = Vector(vel).rotate(randint(0, 360))


    def update (self, dt):
        self.ball.move()

        # bounce of paddles
        self.player1.bounce_ball(self.ball)
        self.player2.bounce_ball(self.ball)

        # bounce ball off bottom or top
        if (self.ball.y < self.y) or (self.ball.top > self.top):
            self.ball.velocity_y *= -1

        # went of to a side to score point?
        if self.ball.x < self.x:
            self.player2.score += 1
            self.serve_ball(vel=(4, 0))

        if self.ball.x > self.width:
            self.player1.score += 1
            self.serve_ball(vel=(-4, 0))

        # actions for keys pressed
        if self.pressed_keys['w']:
            if self.player1.center_y + 20 < self.height:
                self.player1.center_y += 20

        if self.pressed_keys['s']:
            if self.player1.center_y + 20 > 0:
                self.player1.center_y -= 20

        if self.pressed_keys['up']:
            if self.player2.center_y + 20 < self.height:
                self.player2.center_y += 20

        if self.pressed_keys['down']:
            if self.player2.center_y + 20 > 0:
                self.player2.center_y -= 20


    def on_touch_move (self, touch):
        if touch.x < self.width / 3:
            self.player1.center_y = touch.y
        if touch.x > self.width - self.width / 3:
            self.player2.center_y = touch.y


class PongApp(App):
    def build (self):
        game = PongGame()
        game.serve_ball()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return game


if __name__ == '__main__':
    PongApp().run()
来自随机导入randint
从kivy.app导入应用程序
从kivy.core.window导入窗口
从kivy.uix.widget导入widget
从kivy.properties导入NumericProperty、ReferenceListProperty和ObjectProperty
从kivy.vector导入向量
从kivy.clock导入时钟
类PongPaddle(小部件):
分数=数值属性(0)
def弹跳球(自身,球):
如果self.collide_小部件(球):
vx,vy=球的速度
偏移=(ball.center_y-self.center_y)/(self.height/2)
反弹=矢量(-1*vx,vy)
水平=反弹*1.1
球体速度=x层,y层+偏移
类PongBall(小部件):
速度x=数值属性(0)
速度_y=数值属性(0)
速度=ReferenceListProperty(速度x,速度y)
def移动(自我):
self.pos=向量(*self.velocity)+self.pos
类PongGame(小部件):
ball=ObjectProperty(无)
player1=ObjectProperty(无)
player2=ObjectProperty(无)
按下按钮={
w:错,
s:错,
“向上”:错误,
“向下”:错误
}
定义初始化(自):
超级(PongGame,self)。\uuuu init\uuuuu()
self.\u-keyboard=Window.request\u-keyboard(self.\u-keyboard\u-closed,self)
self.\u keyboard.bind(按键盘上下=按键盘上下)
self.\u keyboard.bind(在键盘上=self.\u在键盘上)
def_键盘_关闭(自身):
self.\u keyboard.unbind(按键盘上下=self.\u键盘上下)
self.\u键盘=无
键盘上下定义(self、键盘、键码、文本、修改器):
#按下键=self.\u键盘。键码\u到字符串(键码)#不知怎的,这不起作用
按下按键=按键代码[1]
打印('您按键',按键',sep='',end='\n')
self.pressed_key[pressed_key]=真
返回真值
键盘上的定义(自身、键盘、键码):
释放键=键码[1]
打印('youreleasedthekey','releasedthekey','sep='',end='\n')
self.pressed_keys[released_key]=False
返回真值
def发球(自我,水平=(4,0)):
self.ball.center=self.center
self.ball.velocity=向量(vel).旋转(randint(0360))
def更新(自我,dt):
self.ball.move()
#桨的弹跳
self.player1.弹起球(self.ball)
self.player2.弹起球(self.ball)
#将球从底部或顶部反弹
如果(self.ball.yself.top):
self.ball.velocity_y*=-1
#跑到一边去得分?
如果self.ball.xself.width:
self.player1.score+=1
自我发球(水平=(-4,0))
#按键操作
如果按下self.键['w']:
如果self.player1.center_y+200:
self.player1.center_y-=20
如果按下self.键['up']:
如果self.player2.center_y+200:
self.player2.center_y-=20
def on_touch_move(自我,触摸):
如果触摸.xself.wid
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.clock import Clock

class Basic(Widget):

    pFrame = 0

    def __init__(self, **kwargs):
        super(Basic, self).__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)

        self.pressed_keys = set()

        self.pressed_actions = {
            'w': lambda: self.text_example('w pressed'),
            's': lambda: self.text_example('s pressed'),
            'a': lambda: self.text_example('a pressed'),
            'd': lambda: self.text_example('d pressed'),
        }

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

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        self.pressed_keys.add(keycode[1])

    def _on_keyboard_up(self, keyboard, keycode):
        self.pressed_keys.remove(keycode[1])

    def text_example(self, text):
        print('Frame: %s Key %s' % (self.pFrame, text))

    def update(self, dt):
        for key in self.pressed_keys:
            try:
                self.pressed_actions[key]()
            except KeyError:
                print("Frame: %s Key %s. Omitted" % (self.pFrame, key))

        self.pFrame += 1

class MyApp(App):

    def build(self):    
        basic = Basic() 
        Clock.schedule_interval(basic.update, 1.0 / 2.0)
        return basic

if __name__ == '__main__':
    try:
        MyApp().run()
    except KeyboardInterrupt:
        print('App has been closed by ^C')