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