|
|
|
@@ -42,7 +42,7 @@ Ball :: struct {
|
|
|
|
|
# A frame's worth of player intent, as a tagged union. Each arm carries exactly
|
|
|
|
|
# the data that action needs (or `void` when it needs none).
|
|
|
|
|
Command :: union(enum) {
|
|
|
|
|
spawn Vector2 # spawn a shape at this point
|
|
|
|
|
spawn rl.Vector2 # spawn a shape at this point
|
|
|
|
|
push struct { dx f32, dy f32 } # blow every shape this way
|
|
|
|
|
clear void
|
|
|
|
|
idle void
|
|
|
|
@@ -55,11 +55,11 @@ SpawnError :: union(enum) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# value-match used as an expression source: each arm yields a Color.
|
|
|
|
|
color_for func(k Kind) Color {
|
|
|
|
|
color_for func(k Kind) rl.Color {
|
|
|
|
|
col :: match k {
|
|
|
|
|
.circle: Color{ r = 235, g = 90, b = 90, a = 255 }
|
|
|
|
|
.square: Color{ r = 90, g = 205, b = 130, a = 255 }
|
|
|
|
|
.triangle: Color{ r = 105, g = 160, b = 245, a = 255 }
|
|
|
|
|
.circle: rl.Color{ r = 235, g = 90, b = 90, a = 255 }
|
|
|
|
|
.square: rl.Color{ r = 90, g = 205, b = 130, a = 255 }
|
|
|
|
|
.triangle: rl.Color{ r = 105, g = 160, b = 245, a = 255 }
|
|
|
|
|
}
|
|
|
|
|
return col
|
|
|
|
|
}
|
|
|
|
@@ -76,19 +76,19 @@ next_kind func(k Kind) Kind {
|
|
|
|
|
# Read this frame's input into a single Command (contextual union construction:
|
|
|
|
|
# `.clear`, `.spawn{...}`, `.push{...}` are built against the return type).
|
|
|
|
|
read_command func() Command {
|
|
|
|
|
if rl.IsMouseButtonPressed(MOUSE_BUTTON_LEFT) return .spawn{ GetMousePosition() }
|
|
|
|
|
if rl.IsKeyPressed(KEY_SPACE) return .clear
|
|
|
|
|
if rl.IsMouseButtonPressed(rl.MOUSE_BUTTON_LEFT) return .spawn{ rl.GetMousePosition() }
|
|
|
|
|
if rl.IsKeyPressed(rl.KEY_SPACE) return .clear
|
|
|
|
|
|
|
|
|
|
fx f32 = 0.0
|
|
|
|
|
fy f32 = 0.0
|
|
|
|
|
if rl.IsKeyDown(KEY_A) fx -= FORCE
|
|
|
|
|
if rl.IsKeyDown(KEY_D) fx += FORCE
|
|
|
|
|
if rl.IsKeyDown(KEY_W) fy -= FORCE
|
|
|
|
|
if rl.IsKeyDown(KEY_S) fy += FORCE
|
|
|
|
|
if rl.IsKeyDown(KEY_LEFT) fx -= FORCE
|
|
|
|
|
if rl.IsKeyDown(KEY_RIGHT) fx += FORCE
|
|
|
|
|
if rl.IsKeyDown(KEY_UP) fy -= FORCE
|
|
|
|
|
if rl.IsKeyDown(KEY_DOWN) fy += FORCE
|
|
|
|
|
if rl.IsKeyDown(rl.KEY_A) fx -= FORCE
|
|
|
|
|
if rl.IsKeyDown(rl.KEY_D) fx += FORCE
|
|
|
|
|
if rl.IsKeyDown(rl.KEY_W) fy -= FORCE
|
|
|
|
|
if rl.IsKeyDown(rl.KEY_S) fy += FORCE
|
|
|
|
|
if rl.IsKeyDown(rl.KEY_LEFT) fx -= FORCE
|
|
|
|
|
if rl.IsKeyDown(rl.KEY_RIGHT) fx += FORCE
|
|
|
|
|
if rl.IsKeyDown(rl.KEY_UP) fy -= FORCE
|
|
|
|
|
if rl.IsKeyDown(rl.KEY_DOWN) fy += FORCE
|
|
|
|
|
|
|
|
|
|
moved :: fx != 0.0 or fy != 0.0
|
|
|
|
|
if (moved) return .push{ dx = fx, dy = fy }
|
|
|
|
@@ -130,7 +130,7 @@ step func(b @mut Ball) void {
|
|
|
|
|
|
|
|
|
|
draw_ball func(b @Ball, highlight bool) void {
|
|
|
|
|
col :: color_for(b.kind)
|
|
|
|
|
center Vector2 = Vector2{ x = b.x, y = b.y }
|
|
|
|
|
center rl.Vector2 = rl.Vector2{ x = b.x, y = b.y }
|
|
|
|
|
match b.kind {
|
|
|
|
|
.circle: rl.DrawCircleV(center, b.radius, col)
|
|
|
|
|
.square: rl.DrawPoly(center, 4, b.radius, 45.0, col)
|
|
|
|
@@ -143,7 +143,7 @@ draw_ball func(b @Ball, highlight bool) void {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main func() i32 {
|
|
|
|
|
rl.SetConfigFlags(FLAG_MSAA_4X_HINT)
|
|
|
|
|
rl.SetConfigFlags(rl.FLAG_MSAA_4X_HINT)
|
|
|
|
|
rl.InitWindow(W, H, "brolang — bouncing shapes")
|
|
|
|
|
defer rl.CloseWindow() # runs on every exit path out of main
|
|
|
|
|
rl.SetTargetFPS(60)
|
|
|
|
@@ -210,9 +210,9 @@ main func() i32 {
|
|
|
|
|
|
|
|
|
|
# --- which shape is under the cursor? (optional via a value-loop) ---
|
|
|
|
|
mouse :: rl.GetMousePosition()
|
|
|
|
|
sel :: for 0..(count) |i| blk: {
|
|
|
|
|
c Vector2 = Vector2{ x = balls[i].x, y = balls[i].y }
|
|
|
|
|
if rl.CheckCollisionPointCircle(mouse, c, balls[i].radius) yield :blk i
|
|
|
|
|
sel :: for 0..(count) |i| hover: {
|
|
|
|
|
c rl.Vector2 = rl.Vector2{ x = balls[i].x, y = balls[i].y }
|
|
|
|
|
if rl.CheckCollisionPointCircle(mouse, c, balls[i].radius) yield :hover i
|
|
|
|
|
yield none
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|