Separate floor from fixture

This commit is contained in:
StephenAdamson
2024-12-29 00:45:07 +00:00
parent 7da420a66e
commit 3aadb8bb78
24 changed files with 269 additions and 304 deletions
+68 -18
View File
@@ -1,9 +1,7 @@
use std::process::exit;
use crate::citizen::Citizen;
use crate::constants::*;
use crate::item::{Item, ItemBundle};
use crate::tiles::TilePrefab;
use crate::item::ItemBundle;
use crate::tiles::FloorTilePrefab;
use crate::{citizen::Citizen, tiles::FixtureTilePrefab};
use bevy::prelude::*;
use noise::{NoiseFn, Perlin};
use rand::prelude::*;
@@ -28,17 +26,14 @@ pub fn setup_level(mut commands: Commands, asset_server: Res<AssetServer>) {
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 {
// Base noise for terrain height
let noise_value_a = noise.get([x as f64 * 0.01, y as f64 * 0.01]) * 1.25;
// Additional noise for bumpiness
let noise_value_b = noise.get([x as f64 * 0.05, y as f64 * 0.05]) * 0.25;
// Combine the two noise values
let combined_noise_value = noise_value_a + noise_value_b;
// print!("({}, {}, {}), ", noise_value_a, noise_value_b, combined_noise_value);
let noise_position = Vec3::new(
(x as f32 * TILE_SIZE).round(),
@@ -54,70 +49,125 @@ fn setup_tilemap(commands: &mut Commands, asset_server: &Res<AssetServer>) {
);
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.1, y as f64 * 0.1, z as f64 * 0.1]);
noise.get([x as f64 * 0.05, y as f64 * 0.05, z as f64 * 0.05]);
if noise_value < -0.5 {
commands
.spawn(TilePrefab::air(position, asset_server))
.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(TilePrefab::rock(position, asset_server))
.spawn(FloorTilePrefab::rock(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("rock");
} else {
commands
.spawn(TilePrefab::dirt(position, asset_server))
.spawn(FloorTilePrefab::dirt(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("dirt");
}
} else {
commands
.spawn(TilePrefab::dirt(position, asset_server))
.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(TilePrefab::air(position, asset_server))
.spawn(FloorTilePrefab::air(position, asset_server))
.with_children(|parent| {
for item in items {
parent.spawn(item);
}
});
floor_type = Some("air");
} else {
commands
.spawn(TilePrefab::grass(position, asset_server))
.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(TilePrefab::bedrock(position, asset_server));
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(fixture_position, asset_server));
}
"rock" => {
commands.spawn(FixtureTilePrefab::rock(fixture_position, asset_server));
}
"bedrock" => {
commands.spawn(FixtureTilePrefab::bedrock(fixture_position, asset_server));
}
_ => {}
}
}
}
}