Fix local tile offset calculation for large coordinates

This commit is contained in:
crumblingstatue 2023-04-02 11:53:54 +02:00
parent 38699c9d09
commit 62bd6b2c7c
3 changed files with 79 additions and 37 deletions

View file

@ -1,5 +1,5 @@
use egui_sfml::{egui, SfEgui}; use egui_sfml::{egui, SfEgui};
use gamedebug_core::imm; use gamedebug_core::imm_dbg;
use sfml::{ use sfml::{
graphics::{Color, RenderTarget, RenderWindow}, graphics::{Color, RenderTarget, RenderWindow},
window::Event, window::Event,
@ -48,7 +48,11 @@ impl App {
} }
} }
fn do_update(&mut self) {} fn do_update(&mut self) {
let tp = self.game.camera_offset.tile_pos();
imm_dbg!(tp);
imm_dbg!(tp.to_chunk_and_local());
}
fn do_rendering(&mut self) { fn do_rendering(&mut self) {
self.rw.clear(Color::BLACK); self.rw.clear(Color::BLACK);

View file

@ -1,9 +1,8 @@
use gamedebug_core::imm_dbg;
use sfml::graphics::{Rect, RenderTarget, RenderWindow, Sprite, Transformable}; use sfml::graphics::{Rect, RenderTarget, RenderWindow, Sprite, Transformable};
use crate::{ use crate::{
graphics::{ScreenPos, NATIVE_RESOLUTION}, graphics::{ScreenPos, NATIVE_RESOLUTION},
math::{WorldPos, WorldPosScalar, TILE_SIZE}, math::WorldPos,
res::Res, res::Res,
world::{TilePos, World}, world::{TilePos, World},
}; };
@ -33,9 +32,8 @@ fn for_each_tile(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos))
y: (camera_offset.y + y as i32) / 32, y: (camera_offset.y + y as i32) / 32,
}, },
ScreenPos { ScreenPos {
x: imm_dbg!(imm_dbg!(x as i32) - (imm_dbg!(camera_offset.x as i32)) % 32) x: (x as i32 - camera_offset.x % 32) as i16,
as i16, y: (y as i32 - (camera_offset.y % 32)) as i16,
y: (y as i32 - (camera_offset.y as i32 % 32)) as i16,
}, },
) )
} }

View file

@ -4,7 +4,7 @@ use rand::{thread_rng, Rng};
type ChunkPosScalar = i16; type ChunkPosScalar = i16;
#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)] #[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
struct ChunkPos { pub struct ChunkPos {
x: ChunkPosScalar, x: ChunkPosScalar,
y: ChunkPosScalar, y: ChunkPosScalar,
} }
@ -33,50 +33,78 @@ impl World {
} }
} }
#[derive(Debug, Clone, Copy)]
pub struct TilePos { pub struct TilePos {
pub x: TilePosScalar, pub x: TilePosScalar,
pub y: TilePosScalar, pub y: TilePosScalar,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct ChunkLocalTilePos { pub struct ChunkLocalTilePos {
pub x: ChunkLocalTilePosScalar, pub x: ChunkLocalTilePosScalar,
pub y: ChunkLocalTilePosScalar, pub y: ChunkLocalTilePosScalar,
} }
type ChunkLocalTilePosScalar = i16; type ChunkLocalTilePosScalar = u8;
impl TilePos { impl TilePos {
fn to_chunk_and_local(&self) -> (ChunkPos, ChunkLocalTilePos) { pub fn to_chunk_and_local(self) -> (ChunkPos, ChunkLocalTilePos) {
// 0,0 is chunk (0, 0) let chk = ChunkPos {
// -1, -1 is chunk (-1, -1) x: chk_pos(self.x),
// For negative offsets, local offset starts from `CHUNK_EXTENT` y: chk_pos(self.y),
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 { let local = ChunkLocalTilePos {
x: if chk.x.is_negative() { x: chunk_local(self.x),
((CHUNK_EXTENT as i32 + self.x) % CHUNK_EXTENT as i32) as i16 y: chunk_local(self.y),
} 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)
} }
} }
fn chk_pos(tile: TilePosScalar) -> ChunkPosScalar {
if tile.is_negative() {
((tile + 1) / CHUNK_EXTENT as i32) as i16 - 1
} else {
(tile / CHUNK_EXTENT as i32) as i16
}
}
#[test]
fn test_chk_pos() {
assert_eq!(chk_pos(0), 0);
assert_eq!(chk_pos(1), 0);
assert_eq!(chk_pos(127), 0);
assert_eq!(chk_pos(128), 1);
assert_eq!(chk_pos(-1), -1);
assert_eq!(chk_pos(-2), -1);
assert_eq!(chk_pos(-127), -1);
assert_eq!(chk_pos(-128), -1);
assert_eq!(chk_pos(-129), -2);
}
/*fn chunk_local(global: TilePosScalar) -> ChunkLocalTilePosScalar {
if global.is_negative() {
(CHUNK_EXTENT as i32 + global % CHUNK_EXTENT as i32) as u8
} else {
(global % CHUNK_EXTENT as i32) as u8
}
}*/
fn chunk_local(global: TilePosScalar) -> ChunkLocalTilePosScalar {
let mut result = global % CHUNK_EXTENT as i32;
if result.is_negative() {
result += CHUNK_EXTENT as i32;
}
result as u8
}
#[test]
fn test_chunk_local() {
assert_eq!(chunk_local(0), 0);
assert_eq!(chunk_local(-1), 127);
assert_eq!(chunk_local(-128), 0);
}
#[test] #[test]
fn test_to_chunk_and_local() { fn test_to_chunk_and_local() {
assert_eq!( assert_eq!(
@ -91,10 +119,22 @@ fn test_to_chunk_and_local() {
TilePos { x: -1, y: -1 }.to_chunk_and_local(), TilePos { x: -1, y: -1 }.to_chunk_and_local(),
( (
ChunkPos { x: -1, y: -1 }, ChunkPos { x: -1, y: -1 },
ChunkLocalTilePos { ChunkLocalTilePos { x: 127, y: 127 }
x: CHUNK_EXTENT as i16 - 1, )
y: CHUNK_EXTENT as i16 - 1 );
} assert_eq!(
TilePos { x: -127, y: -127 }.to_chunk_and_local(),
(ChunkPos { x: -1, y: -1 }, ChunkLocalTilePos { x: 1, y: 1 })
);
assert_eq!(
TilePos { x: -128, y: -128 }.to_chunk_and_local(),
(ChunkPos { x: -1, y: -1 }, ChunkLocalTilePos { x: 0, y: 0 })
);
assert_eq!(
TilePos { x: -129, y: -129 }.to_chunk_and_local(),
(
ChunkPos { x: -2, y: -2 },
ChunkLocalTilePos { x: 127, y: 127 }
) )
); );
} }