render ground infinitely and move skateboard

This commit is contained in:
Mikkel Troels Kongsted 2026-03-31 16:18:22 +02:00
parent 398ce3675a
commit 474a32ae4f
3 changed files with 137 additions and 34 deletions

View File

@ -28,8 +28,15 @@ pub enum Color {
Black, Black,
} }
#[derive(PartialEq, Eq, Hash)]
pub enum Key {
Left,
Right,
}
pub enum Event { pub enum Event {
Exit, KeyUp { key: Key },
KeyDown { key: Key },
} }
pub trait Game<R: Renderer> { pub trait Game<R: Renderer> {

View File

@ -64,6 +64,39 @@ impl SdlIo {
keycode: Some(Keycode::Escape), keycode: Some(Keycode::Escape),
.. ..
} => break 'running, } => break 'running,
Event::KeyDown { keycode, .. } => match keycode {
Some(key) => match key {
Keycode::Left => {
game.event(game::Event::KeyDown {
key: game::Key::Left,
});
}
Keycode::Right => {
game.event(game::Event::KeyDown {
key: game::Key::Right,
});
}
_ => {}
},
None => {}
},
Event::KeyUp { keycode, .. } => match keycode {
Some(key) => match key {
Keycode::Left => {
game.event(game::Event::KeyUp {
key: game::Key::Left,
});
}
Keycode::Right => {
game.event(game::Event::KeyUp {
key: game::Key::Right,
});
}
_ => {}
},
None => {}
},
_ => {} _ => {}
} }
} }

View File

@ -1,13 +1,14 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::{ use std::{
collections::HashSet,
f64::consts::PI, f64::consts::PI,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::Duration, time::Duration,
}; };
use crate::{ use crate::{
engine::{Color, Renderer, Scene, Shape, V3}, engine::{Color, Key, Renderer, Scene, Shape, V3},
event_queue::EventQueue, event_queue::EventQueue,
vermiparous::Server, vermiparous::Server,
}; };
@ -20,6 +21,7 @@ struct Game {
objects: Vec<Object>, objects: Vec<Object>,
next_object_id: u32, next_object_id: u32,
event_queue: Arc<Mutex<EventQueue>>, event_queue: Arc<Mutex<EventQueue>>,
keys_pressed: HashSet<Key>,
} }
impl Game { impl Game {
@ -28,6 +30,7 @@ impl Game {
objects: Vec::new(), objects: Vec::new(),
next_object_id: 0, next_object_id: 0,
event_queue, event_queue,
keys_pressed: HashSet::new(),
} }
} }
@ -53,6 +56,18 @@ impl Game {
impl<R: Renderer> engine::Game<R> for Game { impl<R: Renderer> engine::Game<R> for Game {
fn update(&mut self, delta_time: Duration) { fn update(&mut self, delta_time: Duration) {
for object in &mut self.objects { for object in &mut self.objects {
if self.keys_pressed.contains(&Key::Left) {
match &mut object.kind {
ObjectKind::SkateBoard { vel, .. } => vel.0 -= 0.01,
_ => {}
}
}
if self.keys_pressed.contains(&Key::Right) {
match &mut object.kind {
ObjectKind::SkateBoard { vel, .. } => vel.0 += 0.01,
_ => {}
}
}
object.update(delta_time); object.update(delta_time);
} }
} }
@ -65,7 +80,12 @@ impl<R: Renderer> engine::Game<R> for Game {
scene.render(r, V3(0.0, 0.0, -1.0)); scene.render(r, V3(0.0, 0.0, -1.0));
} }
fn event(&mut self, event: engine::Event) {} fn event(&mut self, event: engine::Event) {
match event {
engine::Event::KeyDown { key } => self.keys_pressed.insert(key),
engine::Event::KeyUp { key } => self.keys_pressed.remove(&key),
};
}
} }
struct Object { struct Object {
@ -74,22 +94,37 @@ struct Object {
} }
enum ObjectKind { enum ObjectKind {
SkateBoard { pos: V3, vel: V3, rot: V3 }, SkateBoard {
Obstacle { pos: V3, vel: V3 }, pos: V3,
Ground { pos: V3, vel_z: f64 }, vel: V3,
rot: V3,
},
Obstacle {
pos: V3,
vel: V3,
},
Ground {
original_pos: V3,
pos: V3,
vel: V3,
rot: V3,
grid_item_size: f64,
grid_width: i32,
grid_depth: i32,
},
} }
struct MultiShapeShape { struct ShapeGroupShape {
shape: Shape, shape: Shape,
offset: V3, offset: V3,
} }
struct MultiShape { struct ShapeGroup {
shapes: Vec<MultiShapeShape>, shapes: Vec<ShapeGroupShape>,
} }
impl MultiShape { impl ShapeGroup {
pub fn new(shapes: Vec<MultiShapeShape>) -> Self { pub fn new(shapes: Vec<ShapeGroupShape>) -> Self {
Self { shapes } Self { shapes }
} }
pub fn rotate(mut self, rot: V3) -> Self { pub fn rotate(mut self, rot: V3) -> Self {
@ -125,18 +160,27 @@ impl Object {
match &mut self.kind { match &mut self.kind {
ObjectKind::SkateBoard { pos, vel, rot } => { ObjectKind::SkateBoard { pos, vel, rot } => {
*pos += *vel * delta_time.as_secs_f64(); *pos += *vel * delta_time.as_secs_f64();
if pos.0 >= 2.1 {
pos.0 = -2.0;
}
// rot.0 += delta_time.as_secs_f64() * PI * 1.0; // rot.0 += delta_time.as_secs_f64() * PI * 1.0;
rot.1 += delta_time.as_secs_f64() * PI * 1.0; // rot.1 += delta_time.as_secs_f64() * PI * 1.0;
// rot.2 += delta_time.as_secs_f64() * PI * 2.0; // rot.2 += delta_time.as_secs_f64() * PI * 2.0;
} }
ObjectKind::Obstacle { pos, vel } => { ObjectKind::Obstacle { pos, vel } => {
*pos += *vel * delta_time.as_secs_f64(); *pos += *vel * delta_time.as_secs_f64();
} }
ObjectKind::Ground { pos, vel_z } => { ObjectKind::Ground {
pos.2 += *vel_z * delta_time.as_secs_f64(); pos,
vel,
grid_depth,
grid_item_size,
original_pos,
..
} => {
*pos += *vel * delta_time.as_secs_f64();
*vel += V3(vel.0, vel.1, vel.0 - 0.01 * delta_time.as_secs_f64());
if pos.2 <= original_pos.2 - *grid_depth as f64 * *grid_item_size as f64 {
pos.2 += *grid_depth as f64 * *grid_item_size as f64
}
} }
} }
} }
@ -144,16 +188,16 @@ impl Object {
fn render(&self, scene: &mut Scene) { fn render(&self, scene: &mut Scene) {
match self.kind { match self.kind {
ObjectKind::SkateBoard { pos, rot, .. } => { ObjectKind::SkateBoard { pos, rot, .. } => {
let board = MultiShape::new(vec![ let board = ShapeGroup::new(vec![
MultiShapeShape { ShapeGroupShape {
shape: Shape::new_cube(V3(0.2, 0.01, 0.05)), shape: Shape::new_cube(V3(0.2, 0.01, 0.05)),
offset: V3(0.0, 0.0, 0.0), offset: V3(0.0, 0.0, 0.0),
}, },
MultiShapeShape { ShapeGroupShape {
shape: Shape::new_cube(V3(0.02, 0.02, 0.05)), shape: Shape::new_cube(V3(0.02, 0.02, 0.05)),
offset: V3(0.04, -0.02, 0.0), offset: V3(0.04, -0.02, 0.0),
}, },
MultiShapeShape { ShapeGroupShape {
shape: Shape::new_cube(V3(0.02, 0.02, 0.05)), shape: Shape::new_cube(V3(0.02, 0.02, 0.05)),
offset: V3(0.14, -0.02, 0.0), offset: V3(0.14, -0.02, 0.0),
}, },
@ -170,17 +214,31 @@ impl Object {
Color::Black, Color::Black,
); );
} }
ObjectKind::Ground { pos, .. } => { ObjectKind::Ground {
for z in 0..10 { pos,
for x in -10..10 { grid_depth,
scene.draw_shape( grid_item_size,
V3(x as f64 * 0.1 + pos.0, pos.1, z as f64 * 0.1 + pos.2), grid_width,
&Shape::new_plane(V3(0.1, 0.0, 0.1)), ..
Color::Cyan, } => {
Color::Black, for grid in 0..5 {
); let mut shapes = Vec::new();
for z in 0..grid_depth {
for x in -grid_width / 2..grid_width / 2 {
shapes.push(ShapeGroupShape {
shape: Shape::new_plane(V3(grid_item_size, 0.0, grid_item_size)),
offset: V3(
x as f64 * grid_item_size,
0.0,
z as f64 * grid_item_size
+ grid as f64 * grid_depth as f64 * grid_item_size,
),
});
} }
} }
let ground = ShapeGroup::new(shapes);
ground.draw(pos, scene, Color::Cyan, Color::Black);
}
} }
} }
} }
@ -196,13 +254,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}); });
let mut objects: Vec<ObjectKind> = Vec::new(); let mut objects: Vec<ObjectKind> = Vec::new();
objects.push(ObjectKind::SkateBoard { objects.push(ObjectKind::SkateBoard {
pos: V3(0.0, -0.1, 0.0), pos: V3(0.0, -0.1, -0.7),
vel: V3(0.0, 0.0, 0.0), vel: V3(0.0, 0.0, 0.0),
rot: V3(0.0, 0.0, 0.0), rot: V3(0.0, PI * 0.5, 0.0),
}); });
objects.push(ObjectKind::Ground { objects.push(ObjectKind::Ground {
pos: V3(0.0, -0.3, -0.5), original_pos: V3(0.0, -0.25, -0.6),
vel_z: -0.1, pos: V3(0.0, -0.25, -0.6),
vel: V3(0.0, 0.0, -0.1),
rot: V3(0.0, 0.0, 0.0),
grid_item_size: 0.1,
grid_width: 10,
grid_depth: 10,
}); });
objects.push(ObjectKind::Obstacle { objects.push(ObjectKind::Obstacle {
pos: V3(0.5, -0.2, 0.0), pos: V3(0.5, -0.2, 0.0),