summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--txtgameengine/__main__.py56
-rw-r--r--txtgameengine/app.py6
-rw-r--r--txtgameengine/scenes.py63
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