use std::time::Instant; 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 VALID_CHARS: [char; 3] = ['v', 's', 'g']; 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: char) -> Self { match value { 'v' => Self::Void, 's' => Self::Sea, 'g' => Self::Grass, _ => panic!("Invalid cell kind") } } } 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 { kind: CellKind } impl Cell { const RADIUS: f32 = 1.; fn new(kind: CellKind) -> Self { Self { kind } } } struct Map { cells: [Cell; Self::SIZE] } impl Map { const HEIGHT: usize = 10; const WIDTH: usize = 10; const SIZE: usize = Self::HEIGHT*Self::WIDTH; fn new() -> Self { std::array::from_fn(|_| thread_rng().gen_range(1..=2)).into() // "sgssv // ggsvg // gsvvs // vgsgs // ssggs".into() } fn enumerate<'a>(&'a self) -> std::iter::Map>, fn((usize, &Cell)) -> ([usize; 2], &Cell)> { self.cells.iter().enumerate().map(|(i, c)| ([i % Self::HEIGHT, i / Self::WIDTH], c)) } } impl From<&str> for Map { fn from(value: &str) -> Self { let mut chars = value.chars().filter(|c| CellKind::VALID_CHARS.contains(c)); let cells = std::array::from_fn(|_| Cell::new(chars.next().expect("Invalid map size").into())); Self { cells } } } impl From<[u8; Map::SIZE]> for Map { fn from(value: [u8; Map::SIZE]) -> Self { Self { cells: value.map(|c| Cell::new(c.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 ([x, y], c) in self.map.enumerate() { 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); } }