我正试着移动雪碧,而按下键。我可以用on_key_press()和on_key_release()来完成这个任务,但是在保持左移动和左移动时遇到了问题。我想使用键轮询,并从pyglet文档中找到了这个。
from pyglet.window import key
window = pyglet.window.Window()
keys = key.KeyStateHandler()
window.push_handlers(keys)
# Check if the spacebar is currently pressed:
if keys[key.SPACE]:
pass 我似乎无法在cocos2d中实现这一点。下面是一个简单的例子。上面印着“按键!”很好,但如果我能把它打印出来的话!当空格键被按下时,它会一再地解决我的问题。
from cocos.director import director
from cocos.layer import *
from cocos.scene import Scene
from pyglet.window import key
from pyglet.window.key import KeyStateHandler
class MyLayer(Layer):
is_event_handler = True
def __init__(self):
super(MyLayer, self).__init__()
self.keys = KeyStateHandler()
director.window.push_handlers(self.keys)
def on_key_press(self, symbol, modifiers):
print('Key press!')
if self.keys[key.SPACE]:
print('Space!')
def main():
director.init(resizable=False, width=1024, height=786)
title_scene = Scene(MyLayer())
director.run(title_scene)
if __name__ == '__main__':
main()为了完整起见,这里是我的on_key_press(),on_key_release()代码。问题是,如果我按右,按左键,向左释放我的雪碧就会停止,因为on_key_release()将x速度设置为零。但是,我仍然是按右,所以我想继续移动方向后,按压和释放左。
def on_key_press(self, symbol, modifiers):
if symbol == key.LEFT:
self.player1.velocity = (-self.player1.speed, self.player1.velocity[1])
if symbol == key.RIGHT:
self.player1.velocity = (self.player1.speed, self.player1.velocity[1])
def on_key_release(self, symbol, modifiers):
if symbol == key.LEFT:
self.player1.velocity = (0, self.player1.velocity[1])
if symbol == key.RIGHT:
self.player1.velocity = (0, self.player1.velocity[1])发布于 2015-05-31 15:13:39
来自竹节导轨
Window.on_key_press和Window.on_key_release事件分别在按下或释放键盘上的任何键时触发。 --这些事件不受“键重复”的影响--一旦按下一个键,就不会再有该键的事件,直到它被释放。
这意味着,如果您按右、按左、放左,但不要向右释放,那么在向右释放并再次按下之前不会分派新的on_key_press事件。
如果您保持现有的结构,我认为您必须检查key.RIGHT是否设置在self.keys中,在on_key_release中。但光靠这个是行不通的。使用当前的代码,您将始终得到keys[key.RIGHT]是False。接下来我会解释这是为什么。
调用director.window.push_handlers(self.keys)时,可以将KeyStateHandler自己的on_key_press和on_key_release处理程序注册到注册MyLayer相应处理程序的队列中。KeyStateHandler的处理程序所做的是在keys dict中设置和取消设置键,这样您就可以查询keys[key.SPACE]来查看是否按住了空格键。
代码的问题在于您在MyLayer的处理程序之前注册了KeyStateHandler的处理程序,这使得MyLayer的处理程序在KeyStateHandler的处理程序之前被调用。所以,当您按下空格并在MyLayer.on_key_press中签入keys[key.SPACE]是否是True时,它就不是了,因为KeyStateHandler还没有设置keys[key.SPACE]。
要在MyLayer之前调用KeyStateHandler的处理程序函数,不应该在MyLayer的构造函数中注册(=push)它们,而是在MyLayer的on_enter函数中注册(=push),如下所示:
def on_enter(self):
super(MyLayer, self).on_enter()
director.window.push_handlers(self.keys)如果这样做,可能还应该删除/取消MyLayer的on_exit函数中的处理程序。
如果您对代码段进行了此更改,则应打印“键按!”还有“太空!”每次按空格键,但不重复,因为每次按下on_key_press事件仍然只发送一次。
您可能已经用CocosNode.schedule计划了一些函数,或者定义了一些使用self.player1.velocity来移动Sprite的操作(从移动操作继承将是一个很好的方法)。获得所需效果的一种方法不是定义您自己的on_key_press和on_key_release处理函数,而是依赖于KeyStateHandler。您按下KeyStateHandler的处理程序函数,就像在代码片段中一样,在计划函数或操作步骤开始时,您从keys dict (正在按下这些键)读取该函数或操作步骤,并在此基础上更新速度。
例如,打印“空格!”重复使用时间表:
from cocos.director import director
from cocos.layer import *
from cocos.scene import Scene
from pyglet.window import key
from pyglet.window.key import KeyStateHandler
class MyLayer(Layer):
def __init__(self):
super(MyLayer, self).__init__()
self.keys = KeyStateHandler()
director.window.push_handlers(self.keys)
self.schedule(self.act_on_input)
def act_on_input(self, dt):
if self.keys[key.SPACE]:
print('Space!')
def main():
director.init(resizable=False, width=1024, height=786)
title_scene = Scene(MyLayer())
director.run(title_scene)
if __name__ == '__main__':
main()请注意,这样做的方式是在KeyStateHandler的self.keys[key.SPACE]处理程序中将True设置为True,每个键按下只调用一次。释放密钥时,在KeyStateHandler的False处理程序中,dict条目设置为False。
https://stackoverflow.com/questions/30552477
复制相似问题