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);
|
|
|
|
}
|
|
|
|
}
|