From 80afd547e587d27edc6dfd67b388f573c3ce910e Mon Sep 17 00:00:00 2001 From: StephenAdamson Date: Tue, 17 Dec 2024 19:44:54 +0000 Subject: [PATCH] Occlusion attempt 1 --- .vscode/launch.json | 45 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + assets/bedrock.png | Bin 0 -> 601 bytes src/game.rs | 30 ++++++++++++++--------------- src/main.rs | 2 +- src/tile.rs | 42 ++++++++++++++++++++++++++++++++++------- src/tiles.rs | 42 ++++++++++++++++++++++++++++++++++------- 7 files changed, 131 insertions(+), 31 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 assets/bedrock.png diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3499889 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'dorf'", + "cargo": { + "args": [ + "build", + "--bin=dorf", + "--package=dorf" + ], + "filter": { + "name": "dorf", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'dorf'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=dorf", + "--package=dorf" + ], + "filter": { + "name": "dorf", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 9ae15c9..aacab8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ opt-level = 3 # Enable only a small amount of optimization in debug mode [profile.dev] opt-level = 1 +debug = true [profile.release] lto = true diff --git a/assets/bedrock.png b/assets/bedrock.png new file mode 100644 index 0000000000000000000000000000000000000000..57ab404ca6d0cb2a318160e88f6b96169161c73b GIT binary patch literal 601 zcmV-f0;c_mP)EX>4Tx04R}tkv&MmKpe$iQ>7vmQ9Fn@WT;Md@e9XN#UfZJZG~1HOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4P#J2)x2NQwVT3N2zhIPS;0dyl(!fY7Kg)$ED_s%9Cf zcudUZR>i<8f*8OcW)P8>sVCBl8F-Gbd-(Wz7vWjn=l&dhO5S9EPb7{q-LQx^h-Wt~ zo%23%h?OLT_?&pcpbHW|a$R=$jdRgqfoFz{OlqDuL@X9NSngm}GF0Me;;^D>lrLmm zRyc2QRx35ux+i~OFt4qoxlVHwaV#N$Bt*!lp^OSFL}=AWF_EJEn1_GF@h8b8ldB9y zjs;YqLUR1zfAG6ovoJO3CIw?a_ls?Ri~)gNpjo%=?_=9;o&f%5;7V)zs|{f8lk|F9 z3m*af+rY(jTa)*I%N=0&NtX=Ck^D4;LIHR`qi@OqL$^Thn%i4zAEysMhPqn50S*p< z@gilfd%U}+v$ucGwEFu2C=hb*3khoY00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF;2%5fd8|D1Ld_0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN zLrFwIR5;7+lQ9keAP55w02V-1Rj5u;z2RihE35fs|z_6!dpSn&c6h%~PpWQc=THkNG@ygq00000NkvXXu0mjf0P^+# literal 0 HcmV?d00001 diff --git a/src/game.rs b/src/game.rs index bc37ca5..5daf154 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,12 +1,12 @@ use crate::citizen::Citizen; +use crate::constants::*; use crate::item::{Item, ItemBundle}; use crate::tiles::TilePrefab; -use crate::constants::*; use bevy::prelude::*; -use rand::prelude::*; use noise::{NoiseFn, Perlin}; +use rand::prelude::*; -pub const Z_INDEX:f32 = 0.; +pub const Z_INDEX: f32 = 0.; pub fn setup_level(mut commands: Commands, asset_server: Res) { setup_tilemap(&mut commands, &asset_server); @@ -26,21 +26,13 @@ pub fn setup_level(mut commands: Commands, asset_server: Res) { fn setup_tilemap(commands: &mut Commands, asset_server: &Res) { let perlin = Perlin::new(0); - for x in -20..20 { - for y in -20..20 { - for z in -2..10 { - let position = Vec3::new( - x as f32 * TILE_SIZE, - y as f32 * TILE_SIZE, - -z as f32, - ); + for x in -15..15 { + for y in -15..15 { + for z in -2..15 { + let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -z as f32); // Generate Perlin noise value - let noise_value = perlin.get([ - x as f64 * 0.1, - y as f64 * 0.1, - z as f64 * 0.1, - ]); + let noise_value = perlin.get([x as f64 * 0.1, y as f64 * 0.1, z as f64 * 0.1]); let mut items: Vec = vec![]; if noise_value < -0.4 { @@ -73,4 +65,10 @@ fn setup_tilemap(commands: &mut Commands, asset_server: &Res) { } } } + for x in -15..15 { + for y in -15..15 { + let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -14.); + commands.spawn(TilePrefab::bedrock(position, asset_server)); + } + } } diff --git a/src/main.rs b/src/main.rs index 1aba68d..6d98fd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,7 @@ fn main() { ) .insert_resource(ClearColor(Color::srgb(0.0, 0.0, 0.0))) .add_systems(Startup, (game::setup_level, camera::spawn_panning_camera)) - .add_systems(PostStartup, tile::tile_sprite_visibility_update) + .add_systems(PostStartup, tile::tile_sprite_occlusion_update) .add_systems(Startup, cursor::setup_curor) .add_systems( FixedUpdate, diff --git a/src/tile.rs b/src/tile.rs index 110df9f..58d9e0b 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -1,16 +1,23 @@ use crate::item::Item; use crate::{constants::*, game}; +use bevy::math::vec2; use bevy::prelude::*; +use std::collections::HashMap; +use std::process::exit; #[derive(Component)] #[require(Sprite)] pub struct Tile { pub id: u32, + pub opaque: bool, } impl Default for Tile { fn default() -> Self { - Self { id: 1 } + Self { + id: 1, + opaque: true, + } } } @@ -51,22 +58,32 @@ pub struct DoorTile { pub locked: bool, } -pub fn tile_sprite_visibility_update( - mut query: Query<(&mut Visibility, &Transform), With>, +pub fn tile_sprite_occlusion_update( + mut query: Query<(&mut Visibility, &Transform, &Tile), With>, tile_query: Query<(&Transform, &Tile)>, ) { - for (mut visibility, transform) in query.iter_mut() { + let mut z_map: HashMap<(i32, i32), i32> = HashMap::new(); + + for (mut visibility, transform, tile) in query.iter_mut() { *visibility = Visibility::Hidden; if transform.translation.z > game::Z_INDEX { continue; } + if let Some(z_val) = z_map.get(&( + transform.translation.x.round() as i32, + transform.translation.y.round() as i32, + )) { + if *z_val >= transform.translation.z as i32 { + continue; + } + } for x_offset in -1..=1 { for y_offset in -1..=1 { - for z_offset in -1..=0 { + for z_offset in -1..=1 { if x_offset == 0 && y_offset == 0 && z_offset == 0 { - continue; // Skip the current tile + continue; // don't check against itself } let neighbor_position = transform.translation + Vec3::new( @@ -75,13 +92,24 @@ pub fn tile_sprite_visibility_update( z_offset as f32 * TILE_SIZE, ); - if let Some((neighbor_transform, neighbor_tile)) = + if let Some((_, neighbor_tile)) = tile_query.iter().find(|(neighbor_transform, _)| { neighbor_transform.translation == neighbor_position }) { + // id == 0 is sky. So if bordering a sky tile (i.e. not deep underground) if neighbor_tile.id == 0 { *visibility = Visibility::Visible; + // if opaque, do not look deeper on this X,Y + if tile.opaque { + z_map.insert( + ( + transform.translation.x.round() as i32, + transform.translation.y.round() as i32, + ), + transform.translation.z.round() as i32, + ); + } break; } } diff --git a/src/tiles.rs b/src/tiles.rs index 3aab658..c6ed97b 100644 --- a/src/tiles.rs +++ b/src/tiles.rs @@ -1,6 +1,6 @@ -use bevy::prelude::*; -use crate::tile::{Tile, TileState}; use crate::constants::*; +use crate::tile::{Tile, TileState}; +use bevy::prelude::*; #[derive(Bundle)] pub struct TilePrefab { @@ -18,7 +18,10 @@ impl TilePrefab { image: asset_server.load("dirt.png"), ..Default::default() }, - tile: Tile {id:1}, + tile: Tile { + id: 1, + opaque: true, + }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, @@ -32,7 +35,10 @@ impl TilePrefab { image: asset_server.load("grass.png"), ..Default::default() }, - tile: Tile {id:2}, + tile: Tile { + id: 2, + opaque: true, + }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, @@ -46,7 +52,10 @@ impl TilePrefab { image: asset_server.load("rock.png"), ..Default::default() }, - tile: Tile {id:3}, + tile: Tile { + id: 3, + opaque: true, + }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, @@ -59,10 +68,29 @@ impl TilePrefab { image: asset_server.load("sky.png"), ..Default::default() }, - tile: Tile {id:0}, + tile: Tile { + id: 0, + opaque: false, + }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, } } -} \ No newline at end of file + pub fn bedrock(position: Vec3, asset_server: &Res) -> Self { + TilePrefab { + transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), + sprite: Sprite { + image: asset_server.load("bedrock.png"), + ..Default::default() + }, + tile: Tile { + id: 4, + opaque: true, + }, + tile_state: TileState { + timer: Timer::from_seconds(1.0, TimerMode::Repeating), + }, + } + } +}