mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-26 21:27:38 +02:00
add segment kinds
This commit is contained in:
parent
12a42dfed4
commit
c42958ebf1
289
game/src/main.rs
289
game/src/main.rs
@ -6,9 +6,8 @@ use rand::Rng;
|
|||||||
|
|
||||||
use core::panic;
|
use core::panic;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{vec_deque, HashSet, VecDeque},
|
collections::{HashSet, VecDeque},
|
||||||
f64::consts::PI,
|
f64::consts::PI,
|
||||||
ops::Index,
|
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
thread,
|
thread,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
@ -19,18 +18,7 @@ use crate::{
|
|||||||
server::Server,
|
server::Server,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SegmentFactory;
|
|
||||||
|
|
||||||
trait SegmentKind {
|
|
||||||
fn obstacles(self) -> Vec<Obstacle>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SegmentFactory {
|
|
||||||
fn new() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Skateboard {
|
struct Skateboard {
|
||||||
start_pos: V3,
|
|
||||||
pos: V3,
|
pos: V3,
|
||||||
size: V3,
|
size: V3,
|
||||||
vel: V3,
|
vel: V3,
|
||||||
@ -40,13 +28,17 @@ struct Skateboard {
|
|||||||
pivot_deg_target: f64,
|
pivot_deg_target: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lose() {
|
||||||
|
panic!("You lost 🫵 😂");
|
||||||
|
}
|
||||||
|
|
||||||
impl Skateboard {
|
impl Skateboard {
|
||||||
fn update(&mut self, delta_time: Duration) {
|
fn update(&mut self, delta_time: Duration) {
|
||||||
self.vel.0 = self.pivot_deg * 2.0 * delta_time.as_secs_f64();
|
self.vel.0 = self.pivot_deg * 2.0 * delta_time.as_secs_f64();
|
||||||
self.pos += self.vel * delta_time.as_secs_f64();
|
self.pos += self.vel * delta_time.as_secs_f64();
|
||||||
self.nyoom_factor += 16.0 * delta_time.as_secs_f64();
|
self.nyoom_factor += 16.0 * delta_time.as_secs_f64();
|
||||||
if self.pos.0 < -0.5 || self.pos.0 > 0.5 {
|
if self.pos.0 < -0.5 || self.pos.0 > 0.5 {
|
||||||
panic!("LLLLL");
|
lose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,16 +158,7 @@ struct UpdateCx<'game> {
|
|||||||
skateboard: &'game mut Skateboard,
|
skateboard: &'game mut Skateboard,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Game {
|
struct GroundManager {
|
||||||
skateboard: Skateboard,
|
|
||||||
segments: Vec<Segment>,
|
|
||||||
camera_pos: V3,
|
|
||||||
keys_pressed: HashSet<Key>,
|
|
||||||
event_queue: Arc<Mutex<VecDeque<f64>>>,
|
|
||||||
ground: GroundMicroManager,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct GroundMicroManager {
|
|
||||||
ground: VecDeque<Ground>,
|
ground: VecDeque<Ground>,
|
||||||
start_position: V3,
|
start_position: V3,
|
||||||
grid_item_size: f64,
|
grid_item_size: f64,
|
||||||
@ -183,10 +166,16 @@ struct GroundMicroManager {
|
|||||||
grid_depth: i32,
|
grid_depth: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroundMicroManager {
|
impl GroundManager {
|
||||||
pub fn new(start_position: V3, grid_item_size: f64, grid_width: i32, grid_depth: i32) -> Self {
|
pub fn new(
|
||||||
|
start_position: V3,
|
||||||
|
grid_item_size: f64,
|
||||||
|
grid_width: i32,
|
||||||
|
grid_depth: i32,
|
||||||
|
render_distance: i32,
|
||||||
|
) -> Self {
|
||||||
let mut ground = VecDeque::new();
|
let mut ground = VecDeque::new();
|
||||||
for i in 0..3 {
|
for i in 0..render_distance {
|
||||||
ground.push_back(Ground {
|
ground.push_back(Ground {
|
||||||
grid_width,
|
grid_width,
|
||||||
grid_depth,
|
grid_depth,
|
||||||
@ -234,13 +223,140 @@ impl GroundMicroManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SegmentFactory {
|
||||||
|
segment_depth: f64,
|
||||||
|
segment_width: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SegmentFactory {
|
||||||
|
pub fn new(segment_depth: f64, segment_width: f64) -> Self {
|
||||||
|
Self {
|
||||||
|
segment_depth,
|
||||||
|
segment_width,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn random_obstacle_segment(&self, pos: V3) -> Segment {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let mut obstacles: Vec<Obstacle> = Vec::new();
|
||||||
|
for i in 1..5 {
|
||||||
|
obstacles.push(Obstacle {
|
||||||
|
pos: V3(
|
||||||
|
rng.gen_range((-self.segment_width / 2.0)..(self.segment_width / 2.0)) - 0.1,
|
||||||
|
0.0,
|
||||||
|
self.segment_depth / i as f64,
|
||||||
|
),
|
||||||
|
vel: V3(0.0, 0.0, 0.0),
|
||||||
|
size: V3(0.1, 0.1, 0.1),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Segment::new(pos, obstacles)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn slalom_obstacle_segment(&self, pos: V3) -> Segment {
|
||||||
|
let mut obstacles: Vec<Obstacle> = Vec::new();
|
||||||
|
for i in 0..3 {
|
||||||
|
let is_left = i % 2 == 0;
|
||||||
|
let width = 0.5;
|
||||||
|
let offset = if is_left { -0.5 } else { 0.5 - width };
|
||||||
|
obstacles.push(Obstacle {
|
||||||
|
pos: V3(offset as f64, 0.0, self.segment_depth / i as f64),
|
||||||
|
vel: V3(0.0, 0.0, 0.0),
|
||||||
|
size: V3(width, 0.1, 0.1),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Segment::new(pos, obstacles)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_random_segment(&self, pos: V3) -> Segment {
|
||||||
|
use SegmentKind::*;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let segment_kind = &[RandomObstacles, SlalomObstacles][rng.gen_range(0..2)];
|
||||||
|
|
||||||
|
match segment_kind {
|
||||||
|
SegmentKind::RandomObstacles => self.random_obstacle_segment(pos),
|
||||||
|
SegmentKind::MovingObstacles => todo!(),
|
||||||
|
SegmentKind::SlalomObstacles => self.slalom_obstacle_segment(pos),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SegmentManager {
|
||||||
|
segment_depth: f64,
|
||||||
|
segment_width: f64,
|
||||||
|
segment_factory: SegmentFactory,
|
||||||
|
segments: VecDeque<Segment>,
|
||||||
|
start_pos: V3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SegmentManager {
|
||||||
|
pub fn new(
|
||||||
|
start_pos: V3,
|
||||||
|
render_distance: i32,
|
||||||
|
segment_depth: f64,
|
||||||
|
segment_width: f64,
|
||||||
|
) -> Self {
|
||||||
|
let mut segments: VecDeque<Segment> = VecDeque::new();
|
||||||
|
let segment_factory = SegmentFactory {
|
||||||
|
segment_depth,
|
||||||
|
segment_width,
|
||||||
|
};
|
||||||
|
for i in 0..render_distance {
|
||||||
|
segments.push_back(segment_factory.new_random_segment(V3(
|
||||||
|
start_pos.0,
|
||||||
|
start_pos.1,
|
||||||
|
start_pos.2 + segment_depth * i as f64,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
segment_depth,
|
||||||
|
segment_width,
|
||||||
|
segment_factory,
|
||||||
|
segments,
|
||||||
|
start_pos,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shuffle(&mut self) {
|
||||||
|
let mut first = self.segments.pop_front().unwrap();
|
||||||
|
let last = self.segments.back().unwrap();
|
||||||
|
first.pos = last.pos + V3(0.0, 0.0, self.segment_depth as f64);
|
||||||
|
self.segments.push_back(first);
|
||||||
|
}
|
||||||
|
pub fn should_shuffle(&self, z: f64) -> bool {
|
||||||
|
let first = self.segments.front().unwrap();
|
||||||
|
first.pos.2 + self.segment_depth < z
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, cx: &mut UpdateCx, delta_time: Duration) {
|
||||||
|
for segment in &mut self.segments {
|
||||||
|
segment.update(cx, delta_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(&self, scene: &mut Scene) {
|
||||||
|
for segment in &self.segments {
|
||||||
|
segment.render(scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Game {
|
||||||
|
skateboard: Skateboard,
|
||||||
|
segment_manager: SegmentManager,
|
||||||
|
camera_pos: V3,
|
||||||
|
keys_pressed: HashSet<Key>,
|
||||||
|
event_queue: Arc<Mutex<VecDeque<f64>>>,
|
||||||
|
ground: GroundManager,
|
||||||
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let start_pos = V3(0.0, -0.15, 0.0);
|
|
||||||
Self {
|
Self {
|
||||||
skateboard: Skateboard {
|
skateboard: Skateboard {
|
||||||
start_pos,
|
pos: V3(0.0, -0.20, 0.0),
|
||||||
pos: start_pos,
|
|
||||||
size: V3(0.05, 0.02, 0.15),
|
size: V3(0.05, 0.02, 0.15),
|
||||||
vel: V3(0.0, 0.0, 0.2),
|
vel: V3(0.0, 0.0, 0.2),
|
||||||
rot: V3(0.0, PI * 0.5, 0.0),
|
rot: V3(0.0, PI * 0.5, 0.0),
|
||||||
@ -250,24 +366,11 @@ impl Game {
|
|||||||
},
|
},
|
||||||
event_queue: Arc::new(Mutex::new(VecDeque::new())),
|
event_queue: Arc::new(Mutex::new(VecDeque::new())),
|
||||||
camera_pos: V3(0.0, 0.0, 0.0),
|
camera_pos: V3(0.0, 0.0, 0.0),
|
||||||
segments: Vec::new(),
|
segment_manager: SegmentManager::new(V3(0.0, -0.24, -0.4), 3, 2.0, 1.0),
|
||||||
keys_pressed: HashSet::new(),
|
keys_pressed: HashSet::new(),
|
||||||
ground: GroundMicroManager::new(V3(0.0, -0.25, -0.4), 0.1, 10, 20),
|
ground: GroundManager::new(V3(0.0, -0.25, -0.4), 0.1, 10, 20, 3),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn(&mut self, segment: Segment) {
|
|
||||||
self.segments.push(segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn despawn(&mut self, id: i32) {
|
|
||||||
let index = self
|
|
||||||
.segments
|
|
||||||
.iter()
|
|
||||||
.position(|s| s.id == id)
|
|
||||||
.expect("doesn't exist");
|
|
||||||
self.segments.remove(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Renderer> engine::Game<R> for Game {
|
impl<R: Renderer> engine::Game<R> for Game {
|
||||||
@ -278,7 +381,7 @@ impl<R: Renderer> engine::Game<R> for Game {
|
|||||||
self.skateboard.pos.1 + 0.15,
|
self.skateboard.pos.1 + 0.15,
|
||||||
self.skateboard.pos.2 - 0.4,
|
self.skateboard.pos.2 - 0.4,
|
||||||
);
|
);
|
||||||
if self.ground.should_shuffle(self.skateboard.pos.2) {
|
if self.ground.should_shuffle(self.camera_pos.2) {
|
||||||
self.ground.shuffle();
|
self.ground.shuffle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,35 +411,14 @@ impl<R: Renderer> engine::Game<R> for Game {
|
|||||||
* delta_time.as_secs_f64();
|
* delta_time.as_secs_f64();
|
||||||
self.skateboard.pivot_deg = self.skateboard.pivot_deg.clamp(-12.5, 12.5);
|
self.skateboard.pivot_deg = self.skateboard.pivot_deg.clamp(-12.5, 12.5);
|
||||||
|
|
||||||
let ids = self
|
|
||||||
.segments
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, segment)| (i, segment.id))
|
|
||||||
.rev()
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
for (i, id) in ids {
|
|
||||||
let segment = &self.segments[i];
|
|
||||||
if segment.should_despawn {
|
|
||||||
self.despawn(segment.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ids = self
|
|
||||||
.segments
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, segment)| (i, segment.id))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let mut cx = UpdateCx {
|
let mut cx = UpdateCx {
|
||||||
skateboard: &mut self.skateboard,
|
skateboard: &mut self.skateboard,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, id) in ids {
|
self.segment_manager.update(&mut cx, delta_time);
|
||||||
let segment = &mut self.segments[i];
|
|
||||||
segment.update(&mut cx, delta_time);
|
if self.segment_manager.should_shuffle(self.camera_pos.2) {
|
||||||
|
self.segment_manager.shuffle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,9 +427,7 @@ impl<R: Renderer> engine::Game<R> for Game {
|
|||||||
self.ground.render(&mut scene);
|
self.ground.render(&mut scene);
|
||||||
|
|
||||||
self.skateboard.render(&mut scene);
|
self.skateboard.render(&mut scene);
|
||||||
for object in &self.segments {
|
self.segment_manager.render(&mut scene);
|
||||||
object.render(&mut scene);
|
|
||||||
}
|
|
||||||
scene.render(r, self.camera_pos);
|
scene.render(r, self.camera_pos);
|
||||||
let id = r.load_text(
|
let id = r.load_text(
|
||||||
&format!("{}", (self.skateboard.pos.2 * 100.0) as u32),
|
&format!("{}", (self.skateboard.pos.2 * 100.0) as u32),
|
||||||
@ -381,24 +461,26 @@ struct Ground {
|
|||||||
grid_depth: i32,
|
grid_depth: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SegmentKind {
|
||||||
|
RandomObstacles,
|
||||||
|
MovingObstacles,
|
||||||
|
SlalomObstacles,
|
||||||
|
}
|
||||||
|
|
||||||
struct Segment {
|
struct Segment {
|
||||||
id: i32,
|
pos: V3,
|
||||||
obstacles: Vec<Obstacle>,
|
obstacles: Vec<Obstacle>,
|
||||||
should_despawn: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Segment {
|
impl Segment {
|
||||||
fn new(id: i32, obstacles: Vec<Obstacle>) -> Self {
|
fn new(pos: V3, obstacles: Vec<Obstacle>) -> Self {
|
||||||
Self {
|
Self { pos, obstacles }
|
||||||
id,
|
|
||||||
obstacles,
|
|
||||||
should_despawn: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update<'game>(&mut self, cx: &mut UpdateCx<'game>, delta_time: Duration) {
|
fn update<'game>(&mut self, cx: &mut UpdateCx<'game>, delta_time: Duration) {
|
||||||
for obstacle in &mut self.obstacles {
|
for obstacle in &mut self.obstacles {
|
||||||
obstacle.pos += obstacle.vel * delta_time.as_secs_f64();
|
obstacle.pos += obstacle.vel * delta_time.as_secs_f64();
|
||||||
|
let actual_obstacle_pos = obstacle.pos + self.pos;
|
||||||
let (skateboard_pos, skateboard_pos_and_size) = (
|
let (skateboard_pos, skateboard_pos_and_size) = (
|
||||||
V2(
|
V2(
|
||||||
cx.skateboard.pos.0 - cx.skateboard.size.0 / 2.0,
|
cx.skateboard.pos.0 - cx.skateboard.size.0 / 2.0,
|
||||||
@ -409,12 +491,12 @@ impl Segment {
|
|||||||
cx.skateboard.pos.2 + cx.skateboard.size.2 / 2.0,
|
cx.skateboard.pos.2 + cx.skateboard.size.2 / 2.0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if skateboard_pos.0 < obstacle.pos.0 + obstacle.size.0
|
if skateboard_pos.0 < actual_obstacle_pos.0 + obstacle.size.0
|
||||||
&& skateboard_pos_and_size.0 > obstacle.pos.0
|
&& skateboard_pos_and_size.0 > actual_obstacle_pos.0
|
||||||
&& skateboard_pos.1 < obstacle.pos.2 + obstacle.size.2
|
&& skateboard_pos.1 < actual_obstacle_pos.2 + obstacle.size.2
|
||||||
&& skateboard_pos_and_size.1 > obstacle.pos.2
|
&& skateboard_pos_and_size.1 > actual_obstacle_pos.2
|
||||||
{
|
{
|
||||||
panic!("You lost 🫵 😂");
|
lose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,7 +504,7 @@ impl Segment {
|
|||||||
fn render(&self, scene: &mut Scene) {
|
fn render(&self, scene: &mut Scene) {
|
||||||
for obstacle in &self.obstacles {
|
for obstacle in &self.obstacles {
|
||||||
scene.draw_shape(
|
scene.draw_shape(
|
||||||
obstacle.pos,
|
self.pos + obstacle.pos,
|
||||||
&Shape::new_cube(obstacle.size),
|
&Shape::new_cube(obstacle.size),
|
||||||
Color::Red,
|
Color::Red,
|
||||||
Color::Black,
|
Color::Black,
|
||||||
@ -487,37 +569,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
let first_segment: Segment = Segment::new(
|
|
||||||
0,
|
|
||||||
vec![Obstacle {
|
|
||||||
pos: V3(0.0, -0.248, 1.0),
|
|
||||||
vel: V3(0.0, 0.0, 0.0),
|
|
||||||
size: V3(0.1, 0.1, 0.1),
|
|
||||||
}],
|
|
||||||
);
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
|
|
||||||
let mut segments: Vec<Segment> = Vec::new();
|
|
||||||
for i in 0..5 {
|
|
||||||
let obstacle = first_segment.obstacles[0];
|
|
||||||
segments.push(Segment::new(
|
|
||||||
first_segment.id + i,
|
|
||||||
vec![Obstacle {
|
|
||||||
pos: V3(
|
|
||||||
obstacle.pos.0 + rng.gen_range(-0.5..0.5),
|
|
||||||
obstacle.pos.1,
|
|
||||||
obstacle.pos.2 + obstacle.pos.2 * i as f64,
|
|
||||||
),
|
|
||||||
vel: obstacle.vel,
|
|
||||||
size: obstacle.size,
|
|
||||||
}],
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
for segment in segments {
|
|
||||||
game.spawn(segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
sdl_io.run(&mut game);
|
sdl_io.run(&mut game);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user