1use ponko::*;
17use serde::{Deserialize, Serialize};
18
19#[derive(Serialize, Deserialize, Clone, Copy)]
21#[serde(default)]
22struct Walker {
23 speed: f32,
25 heading: f32,
27}
28
29impl Default for Walker {
30 fn default() -> Self {
31 Self {
32 speed: 60.0,
33 heading: 0.0,
34 }
35 }
36}
37
38const LEVEL: &str = "levels/level.json";
39
40fn walk(ctx: &mut Ctx) {
41 let dt = ctx.dt();
42 let bounds = ctx.window_size();
43 ctx.world.query::<(&mut Transform2D, &mut Walker)>().for_each(|(t, w)| {
44 let mut v = Vec2::from_angle(w.heading) * w.speed;
45 t.position += v * dt;
46 if !(0.0..=bounds.x).contains(&t.position.x) {
47 v.x = -v.x;
48 }
49 if !(0.0..=bounds.y).contains(&t.position.y) {
50 v.y = -v.y;
51 }
52 t.position = t.position.clamp(Vec2::ZERO, bounds);
53 w.heading = v.to_angle();
54 });
55}
56
57fn main() {
58 Game::new("Crabby Engine: editor", 1280, 720)
59 .inspector(true)
60 .sim_system(walk)
61 .run(|ctx| {
62 ctx.clear(Color::hex(0x24323F));
63 ctx.world.reflect::<Walker>();
64 if ctx.load_scene(LEVEL).is_ok() {
65 println!("loaded assets/{LEVEL}");
66 return;
67 }
68 let crab = ctx.load_texture("crab.png");
69 let mut rng = Rng::new(7);
70 for _ in 0..12 {
71 let at = vec2(rng.range(100.0, 1180.0), rng.range(100.0, 620.0));
72 let walker = Walker {
73 speed: rng.range(30.0, 90.0),
74 heading: rng.range(0.0, std::f32::consts::TAU),
75 };
76 ctx.world.spawn((Transform2D::at(at), Sprite::new(crab), walker));
77 }
78 });
79}