1use ponko::*;
14
15struct Crab {
16 pos: Vec2,
17 vel: Vec2,
18 color: Color,
19}
20
21struct Rng(u64);
23impl Rng {
24 fn next_f32(&mut self) -> f32 {
25 self.0 ^= self.0 << 13;
26 self.0 ^= self.0 >> 7;
27 self.0 ^= self.0 << 17;
28 (self.0 >> 40) as f32 / (1u64 << 24) as f32
29 }
30}
31
32fn env_number(name: &str, default: f64) -> f64 {
33 std::env::var(name).ok().and_then(|v| v.parse().ok()).unwrap_or(default)
34}
35
36fn main() {
37 let start_count = env_number("CRABS", 10_000.0) as usize;
38 let quit_after = env_number("SECONDS", 0.0);
39
40 Game::new("Crabby Engine: bunnymark", 1280, 720).vsync(false).run(move |ctx| {
41 let crab = ctx.load_texture("crab.png");
42 let mut rng = Rng(0x9E37_79B9_7F4A_7C15);
43 let mut crabs: Vec<Crab> = Vec::new();
44
45 let mut spawn = move |crabs: &mut Vec<Crab>, n: usize, at: Vec2| {
46 crabs.reserve(n);
47 for _ in 0..n {
48 crabs.push(Crab {
49 pos: at,
50 vel: vec2(rng.next_f32() * 400.0 - 200.0, rng.next_f32() * 400.0 - 300.0),
51 color: Color::rgb(0.6 + rng.next_f32() * 0.4, 0.6 + rng.next_f32() * 0.4, 0.6 + rng.next_f32() * 0.4),
52 });
53 }
54 };
55 spawn(&mut crabs, start_count, vec2(20.0, 20.0));
56
57 let mut report_at = 1.0;
58 let mut frames_since = 0u32;
59 let mut worst_ms = 0.0f32;
60 let mut frame_start = Instant::now();
61 let mut update_ms_sum = 0.0f64;
62
63 move |ctx: &mut Ctx| {
64 let now = Instant::now();
65 let frame_ms = now.duration_since(frame_start).as_secs_f32() * 1000.0;
66 frame_start = now;
67 worst_ms = worst_ms.max(frame_ms);
68 frames_since += 1;
69
70 if ctx.mouse_down(MouseButton::Left) {
71 spawn(&mut crabs, 1000, ctx.mouse_pos());
72 }
73
74 let update_start = Instant::now();
75 let dt = ctx.dt();
76 let bounds = ctx.window_size();
77 let gravity = 600.0;
78 for c in &mut crabs {
79 c.vel.y += gravity * dt;
80 c.pos += c.vel * dt;
81 if c.pos.x < 0.0 { c.pos.x = 0.0; c.vel.x = c.vel.x.abs(); }
82 if c.pos.x > bounds.x { c.pos.x = bounds.x; c.vel.x = -c.vel.x.abs(); }
83 if c.pos.y > bounds.y { c.pos.y = bounds.y; c.vel.y = -c.vel.y.abs() * 0.85; }
84 if c.pos.y < 0.0 { c.pos.y = 0.0; c.vel.y = 0.0; }
85 ctx.draw_ex(&crab, c.pos, DrawParams { color: c.color, ..Default::default() });
86 }
87 update_ms_sum += update_start.elapsed().as_secs_f64() * 1000.0;
88
89 if ctx.time() >= report_at {
90 println!(
91 "crabs: {:>8} fps: {:>6.1} avg frame: {:>6.2} ms worst: {:>6.2} ms update+draw calls: {:>6.2} ms",
92 crabs.len(),
93 frames_since as f64 / 1.0,
94 1000.0 / frames_since as f64,
95 worst_ms,
96 update_ms_sum / frames_since as f64,
97 );
98 report_at += 1.0;
99 frames_since = 0;
100 worst_ms = 0.0;
101 update_ms_sum = 0.0;
102 }
103
104 if ctx.key_pressed(Key::Escape) || (quit_after > 0.0 && ctx.time() >= quit_after) {
105 ctx.quit();
106 }
107 }
108 });
109}