From 62bd6b2c7c5fb825ab5a837b5cb008513bde9aca Mon Sep 17 00:00:00 2001 From: crumblingstatue Date: Sun, 2 Apr 2023 11:53:54 +0200 Subject: [PATCH] Fix local tile offset calculation for large coordinates --- src/app.rs | 8 +++-- src/game.rs | 8 ++--- src/world.rs | 100 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 79 insertions(+), 37 deletions(-) diff --git a/src/app.rs b/src/app.rs index b683698..f16e7f0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,5 @@ use egui_sfml::{egui, SfEgui}; -use gamedebug_core::imm; +use gamedebug_core::imm_dbg; use sfml::{ graphics::{Color, RenderTarget, RenderWindow}, 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) { self.rw.clear(Color::BLACK); diff --git a/src/game.rs b/src/game.rs index 906643c..1cd2380 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,9 +1,8 @@ -use gamedebug_core::imm_dbg; use sfml::graphics::{Rect, RenderTarget, RenderWindow, Sprite, Transformable}; use crate::{ graphics::{ScreenPos, NATIVE_RESOLUTION}, - math::{WorldPos, WorldPosScalar, TILE_SIZE}, + math::WorldPos, res::Res, 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, }, ScreenPos { - x: imm_dbg!(imm_dbg!(x as i32) - (imm_dbg!(camera_offset.x as i32)) % 32) - as i16, - y: (y as i32 - (camera_offset.y as i32 % 32)) as i16, + x: (x as i32 - camera_offset.x % 32) as i16, + y: (y as i32 - (camera_offset.y % 32)) as i16, }, ) } diff --git a/src/world.rs b/src/world.rs index 7682ee8..157f447 100644 --- a/src/world.rs +++ b/src/world.rs @@ -4,7 +4,7 @@ use rand::{thread_rng, Rng}; type ChunkPosScalar = i16; #[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)] -struct ChunkPos { +pub struct ChunkPos { x: ChunkPosScalar, y: ChunkPosScalar, } @@ -33,50 +33,78 @@ impl World { } } +#[derive(Debug, Clone, Copy)] pub struct TilePos { pub x: TilePosScalar, pub y: TilePosScalar, } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Clone, Copy)] pub struct ChunkLocalTilePos { pub x: ChunkLocalTilePosScalar, pub y: ChunkLocalTilePosScalar, } -type ChunkLocalTilePosScalar = i16; +type ChunkLocalTilePosScalar = u8; impl TilePos { - fn to_chunk_and_local(&self) -> (ChunkPos, ChunkLocalTilePos) { - // 0,0 is chunk (0, 0) - // -1, -1 is chunk (-1, -1) - // 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, + pub fn to_chunk_and_local(self) -> (ChunkPos, ChunkLocalTilePos) { + let chk = ChunkPos { + x: chk_pos(self.x), + y: chk_pos(self.y), }; - if self.x.is_negative() { - chk.x -= 1; - } - if self.y.is_negative() { - chk.y -= 1; - } let local = ChunkLocalTilePos { - 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 - }, + x: chunk_local(self.x), + y: chunk_local(self.y), }; (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] fn test_to_chunk_and_local() { assert_eq!( @@ -91,10 +119,22 @@ fn test_to_chunk_and_local() { 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 - } + ChunkLocalTilePos { x: 127, y: 127 } + ) + ); + 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 } ) ); }