summaryrefslogtreecommitdiff
path: root/composeApp/src/commonMain/kotlin/coffee/liz/abstractionengine/game/Game.kt
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-10-23 21:59:37 -0700
committerElizabeth Hunt <me@liz.coffee>2025-10-24 20:00:58 -0700
commit64f825465de9fa30c4dfe2707067efdb96110db8 (patch)
tree5241385e316e2f4ceede5018603103d71be75202 /composeApp/src/commonMain/kotlin/coffee/liz/abstractionengine/game/Game.kt
downloadabstraction-engine-kt-64f825465de9fa30c4dfe2707067efdb96110db8.tar.gz
abstraction-engine-kt-64f825465de9fa30c4dfe2707067efdb96110db8.zip
Init
Diffstat (limited to 'composeApp/src/commonMain/kotlin/coffee/liz/abstractionengine/game/Game.kt')
-rw-r--r--composeApp/src/commonMain/kotlin/coffee/liz/abstractionengine/game/Game.kt77
1 files changed, 77 insertions, 0 deletions
diff --git a/composeApp/src/commonMain/kotlin/coffee/liz/abstractionengine/game/Game.kt b/composeApp/src/commonMain/kotlin/coffee/liz/abstractionengine/game/Game.kt
new file mode 100644
index 0000000..9490f83
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/coffee/liz/abstractionengine/game/Game.kt
@@ -0,0 +1,77 @@
+package coffee.liz.abstractionengine.game
+
+import androidx.compose.foundation.Canvas
+import androidx.compose.runtime.*
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import coffee.liz.ecs.World
+import kotlinx.coroutines.isActive
+
+/**
+ * Manages the game loop for an ECS world.
+ * Syncs with Compose's frame rate (like requestAnimationFrame) and provides
+ * the world to child content for custom rendering/UI.
+ *
+ * @param world The ECS world containing entities and systems
+ * @param content Composable content that can use the world for rendering
+ */
+@Composable
+fun Game(
+ world: World,
+ content: @Composable () -> Unit
+) {
+ // Trigger recomposition when we need to redraw
+ var frameCount by remember { mutableStateOf(0) }
+
+ // Game loop - syncs with Compose's frame rate like requestAnimationFrame
+ LaunchedEffect(world) {
+ var lastFrameTimeNanos = 0L
+
+ while (isActive) {
+ // Wait for next frame (like requestAnimationFrame)
+ withFrameNanos { frameTimeNanos ->
+ val deltaTime = if (lastFrameTimeNanos != 0L) {
+ (frameTimeNanos - lastFrameTimeNanos) / 1_000_000_000f
+ } else {
+ 0f
+ }
+ lastFrameTimeNanos = frameTimeNanos
+
+ // Update ECS world (runs all systems)
+ if (deltaTime > 0f) {
+ world.update(deltaTime)
+ }
+
+ // Trigger recomposition to redraw
+ frameCount++
+ }
+ }
+ }
+
+ // Render content
+ content()
+}
+
+/**
+ * A Canvas that renders sprites from an ECS world using a RenderSystem.
+ *
+ * @param world The ECS world containing entities to render
+ * @param renderSystem The system responsible for rendering sprites
+ * @param backgroundColor Background color for the canvas
+ * @param modifier Modifier for the Canvas
+ */
+@Composable
+fun GameCanvas(
+ world: World,
+ renderSystem: RenderSystem,
+ backgroundColor: Color = Color.Transparent,
+ modifier: Modifier = Modifier
+) {
+ Canvas(modifier = modifier) {
+ // Clear background
+ drawRect(backgroundColor)
+
+ // Render all sprites
+ renderSystem.render(world, this)
+ }
+}