Skip to content

Commit

Permalink
Added map settings.
Browse files Browse the repository at this point in the history
  • Loading branch information
StarArawn authored and StarArawn committed May 3, 2021
1 parent 330cfa2 commit 3ac42b4
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 54 deletions.
4 changes: 2 additions & 2 deletions examples/hex_column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn startup(

let mut map = Map::new(Vec2::new(1.0, 1.0).into(), Vec2::new(64.0, 64.0).into(), Vec2::new(17.0, 15.0), Vec2::new(102.0, 15.0), 0);
// New mesher needs to be applied before chunks are built with map.
map.mesher = Box::new(HexChunkMesher::new(HexType::Column));
map.settings.mesher = Box::new(HexChunkMesher::new(HexType::Column));
let map_entity = commands.spawn().id();
map.build(&mut commands, &mut meshes, material_handle.clone(), map_entity, true);
commands.entity(map_entity).insert_bundle(MapBundle {
Expand All @@ -28,7 +28,7 @@ fn startup(
for z in 0..2 {
let mut map = Map::new(Vec2::new(1.0, 1.0).into(), Vec2::new(64.0, 64.0).into(), Vec2::new(17.0, 15.0), Vec2::new(102.0, 15.0), z + 1);
// New mesher needs to be applied before chunks are built with map.
map.mesher = Box::new(HexChunkMesher::new(HexType::Column));
map.settings.mesher = Box::new(HexChunkMesher::new(HexType::Column));
let map_entity = commands.spawn().id();
map.build(&mut commands, &mut meshes, material_handle.clone(), map_entity, false);

Expand Down
4 changes: 2 additions & 2 deletions examples/hex_row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn startup(

let mut map = Map::new(Vec2::new(1.0, 1.0).into(), Vec2::new(64.0, 64.0).into(), Vec2::new(15.0, 17.0), Vec2::new(105.0, 17.0), 0);
// New mesher needs to be applied before chunks are built with map.
map.mesher = Box::new(HexChunkMesher::new(HexType::Row));
map.settings.mesher = Box::new(HexChunkMesher::new(HexType::Row));
let map_entity = commands.spawn().id();
map.build(&mut commands, &mut meshes, material_handle.clone(), map_entity, true);
commands.entity(map_entity).insert_bundle(MapBundle {
Expand All @@ -28,7 +28,7 @@ fn startup(
for z in 0..2 {
let mut map = Map::new(Vec2::new(1.0, 1.0).into(), Vec2::new(64.0, 64.0).into(), Vec2::new(15.0, 17.0), Vec2::new(105.0, 17.0), z + 1);
// New mesher needs to be applied before chunks are built with map.
map.mesher = Box::new(HexChunkMesher::new(HexType::Row));
map.settings.mesher = Box::new(HexChunkMesher::new(HexType::Row));
let map_entity = commands.spawn().id();
map.build(&mut commands, &mut meshes, material_handle.clone(), map_entity, false);

Expand Down
4 changes: 2 additions & 2 deletions examples/iso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn startup(

// Layer 0
let mut map = Map::new(Vec2::new(2.0, 2.0).into(), Vec2::new(8.0, 8.0).into(), Vec2::new(64.0, 32.0), Vec2::new(640.0, 1024.0), 0);
map.mesher = Box::new(IsoChunkMesher);
map.settings.mesher = Box::new(IsoChunkMesher);
let map_entity = commands.spawn().id();
map.build(&mut commands, &mut meshes, material_handle.clone(), map_entity, false);
for x in 0..16 {
Expand All @@ -38,7 +38,7 @@ fn startup(
// Make 2 layers on "top" of the base map.
for z in 0..2 {
let mut map = Map::new(Vec2::new(2.0, 2.0).into(), Vec2::new(8.0, 8.0).into(), Vec2::new(64.0, 32.0), Vec2::new(640.0, 1024.0), z + 1);
map.mesher = Box::new(IsoChunkMesher);
map.settings.mesher = Box::new(IsoChunkMesher);
let map_entity = commands.spawn().id();
map.build(&mut commands, &mut meshes, material_handle.clone(), map_entity, false);

Expand Down
6 changes: 3 additions & 3 deletions examples/random_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ fn random(
// Smarter way to update..
if did_update {
if let Ok(map) = map_query.single() {
for x in 0..map.size.x {
for y in 0..map.size.y {
for x in 0..map.settings.size.x {
for y in 0..map.settings.size.y {
// Update first tile in each chunk at least until we get an notify_chunk
map.notify(&mut commands, MapVec2::new(x * map.chunk_size.x, y * map.chunk_size.y));
map.notify(&mut commands, MapVec2::new(x * map.settings.chunk_size.x, y * map.settings.chunk_size.y));
}
}
}
Expand Down
20 changes: 11 additions & 9 deletions src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl Default for ChunkBundle {
}
}

#[derive(Debug)]
pub struct ChunkSettings {
pub position: MapVec2,
pub size: MapVec2,
Expand Down Expand Up @@ -106,18 +107,19 @@ impl Default for Chunk {
impl Chunk {
pub(crate) fn new(map_entity: Entity, position: MapVec2, chunk_size: MapVec2, tile_size: Vec2, texture_size: Vec2, mesh_handle: Handle<Mesh>, layer_id: u32, mesher: Box<dyn TilemapChunkMesher>) -> Self {
let tiles = vec![None; chunk_size.x as usize * chunk_size.y as usize];
let settings = ChunkSettings {
position,
size: chunk_size,
tile_size,
texture_size,
mesh_handle,
layer_id,
mesher,
};
Self {
map_entity,
tiles,
settings: ChunkSettings {
position,
size: chunk_size,
tile_size,
texture_size,
mesh_handle,
layer_id,
mesher,
},
settings,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub mod prelude {
pub use crate::tile::Tile;
pub use crate::chunk::Chunk;
pub use crate::map_vec2::MapVec2;
pub use crate::map::{Map, MapBundle, MapTileError, RemoveTile};
pub use crate::map::{Map, MapBundle, MapSettings, MapTileError, RemoveTile};
pub use crate::TileMapPlugin;
pub use crate::mesher::{SquareChunkMesher, IsoChunkMesher, HexChunkMesher, HexType, TilemapChunkMesher};
}
91 changes: 57 additions & 34 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,47 @@ pub struct MapBundle {
pub transform: Transform,
pub global_transform: GlobalTransform,
}

/// TODO: DOCS
pub struct Map {
pub struct MapSettings {
pub size: MapVec2,
pub chunk_size: MapVec2,
pub tile_size: Vec2,
pub texture_size: Vec2,
pub layer_id: u32,
chunks: HashMap<MapVec2, (Entity, Vec<Option<Entity>>)>,
pub mesher: Box<dyn TilemapChunkMesher>,
}

impl Clone for MapSettings {
fn clone(&self) -> Self {
Self {
size: self.size.clone(),
chunk_size: self.chunk_size.clone(),
tile_size: self.tile_size.clone(),
texture_size: self.texture_size.clone(),
layer_id: self.layer_id.clone(),
mesher: dyn_clone::clone_box(&*self.mesher),
}
}
}

/// TODO: DOCS
pub struct Map {
pub settings: MapSettings,
chunks: HashMap<MapVec2, (Entity, Vec<Option<Entity>>)>,
events: VecDeque<SetTileEvent>
}

impl Default for Map {
fn default() -> Self {
Self {
size: MapVec2::default(),
chunk_size: MapVec2::default(),
tile_size: Vec2::default(),
texture_size: Vec2::default(),
layer_id: 0,
settings: MapSettings {
size: MapVec2::default(),
chunk_size: MapVec2::default(),
tile_size: Vec2::default(),
texture_size: Vec2::default(),
layer_id: 0,
mesher: Box::new(SquareChunkMesher),
},
chunks: HashMap::new(),
mesher: Box::new(SquareChunkMesher),
events: VecDeque::new(),
}
}
Expand All @@ -55,13 +73,15 @@ impl Map {
/// TODO: DOCS
pub fn new(size: MapVec2, chunk_size: MapVec2, tile_size: Vec2, texture_size: Vec2, layer_id: u32) -> Self {
Self {
size,
chunk_size,
tile_size,
texture_size,
layer_id,
settings: MapSettings {
size,
chunk_size,
tile_size,
texture_size,
layer_id,
mesher: Box::new(SquareChunkMesher),
},
chunks: HashMap::with_capacity((size.x * size.y) as usize),
mesher: Box::new(SquareChunkMesher),
events: VecDeque::new(),
}
}
Expand All @@ -81,10 +101,10 @@ impl Map {
let mut possible_tile_event = None;

let chunk_pos = MapVec2::new(
tile_pos.x / self.chunk_size.x,
tile_pos.y / self.chunk_size.y
tile_pos.x / self.settings.chunk_size.x,
tile_pos.y / self.settings.chunk_size.y
);
let chunk_size = self.chunk_size;
let chunk_size = self.settings.chunk_size;
if let Some(chunk_data) = self.get_chunk_mut(chunk_pos) {
let chunk_tile_pos = MapVec2::new(
tile_pos.x - (chunk_pos.x * chunk_size.x),
Expand Down Expand Up @@ -138,8 +158,8 @@ impl Map {
/// Note: This just adds a Tag to the chunk entity to be re-meshed.
pub fn notify(&self, commands: &mut Commands, position: MapVec2) {
if let Some(chunk_data) = self.get_chunk(MapVec2::new(
position.x / self.chunk_size.x,
position.y / self.chunk_size.y
position.x / self.settings.chunk_size.x,
position.y / self.settings.chunk_size.y
)) {
commands.entity(chunk_data.0).insert(RemeshChunk);
}
Expand Down Expand Up @@ -184,12 +204,12 @@ impl Map {
let map_size = &self.get_map_size_in_tiles();
if tile_pos.x >= 0 && tile_pos.y >= 0 && tile_pos.x <= map_size.x && tile_pos.y <= map_size.y {
let chunk_pos = MapVec2::new(
tile_pos.x / self.chunk_size.x,
tile_pos.y / self.chunk_size.y,
tile_pos.x / self.settings.chunk_size.x,
tile_pos.y / self.settings.chunk_size.y,
);
let chunk_tile_pos = MapVec2::new(
tile_pos.x - (chunk_pos.x * self.chunk_size.x),
tile_pos.y - (chunk_pos.y * self.chunk_size.y),
tile_pos.x - (chunk_pos.x * self.settings.chunk_size.x),
tile_pos.y - (chunk_pos.y * self.settings.chunk_size.y),
);

let chunk = self.chunks.get(&chunk_pos);
Expand All @@ -212,8 +232,8 @@ impl Map {
tiles.1.iter().enumerate().map(|(index, entity)| {
let chunk_tile_pos = MapVec2::from_morton(index);
let global_tile_pos = MapVec2::new(
chunk_tile_pos.x + (chunk_pos.x * self.chunk_size.x),
chunk_tile_pos.y + (chunk_pos.y * self.chunk_size.y),
chunk_tile_pos.x + (chunk_pos.x * self.settings.chunk_size.x),
chunk_tile_pos.y + (chunk_pos.y * self.settings.chunk_size.y),
);
(global_tile_pos, entity)
}).collect::<Vec<(MapVec2, &Option<Entity>)>>()
Expand All @@ -223,8 +243,8 @@ impl Map {
/// Gets the map's size in tiles just for convenience.
pub fn get_map_size_in_tiles(&self) -> MapVec2 {
MapVec2::new(
self.size.x * self.chunk_size.x,
self.size.y * self.chunk_size.y,
self.settings.size.x * self.settings.chunk_size.x,
self.settings.size.y * self.settings.chunk_size.y,
)
}

Expand All @@ -238,8 +258,8 @@ impl Map {
map_entity: Entity,
populate_chunks: bool,
) {
for x in 0..self.size.x {
for y in 0..self.size.y {
for x in 0..self.settings.size.x {
for y in 0..self.settings.size.y {
let mut chunk_entity = None;
commands.entity(map_entity).with_children(|child_builder| {
chunk_entity = Some(child_builder.spawn().id());
Expand All @@ -253,7 +273,7 @@ impl Map {
mesh.set_attribute("Vertex_Uv", VertexAttributeValues::Float2(vec![]));
mesh.set_indices(Some(Indices::U32(vec![])));
let mesh_handle = meshes.add(mesh);
let mut chunk = Chunk::new(map_entity, chunk_pos, self.chunk_size, self.tile_size, self.texture_size, mesh_handle.clone(), self.layer_id, dyn_clone::clone_box(&*self.mesher));
let mut chunk = Chunk::new(map_entity, chunk_pos, self.settings.chunk_size, self.settings.tile_size, self.settings.texture_size, mesh_handle.clone(), self.settings.layer_id, dyn_clone::clone_box(&*self.settings.mesher));

if populate_chunks {
chunk.build_tiles(commands, chunk_entity);
Expand All @@ -279,6 +299,9 @@ pub(crate) fn update_chunk_hashmap_for_added_tiles(
mut chunk_query: Query<&mut Chunk>,
tile_query: Query<(Entity, &Tile, &MapVec2), Added<Tile>>,
) {
if tile_query.iter().count() > 0 {
log::info!("Updating tile cache.");
}
for (tile_entity, new_tile, tile_pos) in tile_query.iter() {
if let Ok(mut chunk) = chunk_query.get_mut(new_tile.chunk) {
let tile_pos = chunk.to_chunk_pos(*tile_pos);
Expand All @@ -305,8 +328,8 @@ pub(crate) fn update_chunk_hashmap_for_removed_tiles(
}

let chunk_coords = MapVec2::new(
tile_pos.x / map.chunk_size.x,
tile_pos.y / map.chunk_size.y,
tile_pos.x / map.settings.chunk_size.x,
tile_pos.y / map.settings.chunk_size.y,
);

// Remove tile from map tiles cache.
Expand Down
2 changes: 1 addition & 1 deletion src/mesher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{chunk::ChunkSettings, morton_index, prelude::*};

/// TODO: DOCS
#[async_trait]
pub trait TilemapChunkMesher : Component + DynClone {
pub trait TilemapChunkMesher : Component + DynClone + std::fmt::Debug {
async fn mesh(self: Box<Self>, chunk: ChunkSettings, tile_query: Vec<Option<Tile>>) -> (Handle<Mesh>, Mesh);
}

Expand Down

0 comments on commit 3ac42b4

Please sign in to comment.