Noise surface

This commit is contained in:
StephenAdamson
2024-12-20 22:45:30 +00:00
parent 4141a1b430
commit 1d292d080b
7 changed files with 105 additions and 46 deletions
+5 -5
View File
@@ -1,5 +1,5 @@
use bevy::prelude::*;
use bevy::input::keyboard::KeyCode; use bevy::input::keyboard::KeyCode;
use bevy::prelude::*;
#[derive(Component)] #[derive(Component)]
pub struct PanningCamera { pub struct PanningCamera {
@@ -28,7 +28,7 @@ pub fn camera_movement(
if direction.length() > 0.0 { if direction.length() > 0.0 {
direction = direction.normalize(); direction = direction.normalize();
let movement = direction * camera.pan_speed; let movement = direction * camera.pan_speed;
transform.translation.x += movement.x; transform.translation.x += movement.x;
transform.translation.y += movement.y; transform.translation.y += movement.y;
@@ -39,7 +39,7 @@ pub fn camera_movement(
pub fn spawn_panning_camera(mut commands: Commands) { pub fn spawn_panning_camera(mut commands: Commands) {
commands.spawn(( commands.spawn((
Camera2d::default(), Camera2d::default(),
Transform::from_xyz(0.,0.,10.), Transform::from_xyz(0., 0., 10.),
PanningCamera { pan_speed: 5.0 } PanningCamera { pan_speed: 5.0 },
)); ));
} }
+5 -7
View File
@@ -18,7 +18,7 @@ pub struct Citizen {
impl Citizen { impl Citizen {
pub fn new(asset_server: &Res<AssetServer>, position: Vec3) -> Self { pub fn new(asset_server: &Res<AssetServer>, position: Vec3) -> Self {
Citizen { Citizen {
walker: Ambulatory { speed: 64. }, walker: Ambulatory { speed: TILE_SIZE },
sprite: Sprite { sprite: Sprite {
image: asset_server.load("character.png"), image: asset_server.load("character.png"),
..Default::default() ..Default::default()
@@ -28,11 +28,9 @@ impl Citizen {
} }
} }
pub fn citizen_movement( pub fn citizen_movement(mut query: Query<(&Ambulatory, &mut Transform), With<Ambulatory>>) {
mut query: Query<(&Ambulatory, &mut Transform), With<Ambulatory>>,
) {
for (citizen, mut transform) in query.iter_mut() { for (citizen, mut transform) in query.iter_mut() {
if random::<f32>() < 0.66666{ if random::<f32>() < 0.66666 {
continue; continue;
} }
let mut direction = Vec2::ZERO; let mut direction = Vec2::ZERO;
@@ -51,9 +49,9 @@ pub fn citizen_movement(
transform.translation.y += movement.y; transform.translation.y += movement.y;
if direction.x > 0.0 { if direction.x > 0.0 {
transform.scale.x = PIXEL_RATIO.abs(); transform.scale.x = PIXEL_RATIO;
} else if direction.x < 0.0 { } else if direction.x < 0.0 {
transform.scale.x = -PIXEL_RATIO.abs(); transform.scale.x = -PIXEL_RATIO;
} }
} }
} }
+1 -1
View File
@@ -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; pub const TILE_SIZE: f32 = 16.0 * PIXEL_RATIO;
+2 -2
View File
@@ -37,8 +37,8 @@ pub fn move_cursor(
return; return;
}; };
transform.1.translation = Vec3::new( transform.1.translation = Vec3::new(
((point.x / (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, ((point.y / (TILE_SIZE) + 0.5).floor()) * TILE_SIZE,
100.0, 100.0,
); );
} }
+69 -21
View File
@@ -1,3 +1,5 @@
use std::process::exit;
use crate::citizen::Citizen; use crate::citizen::Citizen;
use crate::constants::*; use crate::constants::*;
use crate::item::{Item, ItemBundle}; use crate::item::{Item, ItemBundle};
@@ -17,7 +19,7 @@ pub fn setup_level(mut commands: Commands, asset_server: Res<AssetServer>) {
if random::<f32>() < 0.1 { if random::<f32>() < 0.1 {
commands.spawn(Citizen::new( commands.spawn(Citizen::new(
&asset_server, &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<AssetServer>) {
} }
fn setup_tilemap(commands: &mut Commands, asset_server: &Res<AssetServer>) { fn setup_tilemap(commands: &mut Commands, asset_server: &Res<AssetServer>) {
let perlin = Perlin::new(0); let noise = Perlin::new(0);
for x in -50..50 { for y in -50..50 {
for y in -50..50 { for x in -50..50 {
for z in -50..150 { // Base noise for terrain height
let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -z as f32); 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 // Combine the two noise values
let noise_value = perlin.get([x as f64 * 0.1, y as f64 * 0.1, z as f64 * 0.1]); let combined_noise_value = noise_value_a + noise_value_b;
// print!("({}, {}, {}), ", noise_value_a, noise_value_b, combined_noise_value);
let mut items: Vec<ItemBundle> = vec![]; let noise_position = Vec3::new(
if noise_value < -0.4 { (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![];
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 commands
.spawn(TilePrefab::air(position, asset_server)) .spawn(TilePrefab::air(position, asset_server))
.with_children(|parent| { .with_children(|parent| {
@@ -44,7 +101,7 @@ fn setup_tilemap(commands: &mut Commands, asset_server: &Res<AssetServer>) {
parent.spawn(item); parent.spawn(item);
} }
}); });
} else if noise_value < -0.2 { } else {
commands commands
.spawn(TilePrefab::grass(position, asset_server)) .spawn(TilePrefab::grass(position, asset_server))
.with_children(|parent| { .with_children(|parent| {
@@ -52,20 +109,11 @@ fn setup_tilemap(commands: &mut Commands, asset_server: &Res<AssetServer>) {
parent.spawn(item); 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 x in -50..50 {
for y in -50..50 { for y in -50..50 {
let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -150.); let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -150.);
+8 -1
View File
@@ -32,7 +32,14 @@ fn main() {
cursor::setup_cursor, 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( .add_systems(
FixedUpdate, FixedUpdate,
( (
+15 -9
View File
@@ -1,8 +1,10 @@
use crate::constants::TILE_SIZE;
use crate::game; use crate::game;
use crate::item::Item; use crate::item::Item;
use bevy::ecs::system::ParamSet; use bevy::ecs::system::ParamSet;
use bevy::prelude::*; use bevy::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::process::exit;
#[derive(Component, Clone)] #[derive(Component, Clone)]
#[require(Sprite)] #[require(Sprite)]
@@ -118,18 +120,19 @@ pub fn tile_sprite_generate_occlusion_map(
); );
// Check visibility for each possible z-index // 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; let mut is_visible = false;
// Skip if tile is above camera // Skip if tile is above camera
if pos.2 > camera_z { if pos.2 > (camera_z) {
continue; continue;
} }
// Check for opaque tiles above // Check for opaque tiles above
let mut is_occluded = false; let mut is_occluded = false;
'vertical_check: for z_offset in 1..=20 { '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 above_pos.2 <= camera_z {
if let Some(&(is_opaque, _)) = tile_map.get(&above_pos) { if let Some(&(is_opaque, _)) = tile_map.get(&above_pos) {
if is_opaque { if is_opaque {
@@ -137,6 +140,8 @@ pub fn tile_sprite_generate_occlusion_map(
break 'vertical_check; break 'vertical_check;
} }
} }
} else {
break 'vertical_check;
} }
} }
@@ -149,12 +154,14 @@ pub fn tile_sprite_generate_occlusion_map(
continue; continue;
} }
let neighbor_pos = let neighbor_pos = (
(pos.0 + x_offset, pos.1 + y_offset, pos.2 + z_offset); 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 let Some(&(_, id)) = tile_map.get(&neighbor_pos) {
if id == 0 { if id == 0 {
// sky tile // air tile
is_visible = true; is_visible = true;
break 'neighbor_check; break 'neighbor_check;
} }
@@ -165,7 +172,7 @@ pub fn tile_sprite_generate_occlusion_map(
} }
if is_visible { 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); 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)>, mut query: Query<(&Tile, &mut Visibility)>,
) { ) {
let z_index = (z_index.0 as i32 + 150) as usize; let z_index = (z_index.0 as i32 + 150) as usize;
query.par_iter_mut().for_each(|(tile, mut visibility)| { 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; let is_visible = (tile.visible_range[z_index / 32] & (1 << (z_index % 32) as u32)) != 0;
*visibility = if is_visible { *visibility = if is_visible {