sprite - Key polling with cocos2d-python and pyglet -
i'm trying move sprite while key pressed. can on_key_press() , on_key_release(), these run problems moving right while holding left , vice versa. i'd use key polling , found pyglet documentation.
from pyglet.window import key window = pyglet.window.window() keys = key.keystatehandler() window.push_handlers(keys) # check if spacebar pressed: if keys[key.space]: pass i don't seem able implement in cocos2d. simple example below. prints 'key press!' fine, if print 'space!' repeatedly when space key pressed solve problem.
from cocos.director import director cocos.layer import * cocos.scene import scene pyglet.window import key 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() for completeness here on_key_press(), on_key_release() code. problem if press right, press left, release left sprite stopped since on_key_release() sets x velocity zero. but, i'm still pressing right want continue moving directions after pressing , releasing left.
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])
from pyglet guide:
the window.on_key_press , window.on_key_release events fired when key on keyboard pressed or released, respectively. these events not affected "key repeat" -- once key pressed there no more events key until released.
this means if press right, press left, release left, don't release right, new on_key_press events won't dispatched before release right , press again.
if keep structure have, think have check if key.right set in self.keys, inside on_key_release. alone wouldn't work. current code keys[key.right] false. i'll explain next why is.
when call director.window.push_handlers(self.keys), register keystatehandler's own on_key_press , on_key_release handlers same queue register mylayer's corresponding handlers. keystatehandler's handlers set , unset keys in keys dict can example query keys[key.space] see if space key being held down.
the problem code register keystatehandler's handlers before mylayer's handlers, causes mylayer's handlers called before of keystatehandler. when press space , check in mylayer.on_key_press whether keys[key.space] true, not, since keystatehandler hasn't set keys[key.space] yet.
to call keystatehandler's handler functions before of mylayer, shouldn't register (=push) them in mylayer's constructor, in mylayer's on_enter function this:
def on_enter(self): super(mylayer, self).on_enter() director.window.push_handlers(self.keys) if this, should remove/deregister handler's in mylayer's on_exit function.
if make change code snippet, should print 'key press!' , 'space!' every time press space, not repeatedly since on_key_press event still dispatched once per key press.
you have scheduled function cocosnode.schedule, or defined action uses self.player1.velocity move sprite (inheriting move action way this). 1 way effect want not define own on_key_press , and on_key_release handler functions, rely on keystatehandler. push keystatehandler's handler functions in code snippet, , in beginning of scheduled function or action step read keys dict, keys being pressed, , update velocity based on that.
for example, print 'space!' repeatedly using schedule:
from cocos.director import director cocos.layer import * cocos.scene import scene pyglet.window import key 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() note way works self.keys[key.space] set true in keystatehandler's on_key_press handler, called once per key press. when release key, dict entry set false in keystatehandler's on_key_release handler.
Comments
Post a Comment