add new segment and fix randomness

This commit is contained in:
Mikkel Troels Kongsted 2026-04-24 13:45:16 +02:00
parent c601f09285
commit 6b31d1c51b
4 changed files with 112 additions and 151 deletions

139
game/Cargo.lock generated
View File

@ -4,95 +4,15 @@ version = 4
[[package]]
name = "bitflags"
version = "2.11.0"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
[[package]]
name = "libc"
version = "0.2.183"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "sdl3"
@ -108,12 +28,9 @@ dependencies = [
[[package]]
name = "sdl3-sys"
version = "0.6.1+SDL-3.4.2"
version = "0.6.3+SDL-3.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d73fc820b0b6b9bd0557de7b799ec9da1ca4f35fcd1cb42f7ceb85e640d1477"
dependencies = [
"pkg-config",
]
checksum = "c7adc59563535710602c8e7035297fd73d2506c0c61677f40aeb8917c0e86a01"
[[package]]
name = "sdl3-ttf-sys"
@ -128,49 +45,5 @@ dependencies = [
name = "skate-slope"
version = "0.1.0"
dependencies = [
"rand",
"sdl3",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "zerocopy"
version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@ -4,5 +4,4 @@ version = "0.1.0"
edition = "2021"
[dependencies]
sdl3 = { version = "0.18.0", features = ["ttf", "use-pkg-config"] }
rand = "0.8"
sdl3 = { version = "0.18.0", features = ["ttf"] }

View File

@ -1,10 +1,9 @@
#![allow(dead_code)]
mod engine;
mod random;
mod server;
use rand::Rng;
use core::panic;
use std::{
collections::{HashSet, VecDeque},
f64::consts::PI,
@ -237,12 +236,13 @@ impl SegmentFactory {
}
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,
random::next_in_range_f64(
(-self.segment_width / 2.0)..(self.segment_width / 2.0),
) - 0.1,
0.0,
self.segment_depth / i as f64,
),
@ -250,7 +250,25 @@ impl SegmentFactory {
size: V3(0.1, 0.1, 0.1),
})
}
Segment::new(pos, obstacles)
Segment::new(SegmentKind::RandomObstacles, pos, obstacles)
}
pub fn moving_obstacle_segment(&self, pos: V3) -> Segment {
let mut obstacles: Vec<Obstacle> = Vec::new();
for i in 1..4 {
obstacles.push(Obstacle {
pos: V3(
random::next_in_range_f64(
(-self.segment_width / 2.0)..(self.segment_width / 2.0),
) - 0.1,
0.0,
self.segment_depth / i as f64,
),
vel: V3(0.1, 0.0, 0.0),
size: V3(0.1, 0.1, 0.1),
})
}
Segment::new(SegmentKind::MovingObstacles, pos, obstacles)
}
pub fn slalom_obstacle_segment(&self, pos: V3) -> Segment {
@ -265,18 +283,20 @@ impl SegmentFactory {
size: V3(width, 0.1, 0.1),
})
}
Segment::new(pos, obstacles)
Segment::new(SegmentKind::SlalomObstacles, pos, obstacles)
}
pub fn new_random_segment(&self, pos: V3) -> Segment {
use SegmentKind::*;
let mut rng = rand::thread_rng();
let choice: usize = random::next() as usize;
let segment_kind = &[RandomObstacles, SlalomObstacles][rng.gen_range(0..2)];
let segment_kind = &[RandomObstacles, MovingObstacles, SlalomObstacles][choice % 3];
dbg!(segment_kind);
match segment_kind {
SegmentKind::RandomObstacles => self.random_obstacle_segment(pos),
SegmentKind::MovingObstacles => todo!(),
SegmentKind::MovingObstacles => self.moving_obstacle_segment(pos),
SegmentKind::SlalomObstacles => self.slalom_obstacle_segment(pos),
}
}
@ -320,10 +340,14 @@ impl SegmentManager {
}
pub fn shuffle(&mut self) {
let mut first = self.segments.pop_front().unwrap();
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);
self.segments
.push_back(self.segment_factory.new_random_segment(V3(
last.pos.0,
last.pos.1,
last.pos.2 + self.segment_depth,
)));
}
pub fn should_shuffle(&self, z: f64) -> bool {
let first = self.segments.front().unwrap();
@ -366,9 +390,9 @@ impl Game {
},
event_queue: Arc::new(Mutex::new(VecDeque::new())),
camera_pos: V3(0.0, 0.0, 0.0),
segment_manager: SegmentManager::new(V3(0.0, -0.24, -0.4), 3, 2.0, 1.0),
segment_manager: SegmentManager::new(V3(0.0, -0.24, 1.6), 4, 2.0, 1.0),
keys_pressed: HashSet::new(),
ground: GroundManager::new(V3(0.0, -0.25, -0.4), 0.1, 10, 20, 3),
ground: GroundManager::new(V3(0.0, -0.25, -0.4), 0.1, 10, 20, 4),
}
}
}
@ -461,6 +485,7 @@ struct Ground {
grid_depth: i32,
}
#[derive(Debug)]
enum SegmentKind {
RandomObstacles,
MovingObstacles,
@ -468,18 +493,36 @@ enum SegmentKind {
}
struct Segment {
segment_kind: SegmentKind,
pos: V3,
obstacles: Vec<Obstacle>,
}
impl Segment {
fn new(pos: V3, obstacles: Vec<Obstacle>) -> Self {
Self { pos, obstacles }
fn new(segment_kind: SegmentKind, pos: V3, obstacles: Vec<Obstacle>) -> Self {
Self {
segment_kind,
pos,
obstacles,
}
}
fn update<'game>(&mut self, cx: &mut UpdateCx<'game>, delta_time: Duration) {
for obstacle in &mut self.obstacles {
obstacle.pos += obstacle.vel * delta_time.as_secs_f64();
match self.segment_kind {
SegmentKind::RandomObstacles => {}
SegmentKind::MovingObstacles => {
if obstacle.pos.0 > 0.5 - obstacle.size.0 {
obstacle.vel.0 = -obstacle.vel.0;
obstacle.pos.0 = 0.5 - obstacle.size.0;
} else if obstacle.pos.0 < (-0.5) {
obstacle.vel.0 = -obstacle.vel.0;
obstacle.pos.0 = -0.5;
}
}
SegmentKind::SlalomObstacles => {}
}
let actual_obstacle_pos = obstacle.pos + self.pos;
let (skateboard_pos, skateboard_pos_and_size) = (
V2(

46
game/src/random.rs Normal file
View File

@ -0,0 +1,46 @@
use std::{cell::RefCell, fs::File, io::Read};
struct Random {
seed: u64,
multiplier: u64,
modulus: u64,
increment: u64,
}
thread_local! {
static RNG: RefCell<Random> = RefCell::new(Random::new());
}
pub fn next() -> u64 {
RNG.with_borrow_mut(|rng| rng.next())
}
pub fn next_in_range_f64(range: std::ops::Range<f64>) -> f64 {
let value = next() as f64;
let percentage = value / RNG.with_borrow(|x| x.modulus as f64);
let span = range.end - range.start;
range.start + percentage * span
}
impl Random {
pub fn new() -> Self {
let mut file = File::open("/dev/urandom").unwrap();
let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0];
file.read_exact(&mut bytes).unwrap();
let modulus = 2u64.pow(31);
let multiplier = 1103515245;
let increment = 12345;
let seed = u64::from_ne_bytes(bytes) % modulus;
Self {
seed,
modulus,
multiplier,
increment,
}
}
pub fn next(&mut self) -> u64 {
self.seed = (self.multiplier * self.seed + self.increment) % self.modulus;
self.seed
}
}