mirror of
https://github.com/Noratrieb/game-wip-dontplay.git
synced 2026-01-17 04:45:02 +01:00
Add very crude proof-of-concept worldgen
This commit is contained in:
parent
314d2eafa0
commit
930f7aac47
7 changed files with 109 additions and 27 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -546,6 +546,7 @@ dependencies = [
|
||||||
"s2dc",
|
"s2dc",
|
||||||
"sfml",
|
"sfml",
|
||||||
"sfml-xt",
|
"sfml-xt",
|
||||||
|
"worldgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1159,3 +1160,9 @@ checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "worldgen"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9b77fba24c873b60af296c1f0c5639114186d1ac3c99f880a7bb590bdc04065"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ hecs = "0.10.1"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
rfd = "0.11.3"
|
rfd = "0.11.3"
|
||||||
sfml = "0.20.0"
|
sfml = "0.20.0"
|
||||||
|
worldgen = "0.5.3"
|
||||||
|
|
||||||
[dependencies.s2dc]
|
[dependencies.s2dc]
|
||||||
git = "https://github.com/crumblingstatue/s2dc.git"
|
git = "https://github.com/crumblingstatue/s2dc.git"
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ impl App {
|
||||||
.clamp(-terminal_velocity, terminal_velocity);
|
.clamp(-terminal_velocity, terminal_velocity);
|
||||||
let mut on_screen_tile_ents = Vec::new();
|
let mut on_screen_tile_ents = Vec::new();
|
||||||
for_each_tile_on_screen(self.game.camera_offset, |tp, _sp| {
|
for_each_tile_on_screen(self.game.camera_offset, |tp, _sp| {
|
||||||
let tid = self.game.world.tile_at_mut(tp).mid;
|
let tid = self.game.world.tile_at_mut(tp, &self.game.worldgen).mid;
|
||||||
if tid == Tile::EMPTY {
|
if tid == Tile::EMPTY {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -163,11 +163,11 @@ impl App {
|
||||||
self.game.player.col_en.en.pos.y = wpos.y as i32;
|
self.game.player.col_en.en.pos.y = wpos.y as i32;
|
||||||
}
|
}
|
||||||
if self.input.lmb_down {
|
if self.input.lmb_down {
|
||||||
let t = self.game.world.tile_at_mut(mouse_tpos);
|
let t = self.game.world.tile_at_mut(mouse_tpos, &self.game.worldgen);
|
||||||
t.mid = 0;
|
t.mid = 0;
|
||||||
t.fg = 0;
|
t.fg = 0;
|
||||||
} else if self.input.rmb_down {
|
} else if self.input.rmb_down {
|
||||||
let t = self.game.world.tile_at_mut(mouse_tpos);
|
let t = self.game.world.tile_at_mut(mouse_tpos, &self.game.worldgen);
|
||||||
if self.game.tile_to_place != 7 {
|
if self.game.tile_to_place != 7 {
|
||||||
t.mid = self.game.tile_to_place;
|
t.mid = self.game.tile_to_place;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
math::{wp_to_tp, WorldPos},
|
math::{wp_to_tp, WorldPos},
|
||||||
res::Res,
|
res::Res,
|
||||||
world::{Tile, TileId, TilePos, World},
|
world::{Tile, TileId, TilePos, World},
|
||||||
|
worldgen::Worldgen,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::player::Player;
|
use self::player::Player;
|
||||||
|
|
@ -21,6 +22,7 @@ pub struct GameState {
|
||||||
pub tile_to_place: TileId,
|
pub tile_to_place: TileId,
|
||||||
pub current_biome: Biome,
|
pub current_biome: Biome,
|
||||||
pub prev_biome: Biome,
|
pub prev_biome: Biome,
|
||||||
|
pub worldgen: Worldgen,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
|
|
@ -33,7 +35,7 @@ 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) {
|
||||||
let mut s = Sprite::with_texture(&res.tile_atlas);
|
let mut s = Sprite::with_texture(&res.tile_atlas);
|
||||||
for_each_tile_on_screen(self.camera_offset, |tp, sp| {
|
for_each_tile_on_screen(self.camera_offset, |tp, sp| {
|
||||||
let tile = self.world.tile_at_mut(tp);
|
let tile = self.world.tile_at_mut(tp, &self.worldgen);
|
||||||
s.set_position(sp.to_sf_vec());
|
s.set_position(sp.to_sf_vec());
|
||||||
if tile.bg != Tile::EMPTY {
|
if tile.bg != Tile::EMPTY {
|
||||||
s.set_texture_rect(Rect::new((tile.bg - 1) as i32 * 32, 0, 32, 32));
|
s.set_texture_rect(Rect::new((tile.bg - 1) as i32 * 32, 0, 32, 32));
|
||||||
|
|
@ -97,6 +99,7 @@ impl Default for GameState {
|
||||||
tile_to_place: 1,
|
tile_to_place: 1,
|
||||||
current_biome: Biome::Surface,
|
current_biome: Biome::Surface,
|
||||||
prev_biome: Biome::Surface,
|
prev_biome: Biome::Surface,
|
||||||
|
worldgen: Worldgen::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ mod input;
|
||||||
mod math;
|
mod math;
|
||||||
mod res;
|
mod res;
|
||||||
mod world;
|
mod world;
|
||||||
|
mod worldgen;
|
||||||
|
|
||||||
use app::App;
|
use app::App;
|
||||||
|
|
||||||
|
|
|
||||||
40
src/world.rs
40
src/world.rs
|
|
@ -1,12 +1,13 @@
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use rand::{thread_rng, Rng};
|
|
||||||
|
use crate::worldgen::Worldgen;
|
||||||
|
|
||||||
pub type ChunkPosScalar = u16;
|
pub type ChunkPosScalar = u16;
|
||||||
|
|
||||||
#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
|
#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
|
||||||
pub struct ChunkPos {
|
pub struct ChunkPos {
|
||||||
x: ChunkPosScalar,
|
pub x: ChunkPosScalar,
|
||||||
y: ChunkPosScalar,
|
pub y: ChunkPosScalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -19,9 +20,12 @@ impl World {
|
||||||
/// Get mutable access to the tile at `pos`.
|
/// Get mutable access to the tile at `pos`.
|
||||||
///
|
///
|
||||||
/// Loads or generates the containing chunk if necessary.
|
/// Loads or generates the containing chunk if necessary.
|
||||||
pub fn tile_at_mut(&mut self, pos: TilePos) -> &mut Tile {
|
pub fn tile_at_mut(&mut self, pos: TilePos, worldgen: &Worldgen) -> &mut Tile {
|
||||||
let (chk, local) = pos.to_chunk_and_local();
|
let (chk, local) = pos.to_chunk_and_local();
|
||||||
let chk = self.chunks.entry(chk).or_insert_with(|| Chunk::gen(chk));
|
let chk = self
|
||||||
|
.chunks
|
||||||
|
.entry(chk)
|
||||||
|
.or_insert_with(|| Chunk::gen(chk, worldgen));
|
||||||
chk.at_mut(local)
|
chk.at_mut(local)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -100,29 +104,19 @@ pub struct Chunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chunk {
|
impl Chunk {
|
||||||
pub fn gen(pos: ChunkPos) -> Self {
|
pub fn gen(pos: ChunkPos, worldgen: &Worldgen) -> Self {
|
||||||
let mut rng = thread_rng();
|
|
||||||
let mut tiles = [Tile {
|
let mut tiles = [Tile {
|
||||||
bg: 0,
|
bg: 0,
|
||||||
mid: 0,
|
mid: 0,
|
||||||
fg: 0,
|
fg: 0,
|
||||||
}; CHUNK_N_TILES];
|
}; CHUNK_N_TILES];
|
||||||
if pos.y == 156 {
|
let noise = worldgen.chunk_noise(pos);
|
||||||
for (i, b) in tiles.iter_mut().enumerate() {
|
if pos.y >= 156 {
|
||||||
if i / CHUNK_EXTENT as usize == 0 {
|
for (i, t) in tiles.iter_mut().enumerate() {
|
||||||
b.fg = 8;
|
let x = i % CHUNK_EXTENT as usize;
|
||||||
}
|
let y = i / CHUNK_EXTENT as usize;
|
||||||
b.mid = 2;
|
let noise = noise[x][y];
|
||||||
b.bg = 9;
|
*t = noise;
|
||||||
}
|
|
||||||
}
|
|
||||||
if pos.y > 156 {
|
|
||||||
for b in &mut tiles {
|
|
||||||
b.bg = 7;
|
|
||||||
b.mid = 1;
|
|
||||||
if rng.gen_bool(0.1) {
|
|
||||||
b.fg = 6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Unbreakable layer at bottom
|
// Unbreakable layer at bottom
|
||||||
|
|
|
||||||
76
src/worldgen.rs
Normal file
76
src/worldgen.rs
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
use worldgen::{
|
||||||
|
constraint,
|
||||||
|
noise::perlin::PerlinNoise,
|
||||||
|
noisemap::{NoiseMap, NoiseMapGenerator, Seed, Step},
|
||||||
|
world::{
|
||||||
|
tile::{Constraint, ConstraintType},
|
||||||
|
Size, Tile, World,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::world::{ChunkPos, Tile as Tl, CHUNK_EXTENT};
|
||||||
|
|
||||||
|
pub struct Worldgen {
|
||||||
|
world: World<crate::world::Tile>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Worldgen {
|
||||||
|
fn default() -> Self {
|
||||||
|
let noise = PerlinNoise::new();
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
|
let nm1 = NoiseMap::new(noise)
|
||||||
|
.set(Seed::of(rng.gen::<i64>()))
|
||||||
|
.set(Step::of(0.005, 0.005));
|
||||||
|
|
||||||
|
let nm2 = NoiseMap::new(noise)
|
||||||
|
.set(Seed::of(rng.gen::<i64>()))
|
||||||
|
.set(Step::of(0.05, 0.05));
|
||||||
|
|
||||||
|
let nm = Box::new(nm1 + nm2 * 3);
|
||||||
|
|
||||||
|
let world = World::new()
|
||||||
|
.set(Size::of(CHUNK_EXTENT as i64, CHUNK_EXTENT as i64))
|
||||||
|
// Dirt coal
|
||||||
|
.add(
|
||||||
|
Tile::new(Tl {
|
||||||
|
bg: 9,
|
||||||
|
mid: 2,
|
||||||
|
fg: 6,
|
||||||
|
})
|
||||||
|
.when(constraint!(nm.clone(), < -0.8)),
|
||||||
|
)
|
||||||
|
// Dirt
|
||||||
|
.add(
|
||||||
|
Tile::new(Tl {
|
||||||
|
bg: 9,
|
||||||
|
mid: 2,
|
||||||
|
fg: 0,
|
||||||
|
})
|
||||||
|
.when(constraint!(nm.clone(), < -0.1)),
|
||||||
|
)
|
||||||
|
// Stone
|
||||||
|
.add(
|
||||||
|
Tile::new(Tl {
|
||||||
|
bg: 7,
|
||||||
|
mid: 1,
|
||||||
|
fg: 0,
|
||||||
|
})
|
||||||
|
.when(constraint!(nm.clone(), < 0.45)),
|
||||||
|
)
|
||||||
|
// Dirt wall
|
||||||
|
.add(Tile::new(Tl {
|
||||||
|
bg: 9,
|
||||||
|
mid: 0,
|
||||||
|
fg: 0,
|
||||||
|
}));
|
||||||
|
Self { world }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Worldgen {
|
||||||
|
pub fn chunk_noise(&self, pos: ChunkPos) -> Vec<Vec<Tl>> {
|
||||||
|
self.world.generate(pos.x as i64, pos.y as i64).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue