Chunking 3

This commit is contained in:
StephenAdamson
2025-01-15 19:50:18 +00:00
parent 7f1ec77ab0
commit d2e9bb0cf3
6 changed files with 88 additions and 288 deletions
-173
View File
@@ -1,177 +1,4 @@
use crate::constants::*;
use crate::item::ItemBundle;
use crate::tiles::FloorTilePrefab;
use crate::{citizen::Citizen, tiles::FixtureTilePrefab};
use bevy::prelude::*;
use noise::{NoiseFn, Perlin};
use rand::prelude::*;
#[derive(Resource)]
pub struct ZIndex(pub f32);
pub fn setup_level(mut commands: Commands, asset_server: Res<AssetServer>) {
println!("setup_level");
setup_tilemap(&mut commands, &asset_server);
for x in -10..10 {
for y in -10..10 {
if random::<f32>() < 0.1 {
commands.spawn(Citizen::new(
&asset_server,
Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, 0.9),
));
}
}
}
}
fn setup_tilemap(commands: &mut Commands, asset_server: &Res<AssetServer>) {
let noise = Perlin::new(0);
let mut floor_positions = Vec::new();
// First pass: Generate and store floor tiles
for y in -50..50 {
for x in -50..50 {
let noise_value_a = noise.get([x as f64 * 0.01, y as f64 * 0.01]) * 1.25;
let noise_value_b = noise.get([x as f64 * 0.05, y as f64 * 0.05]) * 0.25;
let combined_noise_value = noise_value_a + noise_value_b;
let noise_position = Vec3::new(
(x as f32 * TILE_SIZE).round(),
(y as f32 * TILE_SIZE).round(),
(combined_noise_value * 4.).round() as f32 * TILE_SIZE,
);
for z in -150..50 {
let position = Vec3::new(
(x as f32 * TILE_SIZE).round(),
(y as f32 * TILE_SIZE).round(),
(z as f32 * TILE_SIZE).round(),
);
let items: Vec<ItemBundle> = vec![];
let mut floor_type = None;
if noise_position.z > position.z {
if z < -15 {
let noise_value =
noise.get([x as f64 * 0.05, y as f64 * 0.05, z as f64 * 0.05]);
if noise_value < -0.5 {
commands
.spawn(FloorTilePrefab::air(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("air");
} else if noise_value < 0.8 {
commands
.spawn(FloorTilePrefab::rock(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("rock");
} else {
commands
.spawn(FloorTilePrefab::dirt(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("dirt");
}
} else {
commands
.spawn(FloorTilePrefab::dirt(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("dirt");
}
} else if noise_position.z < position.z {
commands
.spawn(FloorTilePrefab::air(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("air");
} else {
commands
.spawn(FloorTilePrefab::dirt(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("dirt");
}
// Store floor type and position
if let Some(floor_type) = floor_type {
floor_positions.push((position, floor_type));
}
}
}
}
// Generate bedrock floor
for x in -50..50 {
for y in -50..50 {
let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -150.);
commands.spawn(FloorTilePrefab::bedrock(position, asset_server));
floor_positions.push((position, "bedrock"));
}
}
// Sort floor positions by z coordinate (highest to lowest) to process from top to bottom
floor_positions.sort_by(|a, b| b.0.z.partial_cmp(&a.0.z).unwrap());
// Create a map to easily look up floor types at specific positions
let floor_map: std::collections::HashMap<(i32, i32, i32), &str> = floor_positions
.iter()
.map(|(pos, floor_type)| ((pos.x as i32, pos.y as i32, pos.z as i32), *floor_type))
.collect();
// Second pass: Generate fixtures based on floor tiles above
for (position, _) in floor_positions.iter() {
let x = position.x as i32;
let y = position.y as i32;
let z = position.z as i32;
// Look up the floor type one z-level above
if let Some(above_floor_type) = floor_map.get(&(x, y, z + TILE_SIZE as i32)) {
// Skip if the floor above is air or if we're at the surface
if *above_floor_type == "air" {
continue;
}
// Calculate fixture position (one tile above current floor)
let fixture_position = Vec3::new(position.x, position.y, position.z + 1.);
// Spawn appropriate fixture based on floor type above
match *above_floor_type {
"dirt" => {
commands.spawn(FixtureTilePrefab::dirt_wall(fixture_position, asset_server));
}
"rock" => {
commands.spawn(FixtureTilePrefab::rock_wall(fixture_position, asset_server));
}
"bedrock" => {
commands.spawn(FixtureTilePrefab::bedrock_wall(
fixture_position,
asset_server,
));
}
_ => {}
}
}
}
}