Render some tiles

This commit is contained in:
crumblingstatue 2023-04-01 23:43:46 +02:00
parent 7a3018c2b1
commit 5e539d668f
5 changed files with 115 additions and 10 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Before After
Before After

View file

@ -1,6 +1,11 @@
use sfml::graphics::{RenderTarget, RenderWindow, Sprite};
use sfml::graphics::{Rect, RenderTarget, RenderWindow, Sprite, Transformable};
use crate::{math::WorldPos, res::Res, world::World};
use crate::{
graphics::{ScreenPos, NATIVE_RESOLUTION},
math::{WorldPos, WorldPosScalar, TILE_SIZE},
res::Res,
world::{TilePos, World},
};
pub struct GameState {
camera_offset: WorldPos,
@ -8,7 +13,33 @@ pub struct GameState {
}
impl GameState {
pub(crate) fn draw_world(&mut self, rw: &mut RenderWindow, res: &Res) {
rw.draw(&Sprite::with_texture(&res.tile_atlas));
let mut s = Sprite::with_texture(&res.tile_atlas);
for_each_tile(self.camera_offset, |tp, sp| {
let tile = self.world.tile_at_mut(tp);
s.set_texture_rect(Rect::new(tile.id as i32 * 32, 0, 32, 32));
s.set_position(sp.to_sf_vec());
rw.draw(&s);
});
}
}
fn for_each_tile(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) {
for y in (camera_offset.y..camera_offset.y + NATIVE_RESOLUTION.h as WorldPosScalar).step_by(32)
{
for x in
(camera_offset.x..camera_offset.x + NATIVE_RESOLUTION.w as WorldPosScalar).step_by(32)
{
f(
TilePos {
x: x / 32,
y: y / 32,
},
ScreenPos {
x: (x - camera_offset.x) as i16,
y: (y - camera_offset.y) as i16,
},
)
}
}
}

View file

@ -1,12 +1,13 @@
use sfml::{
graphics::RenderWindow,
system::Vector2f,
window::{ContextSettings, Style, VideoMode},
};
use sfml_xt::graphics::RenderWindowExt;
struct ScreenRes {
w: u16,
h: u16,
pub struct ScreenRes {
pub w: u16,
pub h: u16,
}
impl ScreenRes {
@ -19,7 +20,19 @@ impl ScreenRes {
}
}
const NATIVE_RESOLUTION: ScreenRes = ScreenRes { w: 640, h: 360 };
// We assume this game won't be played above 32767*32767 resolution
pub struct ScreenPos {
pub x: i16,
pub y: i16,
}
impl ScreenPos {
pub fn to_sf_vec(&self) -> Vector2f {
Vector2f::new(self.x.into(), self.y.into())
}
}
pub const NATIVE_RESOLUTION: ScreenRes = ScreenRes { w: 960, h: 540 };
pub fn make_window() -> RenderWindow {
let mut rw = RenderWindow::new(

View file

@ -1,6 +1,20 @@
use crate::world::TilePos;
pub type WorldPosScalar = i32;
#[derive(Clone, Copy)]
pub struct WorldPos {
pub x: WorldPosScalar,
pub y: WorldPosScalar,
}
impl WorldPos {
pub fn tile_pos(&self) -> TilePos {
TilePos {
x: self.x / TILE_SIZE as i32,
y: self.y / TILE_SIZE as i32,
}
}
}
pub const TILE_SIZE: u8 = 32;

View file

@ -3,13 +3,14 @@ use rand::{thread_rng, Rng};
type ChunkPosScalar = i16;
#[derive(Hash)]
#[derive(Hash, PartialEq, Eq)]
struct ChunkPos {
x: ChunkPosScalar,
y: ChunkPosScalar,
}
pub struct World {
/// The currently loaded chunks
chunks: FnvHashMap<ChunkPos, Chunk>,
}
@ -21,6 +22,48 @@ impl Default for World {
}
}
impl World {
/// Get mutable access to the tile at `pos`.
///
/// Loads or generates the containing chunk if necessary.
pub fn tile_at_mut(&mut self, pos: TilePos) -> &mut Tile {
let (chk, local) = pos.to_chunk_and_local();
let chk = self.chunks.entry(chk).or_insert_with(Chunk::new_rand);
chk.at_mut(local)
}
}
pub struct TilePos {
pub x: TilePosScalar,
pub y: TilePosScalar,
}
pub struct ChunkLocalTilePos {
pub x: ChunkLocalTilePosScalar,
pub y: ChunkLocalTilePosScalar,
}
type ChunkLocalTilePosScalar = i16;
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 {
x: (self.x / CHUNK_EXTENT as i32) as i16,
y: (self.y / CHUNK_EXTENT as i32) as i16,
};
let local = ChunkLocalTilePos {
x: (self.x % CHUNK_EXTENT as i32) as i16,
y: (self.y % CHUNK_EXTENT as i32) as i16,
};
(chk, local)
}
}
// Need to support at least 8 million tiles long
type TilePosScalar = i32;
const CHUNK_EXTENT: u16 = 256;
const CHUNK_N_TILES: usize = CHUNK_EXTENT as usize * CHUNK_EXTENT as usize;
@ -35,15 +78,19 @@ impl Chunk {
let mut rng = thread_rng();
let mut tiles = [Tile { id: 0 }; CHUNK_N_TILES];
for b in &mut tiles {
b.id = rng.gen();
b.id = rng.gen_range(0..8);
}
Self { tiles }
}
fn at_mut(&mut self, local: ChunkLocalTilePos) -> &mut Tile {
&mut self.tiles[CHUNK_EXTENT as usize * local.y as usize + local.x as usize]
}
}
type TileId = u16;
#[derive(Clone, Copy)]
pub struct Tile {
id: TileId,
pub id: TileId,
}