|
| 1 | +@[has_globals] |
| 2 | +module main |
| 3 | + |
| 4 | +import gg |
| 5 | +import rand |
| 6 | + |
| 7 | +__global app = App{} |
| 8 | + |
| 9 | +struct Ball { |
| 10 | +mut: |
| 11 | + x f32 |
| 12 | + y f32 |
| 13 | + dx f32 |
| 14 | + dy f32 |
| 15 | + color gg.Color |
| 16 | +} |
| 17 | + |
| 18 | +struct App { |
| 19 | +mut: |
| 20 | + size gg.Size = gg.Size{1024, 768} |
| 21 | + balls []Ball |
| 22 | +} |
| 23 | + |
| 24 | +fn main() { |
| 25 | + init_app() |
| 26 | + gg.start( |
| 27 | + window_title: 'Bouncing balls' |
| 28 | + width: app.size.width |
| 29 | + height: app.size.height |
| 30 | + frame_fn: on_frame |
| 31 | + ) |
| 32 | +} |
| 33 | + |
| 34 | +fn on_frame(ctx &gg.Context) { |
| 35 | + app.size = gg.window_size() |
| 36 | + if ctx.frame % 20000 == 0 { |
| 37 | + init_app() |
| 38 | + } |
| 39 | + for mut ball in app.balls { |
| 40 | + move_ball(mut ball) |
| 41 | + } |
| 42 | + ctx.begin() |
| 43 | + for ball in app.balls { |
| 44 | + ctx.draw_circle_filled(ball.x, app.size.height - ball.y, 6, ball.color) |
| 45 | + } |
| 46 | + ctx.draw_text(10, 20, 'Frame: ${ctx.frame:06}', color: gg.Color{255, 255, 255, 255}, size: 20) |
| 47 | + ctx.end() |
| 48 | +} |
| 49 | + |
| 50 | +fn init_app() { |
| 51 | + app.balls.clear() |
| 52 | + for _ in 0 .. 2500 { |
| 53 | + app.balls << Ball{ |
| 54 | + x: rand.f32() * app.size.width |
| 55 | + y: 3 * app.size.height / 4 |
| 56 | + dx: 5 * rand.f32() |
| 57 | + dy: 5 * rand.f32() |
| 58 | + color: gg.Color{rand.u8(), rand.u8(), rand.u8(), 255} |
| 59 | + } |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +@[inline] |
| 64 | +fn move_ball(mut ball Ball) { |
| 65 | + ball.x += ball.dx |
| 66 | + ball.y += ball.dy |
| 67 | + ball.dy -= 9.81 * 0.01 |
| 68 | + if ball.x <= 0 || ball.x >= app.size.width - 1 { |
| 69 | + ball.dx = -ball.dx |
| 70 | + apply_friction(mut ball) |
| 71 | + } |
| 72 | + if ball.y <= 0 || ball.y >= app.size.height - 1 { |
| 73 | + ball.dy = -ball.dy |
| 74 | + apply_friction(mut ball) |
| 75 | + } |
| 76 | + // apply some clipping: |
| 77 | + ball.x = f32_max(-5, f32_min(f32(app.size.width) * 1.3, ball.x)) |
| 78 | + ball.y = f32_max(-5, f32_min(f32(app.size.height) * 1.3, ball.y)) |
| 79 | + ball.dx = f32_max(-50, f32_min(30, ball.dx)) |
| 80 | + ball.dy = f32_max(-50, f32_min(30, ball.dy)) |
| 81 | +} |
| 82 | + |
| 83 | +@[inline] |
| 84 | +fn apply_friction(mut ball Ball) { |
| 85 | + // apply some random friction on each bounce: |
| 86 | + ball.dy *= (1 - rand.f32() * 0.1) |
| 87 | + ball.dx *= (1 - rand.f32() * 0.01) |
| 88 | +} |
0 commit comments