chunk logic
This commit is contained in:
@@ -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<Player>>,
|
||||
entities: Query<(Entity, &Chunk)>,
|
||||
mut commands: Commands,
|
||||
camera: Single<&Camera, With<MainCamera>>,
|
||||
run_seed: Res<RunSeed>,
|
||||
) {
|
||||
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<i64> = 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::<u64>()))
|
||||
.add_systems(Update, stream_world);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user