From 1d292d080bd0e8057de725bd478c90dccd43d42e Mon Sep 17 00:00:00 2001 From: StephenAdamson Date: Fri, 20 Dec 2024 22:45:30 +0000 Subject: [PATCH] Noise surface --- src/camera.rs | 10 +++--- src/citizen.rs | 12 +++---- src/constants.rs | 2 +- src/cursor.rs | 4 +-- src/game.rs | 90 +++++++++++++++++++++++++++++++++++++----------- src/main.rs | 9 ++++- src/tile.rs | 24 ++++++++----- 7 files changed, 105 insertions(+), 46 deletions(-) diff --git a/src/camera.rs b/src/camera.rs index 3c0c3c0..7ab5567 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,5 +1,5 @@ -use bevy::prelude::*; use bevy::input::keyboard::KeyCode; +use bevy::prelude::*; #[derive(Component)] pub struct PanningCamera { @@ -28,7 +28,7 @@ pub fn camera_movement( if direction.length() > 0.0 { direction = direction.normalize(); - + let movement = direction * camera.pan_speed; transform.translation.x += movement.x; transform.translation.y += movement.y; @@ -39,7 +39,7 @@ pub fn camera_movement( pub fn spawn_panning_camera(mut commands: Commands) { commands.spawn(( Camera2d::default(), - Transform::from_xyz(0.,0.,10.), - PanningCamera { pan_speed: 5.0 } + Transform::from_xyz(0., 0., 10.), + PanningCamera { pan_speed: 5.0 }, )); -} \ No newline at end of file +} diff --git a/src/citizen.rs b/src/citizen.rs index 9178e5b..b9aac5f 100644 --- a/src/citizen.rs +++ b/src/citizen.rs @@ -18,7 +18,7 @@ pub struct Citizen { impl Citizen { pub fn new(asset_server: &Res, position: Vec3) -> Self { Citizen { - walker: Ambulatory { speed: 64. }, + walker: Ambulatory { speed: TILE_SIZE }, sprite: Sprite { image: asset_server.load("character.png"), ..Default::default() @@ -28,11 +28,9 @@ impl Citizen { } } -pub fn citizen_movement( - mut query: Query<(&Ambulatory, &mut Transform), With>, -) { +pub fn citizen_movement(mut query: Query<(&Ambulatory, &mut Transform), With>) { for (citizen, mut transform) in query.iter_mut() { - if random::() < 0.66666{ + if random::() < 0.66666 { continue; } let mut direction = Vec2::ZERO; @@ -51,9 +49,9 @@ pub fn citizen_movement( transform.translation.y += movement.y; if direction.x > 0.0 { - transform.scale.x = PIXEL_RATIO.abs(); + transform.scale.x = PIXEL_RATIO; } else if direction.x < 0.0 { - transform.scale.x = -PIXEL_RATIO.abs(); + transform.scale.x = -PIXEL_RATIO; } } } diff --git a/src/constants.rs b/src/constants.rs index 8246d63..cba30c1 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,2 +1,2 @@ -pub const PIXEL_RATIO: f32 = 2.0; +pub const PIXEL_RATIO: f32 = 3.; pub const TILE_SIZE: f32 = 16.0 * PIXEL_RATIO; diff --git a/src/cursor.rs b/src/cursor.rs index 37ca642..6160ef3 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -37,8 +37,8 @@ pub fn move_cursor( return; }; transform.1.translation = Vec3::new( - ((point.x / (TILE_SIZE)+0.5).floor()) * TILE_SIZE, - ((point.y / (TILE_SIZE)+0.5).floor()) * TILE_SIZE, + ((point.x / (TILE_SIZE) + 0.5).floor()) * TILE_SIZE, + ((point.y / (TILE_SIZE) + 0.5).floor()) * TILE_SIZE, 100.0, ); } diff --git a/src/game.rs b/src/game.rs index 1180ec5..bb80338 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,3 +1,5 @@ +use std::process::exit; + use crate::citizen::Citizen; use crate::constants::*; use crate::item::{Item, ItemBundle}; @@ -17,7 +19,7 @@ pub fn setup_level(mut commands: Commands, asset_server: Res) { if random::() < 0.1 { commands.spawn(Citizen::new( &asset_server, - Vec3::new(x as f32 * 64., y as f32 * 64., 0.9), + Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, 0.9), )); } } @@ -25,18 +27,73 @@ pub fn setup_level(mut commands: Commands, asset_server: Res) { } fn setup_tilemap(commands: &mut Commands, asset_server: &Res) { - let perlin = Perlin::new(0); + let noise = Perlin::new(0); - for x in -50..50 { - for y in -50..50 { - for z in -50..150 { - let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -z as f32); + 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; - // Generate Perlin noise value - let noise_value = perlin.get([x as f64 * 0.1, y as f64 * 0.1, z as f64 * 0.1]); + // 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 mut items: Vec = vec![]; - if noise_value < -0.4 { + 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 = vec![]; + + 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]); + if noise_value < -0.5 { + commands + .spawn(TilePrefab::air(position, asset_server)) + .with_children(|parent| { + for item in items { + parent.spawn(item); + } + }); + } else if noise_value < 0.8 { + commands + .spawn(TilePrefab::rock(position, asset_server)) + .with_children(|parent| { + for item in items { + parent.spawn(item); + } + }); + } else { + commands + .spawn(TilePrefab::dirt(position, asset_server)) + .with_children(|parent| { + for item in items { + parent.spawn(item); + } + }); + } + } else { + commands + .spawn(TilePrefab::dirt(position, asset_server)) + .with_children(|parent| { + for item in items { + parent.spawn(item); + } + }); + } + } else if noise_position.z < position.z { commands .spawn(TilePrefab::air(position, asset_server)) .with_children(|parent| { @@ -44,7 +101,7 @@ fn setup_tilemap(commands: &mut Commands, asset_server: &Res) { parent.spawn(item); } }); - } else if noise_value < -0.2 { + } else { commands .spawn(TilePrefab::grass(position, asset_server)) .with_children(|parent| { @@ -52,20 +109,11 @@ fn setup_tilemap(commands: &mut Commands, asset_server: &Res) { parent.spawn(item); } }); - } else if noise_value < 0.2 { - commands - .spawn(TilePrefab::dirt(position, asset_server)) - .with_children(|parent| { - for item in items { - parent.spawn(item); - } - }); - } else { - commands.spawn(TilePrefab::rock(position, asset_server)); } } } } + 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.); diff --git a/src/main.rs b/src/main.rs index 21c5396..9423538 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,7 +32,14 @@ fn main() { cursor::setup_cursor, ), ) - .add_systems(PostStartup, (tile::tile_sprite_generate_occlusion_map,tile::update_tile_visibility).chain()) + .add_systems( + PostStartup, + ( + tile::tile_sprite_generate_occlusion_map, + tile::update_tile_visibility, + ) + .chain(), + ) .add_systems( FixedUpdate, ( diff --git a/src/tile.rs b/src/tile.rs index 6e97fab..5d20b4c 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -1,8 +1,10 @@ +use crate::constants::TILE_SIZE; use crate::game; use crate::item::Item; use bevy::ecs::system::ParamSet; use bevy::prelude::*; use std::collections::HashMap; +use std::process::exit; #[derive(Component, Clone)] #[require(Sprite)] @@ -118,18 +120,19 @@ pub fn tile_sprite_generate_occlusion_map( ); // Check visibility for each possible z-index - for camera_z in -150..100 { + for mut camera_z in -150..100 { + camera_z *= TILE_SIZE as i32; let mut is_visible = false; // Skip if tile is above camera - if pos.2 > camera_z { + if pos.2 > (camera_z) { continue; } // Check for opaque tiles above let mut is_occluded = false; 'vertical_check: for z_offset in 1..=20 { - let above_pos = (pos.0, pos.1, pos.2 + z_offset); + let above_pos = (pos.0, pos.1, pos.2 + (z_offset * TILE_SIZE as i32)); if above_pos.2 <= camera_z { if let Some(&(is_opaque, _)) = tile_map.get(&above_pos) { if is_opaque { @@ -137,6 +140,8 @@ pub fn tile_sprite_generate_occlusion_map( break 'vertical_check; } } + } else { + break 'vertical_check; } } @@ -149,12 +154,14 @@ pub fn tile_sprite_generate_occlusion_map( continue; } - let neighbor_pos = - (pos.0 + x_offset, pos.1 + y_offset, pos.2 + z_offset); - + let neighbor_pos = ( + pos.0 + (x_offset * TILE_SIZE as i32), + pos.1 + (y_offset * TILE_SIZE as i32), + pos.2 + (z_offset * TILE_SIZE as i32), + ); if let Some(&(_, id)) = tile_map.get(&neighbor_pos) { if id == 0 { - // sky tile + // air tile is_visible = true; break 'neighbor_check; } @@ -165,7 +172,7 @@ pub fn tile_sprite_generate_occlusion_map( } if is_visible { - let z2 = (camera_z + 150) as usize; + let z2 = ((camera_z / TILE_SIZE as i32) + 150) as usize; tile.visible_range[z2 / 32] |= 1 << ((z2 % 32) as u32); } } @@ -177,7 +184,6 @@ pub fn update_tile_visibility( mut query: Query<(&Tile, &mut Visibility)>, ) { let z_index = (z_index.0 as i32 + 150) as usize; - query.par_iter_mut().for_each(|(tile, mut visibility)| { let is_visible = (tile.visible_range[z_index / 32] & (1 << (z_index % 32) as u32)) != 0; *visibility = if is_visible {