mirror of
https://github.com/Noratrieb/game-wip-dontplay.git
synced 2026-01-14 11:45:01 +01:00
Render some tiles
This commit is contained in:
parent
7a3018c2b1
commit
5e539d668f
5 changed files with 115 additions and 10 deletions
BIN
res/tiles.png
BIN
res/tiles.png
Binary file not shown.
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.8 KiB |
37
src/game.rs
37
src/game.rs
|
|
@ -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,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
14
src/math.rs
14
src/math.rs
|
|
@ -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;
|
||||
|
|
|
|||
53
src/world.rs
53
src/world.rs
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue