save
This commit is contained in:
parent
d3b662ebf6
commit
83f76015d4
@ -42,4 +42,4 @@ web-sys = { version = "0.3", features = [
|
|||||||
getrandom ={ version = "*", features = ["js"]}
|
getrandom ={ version = "*", features = ["js"]}
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
android_logger = "0.14"
|
android_logger = "0.14"
|
||||||
|
@ -16,12 +16,12 @@ impl<'a> App<'a> {
|
|||||||
fn run(&mut self, event_loop: EventLoop<()>) {
|
fn run(&mut self, event_loop: EventLoop<()>) {
|
||||||
dbg!("run");
|
dbg!("run");
|
||||||
event_loop.run(move |event, target| {
|
event_loop.run(move |event, target| {
|
||||||
dbg!(&event);
|
// dbg!(&event);
|
||||||
let _ = &self;
|
let _ = &self;
|
||||||
// let _ = (&graphics, &window, &state);
|
// let _ = (&graphics, &window, &state);
|
||||||
match event {
|
match event {
|
||||||
Event::Resumed => {
|
Event::Resumed => {
|
||||||
std::thread::sleep(Duration::from_secs(10));
|
// std::thread::sleep(Duration::from_secs(5));
|
||||||
self.graphics = Some(pollster::block_on(Graphics::init(&self)));
|
self.graphics = Some(pollster::block_on(Graphics::init(&self)));
|
||||||
},
|
},
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
@ -146,11 +146,13 @@ pub fn main() {
|
|||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn android_main(app: winit::platform::android::activity::AndroidApp) {
|
fn android_main(app: winit::platform::android::activity::AndroidApp) {
|
||||||
use winit::platform::android::EventLoopBuilderExtAndroid;
|
use winit::platform::android::{EventLoopBuilderExtAndroid, activity::WindowManagerFlags};
|
||||||
|
|
||||||
android_logger::init_once(android_logger::Config::default());
|
android_logger::init_once(android_logger::Config::default());
|
||||||
log::error!("testbbbbbbbbbbb");
|
log::error!("testbbbbbbbbbbb");
|
||||||
|
|
||||||
|
app.set_window_flags(WindowManagerFlags::KEEP_SCREEN_ON & WindowManagerFlags::FULLSCREEN, WindowManagerFlags::empty());
|
||||||
|
|
||||||
let event_loop = winit::event_loop::EventLoopBuilder::new()
|
let event_loop = winit::event_loop::EventLoopBuilder::new()
|
||||||
.with_android_app(app)
|
.with_android_app(app)
|
||||||
.build()
|
.build()
|
||||||
|
114
src/state.rs
114
src/state.rs
@ -3,11 +3,11 @@ use log::info;
|
|||||||
use noise::{Fbm, MultiFractal, NoiseFn, Perlin};
|
use noise::{Fbm, MultiFractal, NoiseFn, Perlin};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use voronoice::{BoundingBox, Point, Voronoi, VoronoiBuilder};
|
use voronoice::{BoundingBox, Point, Voronoi, VoronoiBuilder};
|
||||||
use winit::{event::{DeviceEvent, ElementState, Event, KeyEvent, MouseButton, MouseScrollDelta, RawKeyEvent, WindowEvent}, keyboard::{KeyCode, PhysicalKey}, window::Window};
|
use winit::{event::{DeviceEvent, Event, KeyEvent, MouseButton, MouseScrollDelta, WindowEvent}, keyboard::{KeyCode, PhysicalKey}, window::Window};
|
||||||
|
|
||||||
use crate::graphics::{Uniforms, Vertex};
|
use crate::graphics::{Uniforms, Vertex};
|
||||||
|
|
||||||
const FRAMERATE: usize = 10; // Update per second
|
const FRAMERATE: usize = 1; // Update per second
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum CellKind {
|
enum CellKind {
|
||||||
@ -20,19 +20,33 @@ enum CellKind {
|
|||||||
Grass
|
Grass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct CellData {
|
struct CellData {
|
||||||
kind: CellKind,
|
kind: CellKind,
|
||||||
cell: usize,
|
cell: usize,
|
||||||
z: f32,
|
z: f32,
|
||||||
moisture: f32
|
area: f32,
|
||||||
|
moisture: f32,
|
||||||
|
ressource: (f32, usize) // How much ressource there is (between 0 and 1) and the last time it was updated (in frames)
|
||||||
}
|
}
|
||||||
impl CellData {
|
impl CellData {
|
||||||
fn new(kind: CellKind, cell: usize, z: f32, moisture: f32) -> Self {
|
fn new(kind: CellKind, cell: usize, z: f32, moisture: f32, ressource: f32, t: usize, voronoi: &Voronoi) -> Self {
|
||||||
|
let mut area = 0.;
|
||||||
|
let c = voronoi.cell(cell);
|
||||||
|
let vs = c.iter_vertices().collect::<Vec<_>>();
|
||||||
|
let a = vs[0];
|
||||||
|
for i in 1..(vs.len()-1) {
|
||||||
|
let b = vs[i];
|
||||||
|
let c = vs[i+1];
|
||||||
|
area += 0.5 * ((a.x*(b.y-c.y))+(b.x*(c.y-a.y))+(c.x*(a.y-b.y))).abs();
|
||||||
|
}
|
||||||
Self {
|
Self {
|
||||||
kind,
|
kind,
|
||||||
cell,
|
cell,
|
||||||
z,
|
z,
|
||||||
moisture
|
area: area as f32,
|
||||||
|
moisture,
|
||||||
|
ressource: (ressource, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn color(&self) -> [f32; 4] {
|
fn color(&self) -> [f32; 4] {
|
||||||
@ -48,6 +62,22 @@ impl CellData {
|
|||||||
CellKind::Grass => [(136./255.) - (self.moisture*0.4), (204./255.) - (self.moisture*0.4), (59./255.) - (self.moisture*0.4), 1.]
|
CellKind::Grass => [(136./255.) - (self.moisture*0.4), (204./255.) - (self.moisture*0.4), (59./255.) - (self.moisture*0.4), 1.]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn ressource(&self) -> f32 {
|
||||||
|
// How much it get by day
|
||||||
|
let recuperation_rate = match self.kind {
|
||||||
|
CellKind::Void | CellKind::Sea | CellKind::Beach | CellKind::Dirt | CellKind::Stone => 0.,
|
||||||
|
CellKind::Forest => 1. / (100. * 365.25), // Let's say that a forest takes 100 years to mature
|
||||||
|
CellKind::Grass => 1. / (7. * 7.) // Let's say that grass takes 7 weaks to reach its max
|
||||||
|
};
|
||||||
|
self.ressource.0 + (self.ressource.1 as f32 * recuperation_rate)
|
||||||
|
}
|
||||||
|
fn set_ressource(&mut self, val: f32, t: usize) {
|
||||||
|
assert!(val >= 0. && val <= 1.);
|
||||||
|
self.ressource = (val, t);
|
||||||
|
}
|
||||||
|
fn refresh_ressource(&mut self, t: usize) {
|
||||||
|
self.ressource = (self.ressource(), t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Map {
|
struct Map {
|
||||||
@ -58,8 +88,10 @@ struct Map {
|
|||||||
impl Map {
|
impl Map {
|
||||||
const HEIGHT: f32 = 2.;
|
const HEIGHT: f32 = 2.;
|
||||||
const WIDTH: f32 = 2.;
|
const WIDTH: f32 = 2.;
|
||||||
|
const REAL_HEIGHT: f32 = 500.;
|
||||||
|
const REAL_WIDTH: f32 = 500.;
|
||||||
const SIZE: usize = 10_000;
|
const SIZE: usize = 10_000;
|
||||||
fn new(seed: u32) -> Self {
|
fn new(seed: u32, t: usize) -> Self {
|
||||||
let mut rng = rand::rngs::SmallRng::seed_from_u64(seed as u64);
|
let mut rng = rand::rngs::SmallRng::seed_from_u64(seed as u64);
|
||||||
let mut sites = Vec::with_capacity(Self::SIZE);
|
let mut sites = Vec::with_capacity(Self::SIZE);
|
||||||
for _ in 0..Self::SIZE {
|
for _ in 0..Self::SIZE {
|
||||||
@ -95,7 +127,7 @@ impl Map {
|
|||||||
} else {
|
} else {
|
||||||
CellKind::Stone
|
CellKind::Stone
|
||||||
};
|
};
|
||||||
cells_data.push(CellData::new(k, i, z as f32, m));
|
cells_data.push(CellData::new(k, i, z as f32, m, 1., t, &voronoi));
|
||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
voronoi,
|
voronoi,
|
||||||
@ -118,21 +150,26 @@ enum EntityState {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Entity {
|
struct Entity {
|
||||||
pos: [f32; 3],
|
cell: usize,
|
||||||
kind: EntityKind,
|
kind: EntityKind,
|
||||||
start: Instant,
|
start: Instant,
|
||||||
state: EntityState
|
state: EntityState,
|
||||||
|
health: f32 // between 0 and 1
|
||||||
}
|
}
|
||||||
impl Entity {
|
impl Entity {
|
||||||
fn new(pos: [f32; 3], kind: EntityKind) -> Self {
|
fn new(cell: usize, kind: EntityKind) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pos,
|
cell,
|
||||||
kind,
|
kind,
|
||||||
start: Instant::now(),
|
start: Instant::now(),
|
||||||
state: EntityState::Resting
|
state: EntityState::Resting,
|
||||||
|
health: 1.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn render(&self, vertices: &mut Vec<Vertex>, indices: &mut Vec<u32>) {
|
fn pos<'a>(&self, map: &'a Map) -> &'a Point {
|
||||||
|
&map.voronoi.sites()[self.cell]
|
||||||
|
}
|
||||||
|
fn render(&self, vertices: &mut Vec<Vertex>, indices: &mut Vec<u32>, map: &Map) {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
EntityKind::Horse => {
|
EntityKind::Horse => {
|
||||||
let color = [171./255., 122./255., 50./255., 1.];
|
let color = [171./255., 122./255., 50./255., 1.];
|
||||||
@ -222,13 +259,14 @@ impl Entity {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let pos = self.pos(map);
|
||||||
|
|
||||||
vertices.reserve(vs.len());
|
vertices.reserve(vs.len());
|
||||||
let base = vertices.len() as u32;
|
let base = vertices.len() as u32;
|
||||||
for mut v in vs {
|
for mut v in vs {
|
||||||
v.pos[0] = v.pos[0]/50. + self.pos[0];
|
v.pos[0] = v.pos[0]/50. + pos.x as f32;
|
||||||
v.pos[1] = (v.pos[1] + 0.75)/50. + self.pos[1];
|
v.pos[1] = (v.pos[1] + 0.75)/50. + pos.y as f32;
|
||||||
vertices.push(v)
|
vertices.push(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,26 +274,15 @@ impl Entity {
|
|||||||
for i in is {
|
for i in is {
|
||||||
indices.push(base + i);
|
indices.push(base + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// let vs = vec![
|
|
||||||
// Vertex { pos: [-0.5, 0.3, 0.], color },
|
|
||||||
// Vertex { pos: [-0.3, 0., 0.], color },
|
|
||||||
// Vertex { pos: [0.4, -0.1, 0.], color },
|
|
||||||
// Vertex { pos: [0.5, 0.3, 0.], color },
|
|
||||||
// Vertex { pos: [0.3, 0.4, 0.], color },
|
|
||||||
// ];
|
|
||||||
// let i = self.vertices.len() as u32;
|
|
||||||
// for v in vs.iter() {
|
|
||||||
// self.vertices.push(*v);
|
|
||||||
// }
|
|
||||||
// for v in 1..(vs.len()-1) as u32 {
|
|
||||||
// self.indices.push(i);
|
|
||||||
// self.indices.push(i+v);
|
|
||||||
// self.indices.push(i+v+1);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn update(&mut self, map: &mut Map) {
|
||||||
|
// Let’s take 0.57 kg of grass / m2
|
||||||
|
// Let’s take 7.5 kg of food / day for a horse
|
||||||
|
let r = dbg!(&map.cells_data[self.cell]).ressource();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
@ -265,7 +292,7 @@ pub struct State {
|
|||||||
map: Map,
|
map: Map,
|
||||||
entities: Vec<Entity>,
|
entities: Vec<Entity>,
|
||||||
start: Instant,
|
start: Instant,
|
||||||
frame: usize,
|
t: usize, // Time in frames
|
||||||
selected_tile: usize,
|
selected_tile: usize,
|
||||||
mouse_pressed: bool
|
mouse_pressed: bool
|
||||||
}
|
}
|
||||||
@ -276,8 +303,8 @@ impl State {
|
|||||||
indices: vec![],
|
indices: vec![],
|
||||||
uniforms: Uniforms::default(),
|
uniforms: Uniforms::default(),
|
||||||
start: Instant::now(),
|
start: Instant::now(),
|
||||||
frame: 0,
|
t: 0,
|
||||||
map: Map::new(0),
|
map: Map::new(0, 0),
|
||||||
entities: Vec::new(),
|
entities: Vec::new(),
|
||||||
selected_tile: 0,
|
selected_tile: 0,
|
||||||
mouse_pressed: false
|
mouse_pressed: false
|
||||||
@ -291,9 +318,10 @@ impl State {
|
|||||||
if state.is_pressed() {
|
if state.is_pressed() {
|
||||||
match button {
|
match button {
|
||||||
MouseButton::Left => {
|
MouseButton::Left => {
|
||||||
|
self.entities.push(Entity::new(self.selected_tile, EntityKind::Horse));
|
||||||
self.mouse_pressed = true;
|
self.mouse_pressed = true;
|
||||||
},
|
},
|
||||||
MouseButton::Right => self.map = Map::new(self.map.seed + 1),
|
MouseButton::Right => self.map = Map::new(self.map.seed + 1, self.t),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@ -319,8 +347,6 @@ impl State {
|
|||||||
if let CellKind::Dirt = cd.kind {
|
if let CellKind::Dirt = cd.kind {
|
||||||
cd.kind = CellKind::Forest;
|
cd.kind = CellKind::Forest;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.entities.push(Entity::new([pos.x as f32, pos.y as f32, 0.9], EntityKind::Horse));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.selected_tile = c.iter_path(pos).last().unwrap();
|
self.selected_tile = c.iter_path(pos).last().unwrap();
|
||||||
@ -380,7 +406,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for e in self.entities.iter() {
|
for e in self.entities.iter() {
|
||||||
e.render(&mut self.vertices, &mut self.indices);
|
e.render(&mut self.vertices, &mut self.indices, &self.map);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c, cd) in self.map.voronoi.iter_cells().zip(self.map.cells_data.iter()).filter(|(_,cd)| cd.kind == CellKind::Forest) {
|
for (c, cd) in self.map.voronoi.iter_cells().zip(self.map.cells_data.iter()).filter(|(_,cd)| cd.kind == CellKind::Forest) {
|
||||||
@ -403,7 +429,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn update_if_needed(&mut self) {
|
pub fn update_if_needed(&mut self) {
|
||||||
while self.start.elapsed().as_secs_f32() > (self.frame as f32) / (FRAMERATE as f32) {
|
while self.start.elapsed().as_secs_f32() > (self.t as f32) / (FRAMERATE as f32) {
|
||||||
self.update();
|
self.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,6 +460,10 @@ impl State {
|
|||||||
self.map.cells_data[n].kind = k;
|
self.map.cells_data[n].kind = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.frame += 1;
|
for e in self.entities.iter_mut() {
|
||||||
|
e.update(&mut self.map);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.t += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user