How can I use pyglet batches to draw scenes or levels
Question: So I'm currently learning pyglet for Python 2.7 and I'm trying to make a
simple game that has levels. The 1st 'scene' would be the title/intro part,
2nd would be a tutorial of some sort, and the rest are the game levels
themselves.

For this, I've created 7 batches(1 intro, 1 tutorial, 5 levels) namely batch,
batch1, ... batch6. I've also created 7 classes for each of these batches that
represent the scenes/levels. This is what I've done for the intro batch and
class:

    
    
    batch = pyglet.graphics.Batch()
    batch1 = pyglet.graphics.Batch()
    class StartState:
        def __init__(self):
            self.welcome = pyglet.text.Label('WELCOME TO', font_name='Arial', font_size=32, color=(200,255,255,255), x=400, y=550, anchor_x='center', anchor_y='center', batch=batch)
            self.title = pyglet.text.Label("MY GAME", font_name='Arial', font_size=32, color=(100,200,170,255), x=400, y=450, anchor_x='center', anchor_y='center', batch=batch)
            self.press = pyglet.text.Label("press 'SPACE' to continue", font_name='Arial', font_size=32, color=(200,255,150,255), x=400, y=250, anchor_x='center', anchor_y='center', batch=batch)
        def update(self, dt):
            if keymap[pyglet.window.key.SPACE]:
                self.welcome.delete()
                self.title.delete()
                self.press.delete()
                states.pop()
                batch1.draw()
    

The other scenes would also look like that. the states list is a list that I
use to store my classes/scenes. states = [Level5(), Level4(), ... ,
TutorialState(), StartState()]. So every time the condition to advance is
fulfilled, which in this class is to press 'SPACE', the window will be
'cleared' i.e. delete the sprites/labels and proceed to the next scene by
using states.pop() and batch1.draw().

After I've typed these classes, I added this at the end:

    
    
    @window.event
    def on_draw():
        window.clear()
        batch.draw()
    
    def update(dt):
        if len(states):
            states[-1].update(dt)
        else:
            pyglet.app.exit()
    
    states.append(Level5())
    states.append(Level4())
    states.append(Level3())
    states.append(Level2())
    states.append(Level1())
    states.append(TutorialState())
    states.append(StartState())
    
    
    pyglet.clock.schedule_interval(update, 1.0/60.0)
    window.clear()
    window.flip()
    window.set_visible(True)
    pyglet.app.run()
    

The problem here is that it only loads the starting batch/scene. Whenever I
press 'SPACE' to go to the tutorial scene the labels/sprites of the starting
batch disappear but it doesn't draw batch1 or load the the tutorial
class/scene. Any suggestions?


Answer: After creating a batch for each scene class:

    
    
        import pyglet
        from pyglet.window import key
    
        class SceneTemplate(object):
            """a template with common things used by every scene"""
            def __init__(self, text):
                self.batch = pyglet.graphics.Batch()
                self.label = pyglet.text.Label(
                    text,
                    font_name='Arial', font_size=32,
                    color=(200, 255, 255, 255), x=32, y=704,
                    batch=self.batch)
                # (...)
    
        class MainMenuScene(SceneTemplate):
            def __init__(self):
                super(MainMenuScene, self).__init__(text='MainMenuScene')
                # (...)
    
        class IntroScene(SceneTemplate):
            def __init__(self):
                super(IntroScene, self).__init__(text='Introduction')
                # (...)
    
        class Level1(SceneTemplate):
            def __init__(self):
                super(Level1, self).__init__(text='Level 1')
                # (...)
    

You can control the state/scene in another class, such as a window class
(personally I like to [subclass the pyglet window, to keep things organized
and some other
reasons](http://pyglet.readthedocs.org/en/latest/programming_guide/windowing.html#subclassing-
window)):

    
    
        class Window(pyglet.window.Window):
            def __init__(self):
                super(Window, self).__init__(width=1024, height=768)
                self.states = [MainMenuScene(), IntroScene(), Level1()]  # and so on...
                self.current_state = 0  # later you change it to get the scene you want
                self.set_visible()
    
            def on_draw(self):
                self.clear()
                self.states[self.current_state].batch.draw()
    
            def on_key_press(self, symbol, modifiers):
                if symbol == key.SPACE:
                    new_state = self.current_state + 1
                    new_state = new_state % len(self.states)
                    self.current_state = new_state   
                # if you want each scene to handle input, you could use pyglet's push_handlers(), or even something like:
                #     self.states[self.current_state].on_key_press(symbol, modifiers)
                # giving them access to the window instance might be needed.
    
        if __name__ == '__main__':
            window = Window()
            pyglet.app.run()
    

