summaryrefslogtreecommitdiff
path: root/txtgameengine/scenes.py
blob: 725dbd32ace69d5da1234d36f788d40e9984f54d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import typing
from .input.keyboard import KeyboardCallback
from .app import TxtGameApp


class SceneTxtGameApp(TxtGameApp):
    MAIN_SCENE_T: typing.Type['Scene'] = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.scene_stack = []

    def push_scene(self, scene_t: typing.Type['Scene']):
        if self.scene_stack:
            self.scene_stack[-1].on_pause()
        self.scene_stack += [scene_t(self)]
        self.scene_stack[-1].on_enter()
    
    def pop_scene(self):
        self.scene_stack[-1].on_exit()
        del self.scene_stack[-1]
        if not self.scene_stack:
            self.exit()
            return
        self.scene_stack[-2].on_resume()

    def update(self, delta):
        if not self.scene_stack: # TODO: better lifecycles in TxtGameApp so we dont have to hack this
            self.push_scene(self.MAIN_SCENE_T)
        super().update(delta)
        print("Scene Stack:", ' > '.join(type(x).__name__ for x in self.scene_stack))
        self.scene_stack[-1].update(delta)


class Scene:
    def __init__(self, app: 'SceneTxtGameApp'):
        self.app = app

    def pop_scene(self):
        """Exits this scene and returns control to the parent scene"""
        self.app.pop_scene()

    def push_scene(self, scene_t: typing.Type['Scene']):
        """Pushes a scene type onto the scene stack"""
        self.app.push_scene(scene_t)

    def on_exit(self):
        """Called when the scene is removed from the scene tree"""

    def on_enter(self):
        """Called when the scene is first entered in the scene tree"""
        pass

    def on_pause(self):
        """Called when another scene takes update priority over this scene without unloading this scene"""
        pass

    def on_resume(self):
        """Called when this scene takes over update priority after previously using it to another scene"""
        pass

    def update(self, delta: float):
        """Render the current scene"""
        pass