occlusion part 2
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 633 B |
+5
-4
@@ -6,7 +6,8 @@ use bevy::prelude::*;
|
|||||||
use noise::{NoiseFn, Perlin};
|
use noise::{NoiseFn, Perlin};
|
||||||
use rand::prelude::*;
|
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<AssetServer>) {
|
pub fn setup_level(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
setup_tilemap(&mut commands, &asset_server);
|
setup_tilemap(&mut commands, &asset_server);
|
||||||
@@ -26,9 +27,9 @@ 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 perlin = Perlin::new(0);
|
||||||
|
|
||||||
for x in -15..15 {
|
for x in -50..50 {
|
||||||
for y in -15..15 {
|
for y in -50..50 {
|
||||||
for z in -2..15 {
|
for z in -5..40 {
|
||||||
let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -z as f32);
|
let position = Vec3::new(x as f32 * TILE_SIZE, y as f32 * TILE_SIZE, -z as f32);
|
||||||
|
|
||||||
// Generate Perlin noise value
|
// Generate Perlin noise value
|
||||||
|
|||||||
+5
-3
@@ -1,16 +1,17 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
mod constants;
|
|
||||||
mod camera;
|
mod camera;
|
||||||
mod citizen;
|
mod citizen;
|
||||||
|
mod constants;
|
||||||
|
mod cursor;
|
||||||
mod game;
|
mod game;
|
||||||
mod item;
|
mod item;
|
||||||
mod tile;
|
mod tile;
|
||||||
mod tiles;
|
mod tiles;
|
||||||
mod cursor;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
|
.insert_resource(game::ZIndex(-5.0))
|
||||||
.add_plugins(
|
.add_plugins(
|
||||||
DefaultPlugins
|
DefaultPlugins
|
||||||
.set(WindowPlugin {
|
.set(WindowPlugin {
|
||||||
@@ -24,7 +25,7 @@ fn main() {
|
|||||||
)
|
)
|
||||||
.insert_resource(ClearColor(Color::srgb(0.0, 0.0, 0.0)))
|
.insert_resource(ClearColor(Color::srgb(0.0, 0.0, 0.0)))
|
||||||
.add_systems(Startup, (game::setup_level, camera::spawn_panning_camera))
|
.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(Startup, cursor::setup_curor)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
FixedUpdate,
|
FixedUpdate,
|
||||||
@@ -32,6 +33,7 @@ fn main() {
|
|||||||
camera::camera_movement,
|
camera::camera_movement,
|
||||||
citizen::citizen_movement,
|
citizen::citizen_movement,
|
||||||
tile::tile_item_sprite_update,
|
tile::tile_item_sprite_update,
|
||||||
|
// tile::camera_z_movement.chain(tile::tile_sprite_occlusion),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.add_systems(FixedUpdate, cursor::move_cursor)
|
.add_systems(FixedUpdate, cursor::move_cursor)
|
||||||
|
|||||||
+65
-40
@@ -1,9 +1,6 @@
|
|||||||
use crate::item::Item;
|
use crate::item::Item;
|
||||||
use crate::{constants::*, game};
|
use crate::game;
|
||||||
use bevy::math::vec2;
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::process::exit;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
#[require(Sprite)]
|
#[require(Sprite)]
|
||||||
@@ -58,65 +55,93 @@ pub struct DoorTile {
|
|||||||
pub locked: bool,
|
pub locked: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tile_sprite_occlusion_update(
|
// pub fn camera_z_movement(
|
||||||
|
// keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
|
// mut z_index: ResMut<game::ZIndex>,
|
||||||
|
// ) {
|
||||||
|
// 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>>,
|
mut query: Query<(&mut Visibility, &Transform, &Tile), With<Tile>>,
|
||||||
tile_query: Query<(&Transform, &Tile)>,
|
tile_query: Query<(&Transform, &Tile)>,
|
||||||
|
z_index: ResMut<game::ZIndex>,
|
||||||
) {
|
) {
|
||||||
let mut z_map: HashMap<(i32, i32), i32> = HashMap::new();
|
use std::collections::HashMap;
|
||||||
|
|
||||||
for (mut visibility, transform, tile) in query.iter_mut() {
|
// Build spatial lookup
|
||||||
*visibility = Visibility::Hidden;
|
let tile_map: HashMap<(i32, i32, i32), &Tile> = tile_query
|
||||||
|
.iter()
|
||||||
if transform.translation.z > game::Z_INDEX {
|
.map(|(transform, tile)| {
|
||||||
continue;
|
(
|
||||||
}
|
(
|
||||||
if let Some(z_val) = z_map.get(&(
|
|
||||||
transform.translation.x.round() as i32,
|
transform.translation.x.round() as i32,
|
||||||
transform.translation.y.round() as i32,
|
transform.translation.y.round() as i32,
|
||||||
)) {
|
transform.translation.z.round() as i32,
|
||||||
if *z_val >= transform.translation.z as i32 {
|
),
|
||||||
continue;
|
tile,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos = (
|
||||||
|
transform.translation.x.round() as i32,
|
||||||
|
transform.translation.y.round() as i32,
|
||||||
|
transform.translation.z.round() as i32,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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 x_offset in -1..=1 {
|
||||||
for y_offset in -1..=1 {
|
for y_offset in -1..=1 {
|
||||||
for z_offset in -1..=1 {
|
for z_offset in -1..=1 {
|
||||||
if x_offset == 0 && y_offset == 0 && z_offset == 0 {
|
if x_offset == 0 && y_offset == 0 && z_offset == 0 {
|
||||||
continue; // don't check against itself
|
continue;
|
||||||
}
|
}
|
||||||
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,
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some((_, neighbor_tile)) =
|
let neighbor_pos = (pos.0 + x_offset, pos.1 + y_offset, pos.2 + z_offset);
|
||||||
tile_query.iter().find(|(neighbor_transform, _)| {
|
|
||||||
neighbor_transform.translation == neighbor_position
|
if let Some(neighbor_tile) = tile_map.get(&neighbor_pos) {
|
||||||
})
|
// id == 0 is sky
|
||||||
{
|
|
||||||
// id == 0 is sky. So if bordering a sky tile (i.e. not deep underground)
|
|
||||||
if neighbor_tile.id == 0 {
|
if neighbor_tile.id == 0 {
|
||||||
*visibility = Visibility::Visible;
|
*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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tile_item_sprite_update(
|
pub fn tile_item_sprite_update(
|
||||||
|
|||||||
@@ -93,4 +93,21 @@ impl TilePrefab {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn underground(position: Vec3, asset_server: &Res<AssetServer>) -> 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),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user