From fe88997cd183677e24a75ca243fa7647813c5071 Mon Sep 17 00:00:00 2001 From: zefad Date: Fri, 18 Sep 2026 17:40:19 +0200 Subject: [PATCH] chunk logic --- src/world.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/world.rs diff --git a/src/world.rs b/src/world.rs new file mode 100644 index 0000000..36642d7 --- /dev/null +++ b/src/world.rs @@ -0,0 +1,67 @@ +use bevy::prelude::*; + +use crate::{camera::MainCamera, player::Player}; + +pub const CHUNK_HEIGHT: f32 = 700.0; // Height of a cunk +const MARGIN_BELLOW: f32 = 400.0; // Height bellow the camera view it'll be gen +const MARGIN_ABOVE: f32 = 400.0; // Height above the camera view it'll be gen + +#[derive(Component)] +pub struct Chunk { + pub id: i64, +} + +#[derive(Resource)] +pub struct RunSeed(pub u64); + +fn stream_world( + player: Single<&Transform, With>, + entities: Query<(Entity, &Chunk)>, + mut commands: Commands, + camera: Single<&Camera, With>, + run_seed: Res, +) { + let (min_id, max_id) = visible_chunk_range( + player.translation.y, + camera + .logical_viewport_size() + .unwrap_or(Vec2::new(1920.0, 1080.0)) + .y, + ); + + let existing_ids: Vec = entities.iter().map(|(_, chunk)| chunk.id).collect(); + + for (entity, chunk) in entities { + // Out of bounds implies despawn + if chunk.id < min_id || chunk.id > max_id { + commands.entity(entity).despawn(); + } + } + + for id in min_id..=max_id { + if !existing_ids.contains(&id) { + spawn_chunk(&mut commands, id, run_seed.0); + } + } +} + +// Bounds of chunk's ids to be generated +fn visible_chunk_range(player_y: f32, camera_y: f32) -> (i64, i64) { + ( + ((player_y - camera_y / 2.0 - MARGIN_BELLOW) / CHUNK_HEIGHT).floor() as i64, + ((player_y + camera_y / 2.0 + MARGIN_ABOVE) / CHUNK_HEIGHT).floor() as i64, + ) +} + +fn spawn_chunk(commands: &mut Commands, id: i64, run_seed: u64) { + crate::background::spawn_background_chunk(commands, id); + // TODO: obstacles +} +pub struct WorldPlugin; + +impl Plugin for WorldPlugin { + fn build(&self, app: &mut App) { + app.insert_resource(RunSeed(rand::random::())) + .add_systems(Update, stream_world); + } +}