diff --git a/assets/tilesets/tileset_blocked.png b/assets/tilesets/tileset_blocked.png new file mode 100644 index 0000000..0855ae3 Binary files /dev/null and b/assets/tilesets/tileset_blocked.png differ diff --git a/crates/assets/src/tileset_asset.rs b/crates/assets/src/tileset_asset.rs index 099899a..c455d47 100644 --- a/crates/assets/src/tileset_asset.rs +++ b/crates/assets/src/tileset_asset.rs @@ -7,6 +7,7 @@ use bevy::{ pub struct TilesetAsset { pub soil_tileset: Handle, pub fog_tileset: Handle, + pub blocked_tileset: Handle, pub water_tileset: Handle, pub floor_tileset: Handle, } @@ -14,6 +15,7 @@ pub struct TilesetAsset { impl TilesetAsset { const SOIL_PATH: &'static str = "tilesets/tileset_soil.png"; const FOG_PATH: &'static str = "tilesets/tileset_fog.png"; + const BLOCKED_PATH: &'static str = "tilesets/tileset_blocked.png"; const WATER_PATH: &'static str = "tilesets/tileset_water.png"; const FLOOR_PATH: &'static str = "tilesets/tileset_floors.png"; } @@ -34,6 +36,12 @@ impl FromWorld for TilesetAsset { settings.sampler = ImageSampler::nearest(); }, ), + blocked_tileset: assets.load_with_settings( + TilesetAsset::BLOCKED_PATH, + |settings: &mut ImageLoaderSettings| { + settings.sampler = ImageSampler::nearest(); + }, + ), water_tileset: assets.load_with_settings( TilesetAsset::WATER_PATH, |settings: &mut ImageLoaderSettings| { diff --git a/crates/camera/src/camera.rs b/crates/camera/src/camera.rs index 83cb741..e8d56ae 100644 --- a/crates/camera/src/camera.rs +++ b/crates/camera/src/camera.rs @@ -66,6 +66,10 @@ fn setup(mut commands: Commands) { commands.spawn(( input_map, Camera2d, + Projection::Orthographic(OrthographicProjection { + near: -0.5, + ..OrthographicProjection::default_2d() + }), CameraLayer(0), DespawnOnExit(AppState::MainGame), )); @@ -85,8 +89,17 @@ fn zoom( } } -fn scroll(query: Single<(&mut CameraLayer, &ActionState), With>) { - let (mut layer, action_state) = query.into_inner(); +fn scroll( + query: Single< + ( + &mut CameraLayer, + &ActionState, + &mut Transform, + ), + With, + >, +) { + let (mut layer, action_state, mut transform) = query.into_inner(); let mut delta = 0; if action_state.just_pressed(&CameraControls::ScrollUp) { delta += 1; @@ -95,6 +108,7 @@ fn scroll(query: Single<(&mut CameraLayer, &ActionState), With &tileset.floor_tileset, TileType::Half => &tileset.soil_tileset, TileType::Animated => &tileset.water_tileset, TileType::Fog => &tileset.fog_tileset, + TileType::Blocked => &tileset.blocked_tileset, }; - spawn_tile_map(&mut commands, tile_type, map, target, tileset_image); + spawn_tile_map( + &mut commands, + camera_layer.0 - (*z), + tile_type, + map, + target, + tileset_image, + ); } } } fn spawn_tile_map( commands: &mut Commands, + z: i32, tile_type: &TileType, tile_map: &Tilemap, parent_chunk: Entity, @@ -127,7 +136,7 @@ fn spawn_tile_map( texture: TilemapTexture::Single(tileset.clone()), tile_size, anchor: TilemapAnchor::BottomLeft, - transform: Transform::from_xyz(0.0, 0.0, tile_type.z_offset()), + transform: Transform::from_xyz(0.0, 0.0, z as f32 + tile_type.z_offset()), ..default() }) .insert(ChildOf(parent_chunk)); diff --git a/crates/map_generation/src/chunk_visualisation/types.rs b/crates/map_generation/src/chunk_visualisation/types.rs index afcdf05..234ee87 100644 --- a/crates/map_generation/src/chunk_visualisation/types.rs +++ b/crates/map_generation/src/chunk_visualisation/types.rs @@ -1,6 +1,10 @@ use std::{collections::HashMap, hash::Hash}; -use bevy::{color::palettes::css::WHITE, ecs::relationship::RelatedSpawnerCommands, prelude::*}; +use bevy::{ + color::palettes::css::{BLACK, WHITE}, + ecs::relationship::RelatedSpawnerCommands, + prelude::*, +}; use bevy_ecs_tilemap::prelude::*; use common::{constants::TILE_SIZE, traits::Neighbors, types::IWorldCoordinates}; @@ -12,6 +16,7 @@ pub(crate) enum TileType { Half, Animated, Fog, + Blocked, } impl TileType { @@ -38,16 +43,18 @@ impl TileType { TileType::Half => "Full-Tile Tilemap", TileType::Animated => "Animated Tilemap", TileType::Fog => "Fog Tilemap", + TileType::Blocked => "Blocked Tilemap", } } /// Returns the tilemap offset based on its type pub(crate) const fn z_offset(&self) -> f32 { match *self { - TileType::Full => -0.5, + TileType::Full => -0.1, TileType::Half => 0.0, - TileType::Animated => -0.5, - TileType::Fog => 1.0, + TileType::Animated => -0.1, + TileType::Fog => 0.2, + TileType::Blocked => -0.1, } } } @@ -62,6 +69,8 @@ pub(crate) enum TileWrapper { Animated, /// Wrapper for a fog type, carries the opacity in percent (ranging 0.0 to 1.0) Fog(f32), + // Wrapper for a tile that is not visible + Blocked, } impl TileWrapper { @@ -118,6 +127,17 @@ impl TileWrapper { .id(); tile_storage.set(&position, tile_entity); } + (TileWrapper::Blocked, TilePosType::Full(position)) => { + let tile_entity = parent + .spawn(TileBundle { + position, + tilemap_id, + color: TileColor(BLACK.into()), + ..default() + }) + .id(); + tile_storage.set(&position, tile_entity); + } _ => (), } } @@ -133,15 +153,18 @@ pub(crate) enum TilePosType { pub(crate) type Tilemap = HashMap; /// Contains all relevant tilemaps -pub(crate) struct Tilemaps(pub(crate) HashMap); +pub(crate) struct Tilemaps(pub(crate) HashMap<(i32, TileType), Tilemap>); -impl Default for Tilemaps { - fn default() -> Self { +impl Tilemaps { + pub(crate) fn new(layers: i32) -> Self { let mut map = HashMap::new(); - map.insert(TileType::Full, HashMap::new()); - map.insert(TileType::Half, HashMap::new()); - map.insert(TileType::Animated, HashMap::new()); - map.insert(TileType::Fog, HashMap::new()); + for i in 0..=layers { + map.insert((i, TileType::Full), HashMap::new()); + map.insert((i, TileType::Half), HashMap::new()); + map.insert((i, TileType::Animated), HashMap::new()); + map.insert((i, TileType::Fog), HashMap::new()); + } + map.insert((0, TileType::Blocked), HashMap::new()); Tilemaps(map) } } @@ -185,16 +208,23 @@ impl ToTiles for BlockType { // add its state to the flag flags |= solid << index; } - tilemaps.0.entry(TileType::Half).and_modify(|m| { + tilemaps.0.entry((z, TileType::Half)).and_modify(|m| { m.insert( TilePosType::Half((pos.x, pos.y)), TileWrapper::Half((*self, flags)), ); }); + // Blocks the view of the tile + tilemaps.0.entry((z, TileType::Blocked)).and_modify(|m| { + m.insert( + TilePosType::Full(TilePos::new(pos.x, pos.y)), + TileWrapper::Blocked, + ); + }); true } BlockType::Solid(_) => { - tilemaps.0.entry(TileType::Full).and_modify(|m| { + tilemaps.0.entry((z, TileType::Full)).and_modify(|m| { m.insert( TilePosType::Full(TilePos::new(pos.x, pos.y)), TileWrapper::Full(*self), @@ -203,7 +233,7 @@ impl ToTiles for BlockType { true } BlockType::Liquid => { - tilemaps.0.entry(TileType::Animated).and_modify(|m| { + tilemaps.0.entry((z, TileType::Animated)).and_modify(|m| { m.insert( TilePosType::Full(TilePos::new(pos.x, pos.y)), TileWrapper::Animated, @@ -212,7 +242,7 @@ impl ToTiles for BlockType { true } BlockType::None if z != 0 => { - tilemaps.0.entry(TileType::Fog).and_modify(|m| { + tilemaps.0.entry((z, TileType::Fog)).and_modify(|m| { m.insert( TilePosType::Full(TilePos::new(pos.x, pos.y)), TileWrapper::Fog(z as f32 / visible_layers),