Hello Mindok,

Thanks for clarifying the situation. There is still one thing unclear for 
me with your new code. Where do you call your `update` function? I would 
imagine it's scheduled every frame?

If that's the case, it's a very bad idea to push the keystate again and 
again every frame. Let me try to show you what happens when you do that. 
Let's take this code as an example:

import pyglet
from pyglet.window import key
from pyglet.event import EVENT_HANDLED, EVENT_UNHANDLED

window = pyglet.window.Window(width=200, height=200, 
                              caption="Event handlers demo")



@window.event
def on_key_press(key, modifiers):
    print('A key was pressed')  
    if key == pyglet.window.key._1:
        print("Change Things")
        change_things(window)
    elif key == pyglet.window.key._2:
        print("Change Things 2")
        change_things2(window)
    print("Event stack depth:", len(window._event_stack))
    print()

def change_things(window):
    @window.event
    def on_key_press(symbol, modifiers):
        print('Ole!')

def change_things2(window):
    @window.event
    def on_key_press(symbol, modifiers):
        print('Zamzam!')

def update(dt):
    window.push_handlers(key_handler)


key_handler = key.KeyStateHandler()
pyglet.clock.schedule_interval(update, 1.0/30.)
pyglet.app.run()

When the application starts, update is going to be called 30 times per 
second. When update is executed, the call to push_handlers will push a new 
frame of event handlers on the event stack and it will be populated with 
the on_key_press and on_key_release event handlers from KeyStateHandler.

The class KeyStatedHandler does not return anything from its on_key_press 
and on_key_release, which means that the event will propagate down the 
stack until you reach the first layer which is the one containing your 
function on_key_press.

When you press '1', you change the on_key_press event from the last event 
handler pushed. As there is a new one every frame, it's really a mess. :)

Here is an example where I have a default event handler on_key_press and I 
push also a KeyStateHandler. In the on_key_press, I display all the keys 
that are being held down. If you press '1', I pop the KeyStateHandler and I 
assign a new on_key_press to another function, which would be the function 
from a new scene.

import pyglet
from pyglet.window import key
from pyglet.event import EVENT_HANDLED, EVENT_UNHANDLED

window = pyglet.window.Window(width=200, height=200, 
                              caption="Event handlers demo")


@window.event
def on_key_press(symbol, modifiers):
    print('Here are all the keys that are being pressed ',
          ' '.join(key.symbol_string(key_pressed) 
                   for key_pressed, state in key_handler.items() 
                   if state is True)
          )

    if symbol == pyglet.window.key._1:
        print("Going to scene 2.")
        print("Popping the key_handler.")
        window.pop_handlers()
        print("And changing the current event handler for on_key_press.")
        window.set_handlers(on_key_press=on_key_press_in_scene_2)

    print()
    return EVENT_HANDLED

def on_key_press_in_scene_2(symbol, modifiers):
    print('Ole!')
    return EVENT_HANDLED



print("Press and hold multiple keys to see them on the screen.")
print("Press '1' to change to a different scene where pressing keys "
    "diplay just one message.")
key_handler = key.KeyStateHandler()
window.push_handlers(key_handler)
pyglet.app.run()

This example does not use any classes. But in a more real example, a Scene 
would be a class that we push on the stack. Here is an example of that:

import pyglet
from pyglet.window import key
from pyglet.event import EVENT_HANDLED, EVENT_UNHANDLED


class SceneManager:
    def __init__(self):
        self.current_scene = None

    def change_scene(self, scene):
        if self.current_scene is not None:
            self.current_scene.exit_scene()
            window.pop_handlers()
        self.current_scene = scene
        window.push_handlers(scene)
        scene.enter_scene()


class Scene:
    def enter_scene(self):
        pass

    def exit_scene(self):
        pass


class SceneOne(Scene):
    def __init__(self):
        self.key_handler = key.KeyStateHandler()
        
    def enter_scene(self):
        window.push_handlers(self.key_handler)

    def exit_scene(self):
        window.pop_handlers()

    def on_key_press(self, symbol, modifiers):
        print('Here are all the keys that are being pressed ',
              ' '.join(key.symbol_string(key_pressed) 
                       for key_pressed, state in self.key_handler.items() 
                       if state is True)
              )

        if symbol == pyglet.window.key._1:
            print("Going to scene 2.")
            scene_mgr.change_scene(SceneTwo())

        print()
        return EVENT_HANDLED


class SceneTwo(Scene):
    def on_key_press(self, symbol, modifiers):
        print('Ole!')
        return EVENT_HANDLED


window = pyglet.window.Window(width=200, height=200, 
                              caption="Event handlers demo")
scene_mgr = SceneManager()
scene_mgr.change_scene(SceneOne())

pyglet.app.run()

This example looks a lot like what Cocos2D does to handle scenes, but here 
with only the more basic stuffs.

-- 
You received this message because you are subscribed to the Google Groups 
"pyglet-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/pyglet-users.
For more options, visit https://groups.google.com/d/optout.

Reply via email to