use std::time::Instant; use nalgebra::Point2; 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 { const VARIANTS: u8 = 3; 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 for CellKind { fn from(value: u8) -> Self { match value { 0 => Self::Void, 1 => Self::Sea, 2 => Self::Grass, _ => panic!("Invalid cell kind") } } } struct Cell { pos: Point2, kind: CellKind } impl Cell { const RADIUS: f32 = 1.; fn new(pos: Point2, kind: CellKind) -> Self { Self { pos, kind } } } struct Map { cells: [Cell; Self::SIZE] } impl Map { const HEIGHT: usize = 10; const WIDTH: usize = 10; const SIZE: usize = 10; fn new() -> Self { 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() ) }) } // "sgssv // ggsvg // gsvvs // vgsgs // ssggs".into() } } pub struct State { pub vertices: Vec, pub indices: Vec, 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); for c in self.map.cells.iter() { 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); } }