diff --git a/src/game.rs b/src/game.rs index ad1e6f2..906643c 100644 --- a/src/game.rs +++ b/src/game.rs @@ -25,8 +25,8 @@ impl GameState { } fn for_each_tile(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) { - for y in (0..NATIVE_RESOLUTION.h).step_by(32) { - for x in (0..NATIVE_RESOLUTION.w).step_by(32) { + for y in (-32..NATIVE_RESOLUTION.h + 32).step_by(32) { + for x in (-32..NATIVE_RESOLUTION.w + 32).step_by(32) { f( TilePos { x: (camera_offset.x + x as i32) / 32, diff --git a/src/world.rs b/src/world.rs index 0601c7c..7682ee8 100644 --- a/src/world.rs +++ b/src/world.rs @@ -3,7 +3,7 @@ use rand::{thread_rng, Rng}; type ChunkPosScalar = i16; -#[derive(Hash, PartialEq, Eq)] +#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)] struct ChunkPos { x: ChunkPosScalar, y: ChunkPosScalar, @@ -38,6 +38,7 @@ pub struct TilePos { pub y: TilePosScalar, } +#[derive(Debug, PartialEq, Eq)] pub struct ChunkLocalTilePos { pub x: ChunkLocalTilePosScalar, pub y: ChunkLocalTilePosScalar, @@ -49,22 +50,59 @@ impl TilePos { fn to_chunk_and_local(&self) -> (ChunkPos, ChunkLocalTilePos) { // 0,0 is chunk (0, 0) // -1, -1 is chunk (-1, -1) - let chk = ChunkPos { + // For negative offsets, local offset starts from `CHUNK_EXTENT` + let mut chk = ChunkPos { x: (self.x / CHUNK_EXTENT as i32) as i16, y: (self.y / CHUNK_EXTENT as i32) as i16, }; + if self.x.is_negative() { + chk.x -= 1; + } + if self.y.is_negative() { + chk.y -= 1; + } let local = ChunkLocalTilePos { - x: (self.x % CHUNK_EXTENT as i32) as i16, - y: (self.y % CHUNK_EXTENT as i32) as i16, + x: if chk.x.is_negative() { + ((CHUNK_EXTENT as i32 + self.x) % CHUNK_EXTENT as i32) as i16 + } else { + (self.x % CHUNK_EXTENT as i32) as i16 + }, + y: if chk.y.is_negative() { + ((CHUNK_EXTENT as i32 + self.y) % CHUNK_EXTENT as i32) as i16 + } else { + (self.y % CHUNK_EXTENT as i32) as i16 + }, }; (chk, local) } } -// Need to support at least 8 million tiles long +#[test] +fn test_to_chunk_and_local() { + assert_eq!( + TilePos { x: 0, y: 0 }.to_chunk_and_local(), + (ChunkPos { x: 0, y: 0 }, ChunkLocalTilePos { x: 0, y: 0 }) + ); + assert_eq!( + TilePos { x: 1, y: 1 }.to_chunk_and_local(), + (ChunkPos { x: 0, y: 0 }, ChunkLocalTilePos { x: 1, y: 1 }) + ); + assert_eq!( + TilePos { x: -1, y: -1 }.to_chunk_and_local(), + ( + ChunkPos { x: -1, y: -1 }, + ChunkLocalTilePos { + x: CHUNK_EXTENT as i16 - 1, + y: CHUNK_EXTENT as i16 - 1 + } + ) + ); +} + +// Need to support at least 4 million tiles long type TilePosScalar = i32; -const CHUNK_EXTENT: u16 = 256; +const CHUNK_EXTENT: u16 = 128; const CHUNK_N_TILES: usize = CHUNK_EXTENT as usize * CHUNK_EXTENT as usize; type ChunkTiles = [Tile; CHUNK_N_TILES];