diff options
-rw-r--r-- | txtgameengine/__main__.py | 56 | ||||
-rw-r--r-- | txtgameengine/app.py | 6 | ||||
-rw-r--r-- | txtgameengine/scenes.py | 63 |
3 files changed, 105 insertions, 20 deletions
diff --git a/txtgameengine/__main__.py b/txtgameengine/__main__.py index 84d71ca..cc4c11c 100644 --- a/txtgameengine/__main__.py +++ b/txtgameengine/__main__.py @@ -1,31 +1,49 @@ import numpy as np -from .app import TxtGameApp +from .scenes import SceneTxtGameApp, Scene from OpenGL.GL import * -class TestApp(TxtGameApp): - def __init__(self): - super().__init__((640, 480), "OpenGL window") +class TriangleScene(Scene): + TRIANGLE_DATA = [ + -1.0, -1.0, 0.0, + 1.0, -1.0, 0.0, + 0.0, 1.0, 0.0, + ] - def init(self): - self.render.setup_vertex_arrays() - #self.platform.check_debug() - self.default_shaders = self.shaders.load_shaders( + def on_enter(self): + self.default_shaders = self.app.shaders.load_shaders( 'base_shaders/vertex.glsl', 'base_shaders/fragment.glsl') - self.tri_buffer = self.render.setup_triangle(np.array([ - -1.0, -1.0, 0.0, - 1.0, -1.0, 0.0, - 0.0, 1.0, 0.0, - ], np.float32)) - - def update(self, delta: float): - super().update(delta) + + self.tri_buffer = self.app.render.setup_triangle( + np.array(self.TRIANGLE_DATA, np.float32)) + self.t = 0 + + def update(self, delta): + self.t += delta + if self.t > 10: + self.push_scene(EvilTriangleScene) + self.t = 0 with self.default_shaders: - self.render.triangle(self.tri_buffer) - + self.app.render.triangle(self.tri_buffer) + + +class EvilTriangleScene(TriangleScene): + TRIANGLE_DATA = [ + -1.0, 1.0, 0.0, + 1.0, 1.0, 0.0, + 0.0, -1.0, 0.0, + ] + +class TestApp(SceneTxtGameApp): + MAIN_SCENE_T = TriangleScene + + def init(self): + super().init() + self.render.setup_vertex_arrays() + # self.platform.check_debug() if __name__ == '__main__': - a = TestApp() + a = TestApp((640, 480), "OpenGL window") a.start() diff --git a/txtgameengine/app.py b/txtgameengine/app.py index 9f48479..f3cb711 100644 --- a/txtgameengine/app.py +++ b/txtgameengine/app.py @@ -17,6 +17,7 @@ class TxtGameApp: self.platform = self.PLATFORM_CLASS(self) self.render = self.RENDER_CLASS(self) self.shaders = self.SHADER_CLASS(self) + self.should_exit = False def init(self): pass @@ -26,7 +27,7 @@ class TxtGameApp: self.init() self.platform.set_clear_color(1, 0, 0.75, 1) last_update_time = self.platform.monotonic_time() - while not self.platform.should_close: + while not (self.platform.should_close or self.should_exit): update_time = self.platform.monotonic_time() self.platform.poll_events() self.update(update_time - last_update_time) @@ -37,3 +38,6 @@ class TxtGameApp: def update(self, delta: float): print("Running: delta = %.4fs, approx. fps = %ds" % (delta, 1. / (delta or EPSILON))) self.platform.clear_background() + + def exit(self): + self.should_exit = True diff --git a/txtgameengine/scenes.py b/txtgameengine/scenes.py new file mode 100644 index 0000000..c08e8db --- /dev/null +++ b/txtgameengine/scenes.py @@ -0,0 +1,63 @@ +import typing + +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
\ No newline at end of file |