diff --git a/README.md b/README.md new file mode 100644 index 0000000..09519c8 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +my silly little ecs engine for odin and raylib :3 diff --git a/examples/bouncing_balls.odin b/examples/bouncing_balls.odin new file mode 100644 index 0000000..7b9f20f --- /dev/null +++ b/examples/bouncing_balls.odin @@ -0,0 +1,86 @@ +package main + +import "core:fmt" +import "core:math/rand" +import "core:strconv" +import "core:strings" +import ecs "shoal/src" +import rl "vendor:raylib" + +app: ecs.App + +ball_count: int = 1000 +BallComponent :: struct { + radius: f32, + speed: f32, +} +Ball: ecs.Storage(BallComponent) + +main :: proc() { + ecs.add_plugin(&app, ecs.DefaultPlugin) + ecs.add_system(&app, ecs.STARTUP, setup_window) + ecs.add_system(&app, ecs.STARTUP, spawn_balls) + ecs.add_system(&app, ecs.UPDATE, update_balls) + ecs.add_system(&app, ecs.DRAW, draw_balls) + ecs.add_system(&app, ecs.DRAW, show_framerate) + ecs.run(&app) +} + +setup_window :: proc() { + _, window := ecs.single(&ecs.Window) + window.background = rl.BLACK +} + +spawn_balls :: proc() { + for i in 0 ..< ball_count { + ball := ecs.spawn_entity(&app) + ecs.add_component( + ball, + &Ball, + BallComponent{radius = 10, speed = rand.float32_range(4, 6)}, + ) + ecs.add_component( + ball, + &ecs.Transform, + ecs.TransformComponent { + translation = {400, 300}, + rotation = rand.float32_range(0, 360), + }, + ) + } +} + +update_balls :: proc() { + _, window := ecs.single(&ecs.Window) + + for entity, ball in ecs.slice(&Ball) { + transform := ecs.get_component(entity, &ecs.Transform) + pos := transform.translation + + if pos.x <= 0 || pos.x >= f32(window.width) || pos.y <= 0 || pos.y >= f32(window.height) { + transform.rotation -= 180 + } + dir := rl.Vector2Rotate(rl.Vector2{0, ball.speed}, transform.rotation) + + transform.translation += dir + fmt.println(transform.rotation) + } +} + +draw_balls :: proc() { + for entity, ball in ecs.slice(&Ball) { + transform := ecs.get_component(entity, &ecs.Transform) + rl.DrawCircle( + i32(transform.translation.x), + i32(transform.translation.y), + ball.radius, + rl.PURPLE, + ) + } +} + +show_framerate :: proc() { + buf: [19]byte + framerate := strconv.write_int(buf[:], i64(1 / rl.GetFrameTime()), 10) + rl.DrawText(strings.clone_to_cstring(framerate), 0, 0, 24, rl.WHITE) +} diff --git a/plugins.odin b/plugins.odin deleted file mode 100644 index a447a54..0000000 --- a/plugins.odin +++ /dev/null @@ -1,4 +0,0 @@ -#+private -package shoal - -plugins: [dynamic]proc() diff --git a/query.odin b/query.odin deleted file mode 100644 index a59ccf6..0000000 --- a/query.odin +++ /dev/null @@ -1 +0,0 @@ -package shoal diff --git a/componenets.odin b/src/componenets.odin similarity index 79% rename from componenets.odin rename to src/componenets.odin index b3599dc..85e285e 100644 --- a/componenets.odin +++ b/src/componenets.odin @@ -3,9 +3,10 @@ package shoal import rl "vendor:raylib" WindowComponent :: struct { - width: i32, - height: i32, - title: string, + width: i32, + height: i32, + title: string, + background: rl.Color, } Window: Storage(WindowComponent) diff --git a/ecs.odin b/src/ecs.odin similarity index 96% rename from ecs.odin rename to src/ecs.odin index 64c6f24..f8eddd7 100644 --- a/ecs.odin +++ b/src/ecs.odin @@ -42,7 +42,7 @@ run :: proc(app: ^App, entity_limit: int = 1000) { rl.SetTargetFPS(60) for !rl.WindowShouldClose() { - rl.ClearBackground(rl.WHITE) + rl.ClearBackground(window.background) for i in app.update_systems {i()} rl.BeginDrawing() for i in app.draw_systems {i()} diff --git a/entities.odin b/src/entities.odin similarity index 100% rename from entities.odin rename to src/entities.odin diff --git a/systems.odin b/src/systems.odin similarity index 100% rename from systems.odin rename to src/systems.odin