mirror of
https://github.com/Noratrieb/game-wip-dontplay.git
synced 2026-01-17 04:45:02 +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 {
|
pub struct GameState {
|
||||||
camera_offset: WorldPos,
|
camera_offset: WorldPos,
|
||||||
|
|
@ -8,7 +13,33 @@ pub struct GameState {
|
||||||
}
|
}
|
||||||
impl GameState {
|
impl GameState {
|
||||||
pub(crate) fn draw_world(&mut self, rw: &mut RenderWindow, res: &Res) {
|
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::{
|
use sfml::{
|
||||||
graphics::RenderWindow,
|
graphics::RenderWindow,
|
||||||
|
system::Vector2f,
|
||||||
window::{ContextSettings, Style, VideoMode},
|
window::{ContextSettings, Style, VideoMode},
|
||||||
};
|
};
|
||||||
use sfml_xt::graphics::RenderWindowExt;
|
use sfml_xt::graphics::RenderWindowExt;
|
||||||
|
|
||||||
struct ScreenRes {
|
pub struct ScreenRes {
|
||||||
w: u16,
|
pub w: u16,
|
||||||
h: u16,
|
pub h: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenRes {
|
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 {
|
pub fn make_window() -> RenderWindow {
|
||||||
let mut rw = RenderWindow::new(
|
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;
|
pub type WorldPosScalar = i32;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct WorldPos {
|
pub struct WorldPos {
|
||||||
pub x: WorldPosScalar,
|
pub x: WorldPosScalar,
|
||||||
pub y: 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;
|
type ChunkPosScalar = i16;
|
||||||
|
|
||||||
#[derive(Hash)]
|
#[derive(Hash, PartialEq, Eq)]
|
||||||
struct ChunkPos {
|
struct ChunkPos {
|
||||||
x: ChunkPosScalar,
|
x: ChunkPosScalar,
|
||||||
y: ChunkPosScalar,
|
y: ChunkPosScalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct World {
|
pub struct World {
|
||||||
|
/// The currently loaded chunks
|
||||||
chunks: FnvHashMap<ChunkPos, Chunk>,
|
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_EXTENT: u16 = 256;
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -35,15 +78,19 @@ impl Chunk {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let mut tiles = [Tile { id: 0 }; CHUNK_N_TILES];
|
let mut tiles = [Tile { id: 0 }; CHUNK_N_TILES];
|
||||||
for b in &mut tiles {
|
for b in &mut tiles {
|
||||||
b.id = rng.gen();
|
b.id = rng.gen_range(0..8);
|
||||||
}
|
}
|
||||||
Self { tiles }
|
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;
|
type TileId = u16;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Tile {
|
pub struct Tile {
|
||||||
id: TileId,
|
pub id: TileId,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue