Take into account negative coords in chunk offset calculations

This commit is contained in:
crumblingstatue 2023-04-02 10:21:57 +02:00
parent 49c47ac718
commit 38699c9d09
2 changed files with 46 additions and 8 deletions

View file

@ -25,8 +25,8 @@ impl GameState {
} }
fn for_each_tile(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) { fn for_each_tile(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) {
for y in (0..NATIVE_RESOLUTION.h).step_by(32) { for y in (-32..NATIVE_RESOLUTION.h + 32).step_by(32) {
for x in (0..NATIVE_RESOLUTION.w).step_by(32) { for x in (-32..NATIVE_RESOLUTION.w + 32).step_by(32) {
f( f(
TilePos { TilePos {
x: (camera_offset.x + x as i32) / 32, x: (camera_offset.x + x as i32) / 32,

View file

@ -3,7 +3,7 @@ use rand::{thread_rng, Rng};
type ChunkPosScalar = i16; type ChunkPosScalar = i16;
#[derive(Hash, PartialEq, Eq)] #[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
struct ChunkPos { struct ChunkPos {
x: ChunkPosScalar, x: ChunkPosScalar,
y: ChunkPosScalar, y: ChunkPosScalar,
@ -38,6 +38,7 @@ pub struct TilePos {
pub y: TilePosScalar, pub y: TilePosScalar,
} }
#[derive(Debug, PartialEq, Eq)]
pub struct ChunkLocalTilePos { pub struct ChunkLocalTilePos {
pub x: ChunkLocalTilePosScalar, pub x: ChunkLocalTilePosScalar,
pub y: ChunkLocalTilePosScalar, pub y: ChunkLocalTilePosScalar,
@ -49,22 +50,59 @@ impl TilePos {
fn to_chunk_and_local(&self) -> (ChunkPos, ChunkLocalTilePos) { fn to_chunk_and_local(&self) -> (ChunkPos, ChunkLocalTilePos) {
// 0,0 is chunk (0, 0) // 0,0 is chunk (0, 0)
// -1, -1 is chunk (-1, -1) // -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, x: (self.x / CHUNK_EXTENT as i32) as i16,
y: (self.y / 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 { let local = ChunkLocalTilePos {
x: (self.x % CHUNK_EXTENT as i32) as i16, x: if chk.x.is_negative() {
y: (self.y % CHUNK_EXTENT as i32) as i16, ((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) (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; 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; const CHUNK_N_TILES: usize = CHUNK_EXTENT as usize * CHUNK_EXTENT as usize;
type ChunkTiles = [Tile; CHUNK_N_TILES]; type ChunkTiles = [Tile; CHUNK_N_TILES];