From caacf4e072663917a92ce15c3d69a35eb334ef7e Mon Sep 17 00:00:00 2001 From: StephenAdamson Date: Tue, 17 Dec 2024 21:10:21 +0000 Subject: [PATCH] occlusion part 2 --- assets/sky.png | Bin 4774 -> 5511 bytes assets/underground.png | Bin 0 -> 633 bytes src/game.rs | 9 +-- src/main.rs | 8 ++- src/tile.rs | 127 ++++++++++++++++++++++++----------------- src/tiles.rs | 17 ++++++ 6 files changed, 103 insertions(+), 58 deletions(-) create mode 100644 assets/underground.png diff --git a/assets/sky.png b/assets/sky.png index 5d4304b5bc20e4be518f3a8a370123d99be543cd..81cc912093495f4776ec1ca3d3d9df54874876b6 100644 GIT binary patch delta 1462 zcmV;n1xfm*C5J1JBYy)WdQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+U=HYj^ro| zhW~SlJp#5dHpd|lq`ko&e_sfd>YARGdS>>|N)=RmIK(!7?4-i^&)*~bg^Q!6kkmYv zoFlGOQsIh;$Ll&)Pcf~2FXChJA`kZshDb2VwJf~lC*+vZUVoQugdY1Jif&64GkxBu zb<2-e`LPwU|EOqtAaq%deLt`j32%?mwQk#^T-;uc*4wt6w#c8qB*s}YSwf#Un&pDI zb4-SK_UY(oT$Uoe0(uJ`>&I4xPkahVL@$yqFJ=CcRLFVt7O;_|V4>oxFDvj7DB%J; zE!$9ycQ8N3=6@NZFRt$#E5gV)=jIR8o(b}rANP#Dknc3Osd?Tv<1<4RB6z;#zqY;CO+9PGPl68gntf5g`3P|NVCykLt1ns1xvef zNci@Jmf5n*HS*X)?1ZgMP&Sk6w_Et`#xZ6s5kc z_Tx3V3JB^7v*Um@9^q1PC_R%)7HGjn#duXcS>Fl}BA8Ya=(%rB)cN&|L9!#fDlB zKIBM;9{I4tj}ngBkUlLnZMj+VR$A@crK7-m?tj+3mtIdgkxFMe^~|T8ewMQiq}q^? zhK@We3?F6Go7%?usr>>q+SGWFnj7t=2C3OY17%)i<8f*8Oc zW)P8>sVCBl8F-Gbd-(Wz7vWjn=l&dhO5S9EPb7{q-LQx^h-Wt~o%23%h?OLT_?&pc zpbHW|a$R=$jdRgqfoFz{OlqDuL@X9NSngm}GF0Me;;^D>lrLmmRyc2QRx35ux+i~O zFn_PDq`6LW6mcvefh0u8sG*DsEJSG4NHLM3{g{V;#PKJ|C6lWRMvetkp+a)};D7MD zTeC1V=_UnZK=+Gne~bZvU7%UF?eAmTZk_=CXW&X}`>PFL?vwO-TMHin{oBCBbz777 zfXf|V_(_)x$&vgtg+c*%KcjET0YkSy?<|_zTWcSu4?u>xTD}1e4uSC^Wv_d@yQj0a zf6uh~`vE8ra__bNfVBVs5Erx50*V48GB9H`GG$_9EjVK~GA%SXG&3z>V=`ndVlZT7 zFkxjmWMwd9lY#|`2UlrsWN&wKlMx0PCNwrRH8VLjI5IUfGa?EgARtFcO;9>kWpZIyE>tH93>91|$kMR53X^H8?soIkVpe&jOPT2V5jF zI5jphF*P+UF<~(_Ei^GWH7#OeW-u)IyE>tH951U z31|oeG%p_!lOz%#2oV!HJCRhxz>`c8GbfA?0|kJIfkH59z^DPE1`HMh05~NARkV>T QsQ>@~07*qoM6N<$g7JutC;$Ke delta 887 zcmZqIUZy%hxt>uZHNrE^(^HFqgMop8n}LCmg@F;s5&&XGBsLQxGXpbFY!VRjF)}d- z0qGe)ECdt>sRv;xMpiJr3doj*vNr+Q8c;PL{f0ojyg+&v5F0Tv)ia0y87F`^vmIjb z9UvP7IKa@kC^fMpHASI3vm`^o-P1RK;g2Q*Lo`qxMuP+ujPwi*^o%WlMj9BISQ#2w z8JZ{<7+4uwSQ(fwFfp`EVrP&9>iGr4j0+GBW?%>fia-ITRqu=ACjvDzXF59vcse^P z6cpvBW#*(ZFjUN`ooMTE*g@uKe6Z`pRn4+4GDchc$^td}wsN_y5XhR`&TLx0#^~%T zPlj1}vuB0`op~C5bYFOj0gFP{jx##Rev>YJkd6P&@!_l9vCV(Z|FvYh+H|y`!DCKB zTc&Wnz;W~3=FfJ8Gp43a{V}KF(h_bV`=Z#7KYEK#rZ%Rxoy|#`XW^qWZCAw0q%bqn zN0N^^R=u2}|HLNDGQaTJs?uxw)aw&hET~_vQ#|*XMNq^MA(f7R0C(2V8yy!{O-@pD z{_QFMf5z+SCzeiF&E(d{dS!uQ+205CA9hEtwy=Gw+B(VMefQ%Um&Sdu3$7N-d7ped zb1uWd^aoz=e`Nb6e4G5m&AnTO@$l^fM@!v3Z$GyZ7(j-k*N!?_Y+4r;3hQFWpklz`$>| z`58+WlZu6Da*9b>s=2O3TB5nGiD6=zu7$Blimst)idm{*qH(ghk@4gy>|HKCnR%rZ zN?ZyG;1ppMl9`(tT#}euV5?+kZfs&`Y-VO*Vrgk?ZeoE@6qZ_4oSC0zs{~CdlT$dt zxlBS}iDdFo4izNs=Fc4GnKm!vN#GE>+u-j7Od)JZ-tI08|3PrU-sO`gvx+Kk@G+>d zT#tX}Fj-gBSe-|mnYE#_(a9j|zzW92Y&>Gj48l8^d}N+lCV&!{r>mdKI;Vst04(ep A0ssI2 diff --git a/assets/underground.png b/assets/underground.png new file mode 100644 index 0000000000000000000000000000000000000000..802e47dca4f604495268b5943641cca874708af9 GIT binary patch literal 633 zcmV-<0*3vGP)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%5feBMg4R;^0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN zV@X6oR5;6}&`}P+AP56cy8GX`erbd$D~vBRrs)%AM*A_(ejr)eUjYEt17%+U`$aVb z^AAWG09SRMZ@VMJYAr%1#azf6ctT!Zcm(~r6R T<=%{800000NkvXXu0mjf_e=)t literal 0 HcmV?d00001 diff --git a/src/game.rs b/src/game.rs index 5daf154..e6e4e93 100644 --- a/src/game.rs +++ b/src/game.rs @@ -6,7 +6,8 @@ use bevy::prelude::*; use noise::{NoiseFn, Perlin}; use rand::prelude::*; -pub const Z_INDEX: f32 = 0.; +#[derive(Resource)] +pub struct ZIndex(pub f32); pub fn setup_level(mut commands: Commands, asset_server: Res) { setup_tilemap(&mut commands, &asset_server); @@ -26,9 +27,9 @@ 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 -15..15 { - for y in -15..15 { - for z in -2..15 { + for x in -50..50 { + for y in -50..50 { + for z in -5..40 { let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -z as f32); // Generate Perlin noise value diff --git a/src/main.rs b/src/main.rs index 6d98fd5..269b272 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,17 @@ use bevy::prelude::*; -mod constants; mod camera; mod citizen; +mod constants; +mod cursor; mod game; mod item; mod tile; mod tiles; -mod cursor; fn main() { App::new() + .insert_resource(game::ZIndex(-5.0)) .add_plugins( DefaultPlugins .set(WindowPlugin { @@ -24,7 +25,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_occlusion_update) + .add_systems(PostStartup, tile::tile_sprite_occlusion) .add_systems(Startup, cursor::setup_curor) .add_systems( FixedUpdate, @@ -32,6 +33,7 @@ fn main() { camera::camera_movement, citizen::citizen_movement, tile::tile_item_sprite_update, + // tile::camera_z_movement.chain(tile::tile_sprite_occlusion), ), ) .add_systems(FixedUpdate, cursor::move_cursor) diff --git a/src/tile.rs b/src/tile.rs index 58d9e0b..a793da7 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -1,9 +1,6 @@ use crate::item::Item; -use crate::{constants::*, game}; -use bevy::math::vec2; +use crate::game; use bevy::prelude::*; -use std::collections::HashMap; -use std::process::exit; #[derive(Component)] #[require(Sprite)] @@ -58,65 +55,93 @@ pub struct DoorTile { pub locked: bool, } -pub fn tile_sprite_occlusion_update( +// pub fn camera_z_movement( +// keyboard_input: Res>, +// mut z_index: ResMut, +// ) { +// if keyboard_input.pressed(KeyCode::ShiftLeft) { +// z_index.0 -= 1.0; +// } +// if keyboard_input.pressed(KeyCode::ShiftRight) { +// z_index.0 += 1.0; +// } +// } + +pub fn tile_sprite_occlusion( mut query: Query<(&mut Visibility, &Transform, &Tile), With>, tile_query: Query<(&Transform, &Tile)>, + z_index: ResMut, ) { - let mut z_map: HashMap<(i32, i32), i32> = HashMap::new(); + use std::collections::HashMap; - for (mut visibility, transform, tile) in query.iter_mut() { - *visibility = Visibility::Hidden; + // Build spatial lookup + let tile_map: HashMap<(i32, i32, i32), &Tile> = tile_query + .iter() + .map(|(transform, tile)| { + ( + ( + transform.translation.x.round() as i32, + transform.translation.y.round() as i32, + transform.translation.z.round() as i32, + ), + tile, + ) + }) + .collect(); - 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; + query + .par_iter_mut() + .for_each(|(mut visibility, transform, _)| { + *visibility = Visibility::Hidden; + + // Early exit for above camera layer + if transform.translation.z > z_index.0 { + return; } - } - for x_offset in -1..=1 { - for y_offset in -1..=1 { - for z_offset in -1..=1 { - if x_offset == 0 && y_offset == 0 && z_offset == 0 { - continue; // don't check against itself - } - let neighbor_position = transform.translation - + Vec3::new( - x_offset as f32 * TILE_SIZE, - y_offset as f32 * TILE_SIZE, - z_offset as f32 * TILE_SIZE, - ); + let pos = ( + transform.translation.x.round() as i32, + transform.translation.y.round() as i32, + transform.translation.z.round() as i32, + ); - 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; + // Check for any opaque tiles above the current tile + for z_offset in 1..=100 { + // Adjust the max height of the check if needed + let above_pos = (pos.0, pos.1, pos.2 + z_offset); + // look up until camera height + if above_pos.2 <= z_index.0 as i32 { + // get any tiles + if let Some(neighbor_tile) = tile_map.get(&above_pos) { + // If there's an opaque tile above, hide the current tile + if neighbor_tile.opaque { + return; // No need to check further; the tile should remain hidden } } } } - } - } + + // Check all neighbors around the tile + for x_offset in -1..=1 { + for y_offset in -1..=1 { + for z_offset in -1..=1 { + if x_offset == 0 && y_offset == 0 && z_offset == 0 { + continue; + } + + let neighbor_pos = (pos.0 + x_offset, pos.1 + y_offset, pos.2 + z_offset); + + if let Some(neighbor_tile) = tile_map.get(&neighbor_pos) { + // id == 0 is sky + if neighbor_tile.id == 0 { + *visibility = Visibility::Visible; + break; + } + } + } + } + } + }); } pub fn tile_item_sprite_update( diff --git a/src/tiles.rs b/src/tiles.rs index c6ed97b..f9ec6f0 100644 --- a/src/tiles.rs +++ b/src/tiles.rs @@ -93,4 +93,21 @@ impl TilePrefab { }, } } + + pub fn underground(position: Vec3, asset_server: &Res) -> Self { + TilePrefab { + transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), + sprite: Sprite { + image: asset_server.load("underground.png"), + ..Default::default() + }, + tile: Tile { + id: 5, + opaque: true, + }, + tile_state: TileState { + timer: Timer::from_seconds(1.0, TimerMode::Repeating), + }, + } + } }