forestiles/src/state.rs

163 lines
5.3 KiB
Rust
Raw Normal View History

2024-08-22 17:21:34 +01:00
use std::time::Instant;
2024-08-23 09:00:33 +01:00
use nalgebra::Point2;
2024-08-22 17:21:34 +01:00
use rand::prelude::*;
use winit::event::{DeviceEvent, ElementState, Event, MouseButton, MouseScrollDelta, WindowEvent};
use crate::graphics::{Uniforms, Vertex};
pub const SQRT_3: f32 = 1.732050807568877293527446341505872367;
#[repr(u8)]
#[derive(Debug, Clone, Copy)]
enum CellKind {
Void,
Sea,
Grass,
}
impl CellKind {
2024-08-23 09:00:33 +01:00
const VARIANTS: u8 = 3;
2024-08-22 17:21:34 +01:00
fn color(&self) -> [f32; 4] {
match self {
Self::Void => [0.; 4],
Self::Sea => [0., 0., 1., 1.],
Self::Grass => [0., 1., 0., 1.]
}
}
}
impl From<u8> for CellKind {
fn from(value: u8) -> Self {
match value {
0 => Self::Void,
1 => Self::Sea,
2 => Self::Grass,
_ => panic!("Invalid cell kind")
}
}
}
struct Cell {
2024-08-23 09:00:33 +01:00
pos: Point2<f32>,
2024-08-22 17:21:34 +01:00
kind: CellKind
}
impl Cell {
const RADIUS: f32 = 1.;
2024-08-23 09:00:33 +01:00
fn new(pos: Point2<f32>, kind: CellKind) -> Self {
2024-08-22 17:21:34 +01:00
Self {
2024-08-23 09:00:33 +01:00
pos,
2024-08-22 17:21:34 +01:00
kind
}
}
}
struct Map {
cells: [Cell; Self::SIZE]
}
impl Map {
const HEIGHT: usize = 10;
const WIDTH: usize = 10;
2024-08-23 09:00:33 +01:00
const SIZE: usize = 10;
2024-08-22 17:21:34 +01:00
fn new() -> Self {
2024-08-23 09:00:33 +01:00
Self {
cells: std::array::from_fn(|_| {
let mut rng = thread_rng();
Cell::new(
Point2::new(rng.gen_range(-1.0..1.), rng.gen_range(-1.0..1.)),
rng.gen_range(0..CellKind::VARIANTS).into()
)
})
}
2024-08-22 17:21:34 +01:00
// "sgssv
// ggsvg
// gsvvs
// vgsgs
// ssggs".into()
}
}
pub struct State {
pub vertices: Vec<Vertex>,
pub indices: Vec<u32>,
pub uniforms: Uniforms,
start: Instant,
map: Map
}
impl State {
pub fn new() -> Self {
let mut s = Self {
vertices: vec![],
indices: vec![],
uniforms: Uniforms::default(),
start: Instant::now(),
map: Map::new()
};
s.update();
s
}
pub fn input(&mut self, event: Event<()>) {
match event {
Event::WindowEvent { event: WindowEvent::MouseInput { state, button, ..}, ..} => {
if let state = ElementState::Pressed {
self.uniforms.camera[2] += match button {
MouseButton::Left => 0.1,
MouseButton::Right => -0.1,
_ => 0.
};
}
},
// Event::WindowEvent { event: WindowEvent::MouseWheel { delta, ..}, ..} => {
// self.uniforms.camera[2] -= match delta {
// MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
// MouseScrollDelta::LineDelta(_, y) => y
// };
// },
Event::DeviceEvent { event: DeviceEvent::MouseWheel { delta }, ..} => {
self.uniforms.camera[2] += match delta {
MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
MouseScrollDelta::LineDelta(_, y) => y
};
},
_ => {}
}
}
pub fn update(&mut self) {
self.vertices = Vec::with_capacity(self.map.cells.len()*6);
self.indices = Vec::with_capacity(self.map.cells.len()*12);
2024-08-23 09:00:33 +01:00
for c in self.map.cells.iter() {
2024-08-22 17:21:34 +01:00
let x = x as f32;
let y = y as f32;
let i = self.vertices.len();
let color = c.kind.color();
let center = [(0.5+x+((y%2.)*0.5)) * (SQRT_3*Cell::RADIUS), -(0.5+y)*(1.5*Cell::RADIUS)];
// self.vertices.push(Vertex { pos: [center[0], center[1], 0.], color });
// self.vertices.push(Vertex { pos: [center[0]+0.1, center[1]+0.1, 0.], color });
// self.vertices.push(Vertex { pos: [center[0]-0.1, center[1]+0.1, 0.], color });
self.vertices.push(Vertex { pos: [center[0], center[1]+Cell::RADIUS, 0.], color: color.clone() });
self.vertices.push(Vertex { pos: [center[0]-(0.5*SQRT_3*Cell::RADIUS), center[1]+(0.5*Cell::RADIUS), 0.], color: color.clone() });
self.vertices.push(Vertex { pos: [center[0]+(0.5*SQRT_3*Cell::RADIUS), center[1]+(0.5*Cell::RADIUS), 0.], color: color.clone() });
self.vertices.push(Vertex { pos: [center[0]-(0.5*SQRT_3*Cell::RADIUS), center[1]-(0.5*Cell::RADIUS), 0.], color: color.clone() });
self.vertices.push(Vertex { pos: [center[0]+(0.5*SQRT_3*Cell::RADIUS), center[1]-(0.5*Cell::RADIUS), 0.], color: color.clone() });
self.vertices.push(Vertex { pos: [center[0], center[1]-Cell::RADIUS, 0.], color: color.clone() });
self.indices.push(i as u32);
self.indices.push((i+1) as u32);
self.indices.push((i+2) as u32);
self.indices.push((i+1) as u32);
self.indices.push((i+3) as u32);
self.indices.push((i+2) as u32);
self.indices.push((i+3) as u32);
self.indices.push((i+4) as u32);
self.indices.push((i+2) as u32);
self.indices.push((i+3) as u32);
self.indices.push((i+5) as u32);
self.indices.push((i+4) as u32);
}
// dbg!(&self.vertices, &self.indices, &self.uniforms);
// dbg!(self.vertices.len(), self.indices.len(), &self.uniforms);
}
}