diff --git a/src/cell.rs b/src/cell.rs index 6e3243d..6365701 100644 --- a/src/cell.rs +++ b/src/cell.rs @@ -1,7 +1,7 @@ use core::fmt; use std::fmt::write; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum CellVariance { VOID = 0, DAY = 1, diff --git a/src/main.rs b/src/main.rs index b04a2a2..e8f9257 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,9 +13,9 @@ use winit::{ }; use winit_input_helper::WinitInputHelper; -const WIDTH: u32 = 350; -const HEIGHT: u32 = 350; -const SCALE_FACTOR: f64 = 3.0; +const WIDTH: u32 = 64; +const HEIGHT: u32 = 64; +const SCALE_FACTOR: f64 = 10.0; fn main() -> Result<(), Error> { env_logger::init(); @@ -43,7 +43,7 @@ fn main() -> Result<(), Error> { }; let mut stage = Stage::new(WIDTH as usize, HEIGHT as usize); - stage.scatter(stage::ScatterTypes::RANDOM); + stage.scatter(stage::ScatterTypes::HalfVertical); let mut paused = false; @@ -77,7 +77,7 @@ fn main() -> Result<(), Error> { } if input.key_pressed(VirtualKeyCode::R) { - stage.scatter(stage::ScatterTypes::RANDOM); + stage.scatter(stage::ScatterTypes::Random); } // Handle mouse. This is a bit involved since support some simple @@ -105,8 +105,11 @@ fn main() -> Result<(), Error> { .unwrap_or_default(); if input.mouse_pressed(0) { - println!("Mouse click at {mouse_cell:?}"); - stage.spawn_npc(mouse_cell.0, mouse_cell.1); + if mouse_cell.0 < 0 || mouse_cell.1 < 0 { + panic!("Oh no!"); + } + + stage.spawn_npc(mouse_cell.0 as usize, mouse_cell.1 as usize); stage.update(); } diff --git a/src/npc.rs b/src/npc.rs index f95e484..2409ff7 100644 --- a/src/npc.rs +++ b/src/npc.rs @@ -1,26 +1,24 @@ -use vec2d::{Coord, Vec2D}; - use crate::{cell::CellVariance, direction::Direction}; #[derive(Clone, Debug)] pub struct NPC { pub walk_on: CellVariance, pub obstructed_from: Vec, - pub pos_x: isize, - pub pos_y: isize, + pub pos_x: usize, + pub pos_y: usize, pub direction: Direction } impl NPC { - pub fn new(pos_x: isize, pos_y: isize, direction: Direction, walk_on: CellVariance, obstructed_from: Vec) -> Self { + pub fn new(pos_x: usize, pos_y: usize, direction: Direction, walk_on: CellVariance, obstructed_from: Vec) -> Self { Self { walk_on, obstructed_from, pos_x, pos_y, direction } } - pub fn new_day(pos_x: isize, pos_y: isize, direction: Direction) -> Self { + pub fn new_day(pos_x: usize, pos_y: usize, direction: Direction) -> Self { Self { walk_on: CellVariance::DAY, obstructed_from: vec![CellVariance::NIGHT], pos_x, pos_y, direction } } - pub fn new_night(pos_x: isize, pos_y: isize, direction: Direction) -> Self { + pub fn new_night(pos_x: usize, pos_y: usize, direction: Direction) -> Self { Self { walk_on: CellVariance::NIGHT, obstructed_from: vec![CellVariance::DAY], pos_x, pos_y, direction } } } \ No newline at end of file diff --git a/src/stage.rs b/src/stage.rs index 1366117..d171583 100644 --- a/src/stage.rs +++ b/src/stage.rs @@ -15,12 +15,14 @@ pub struct Stage { /// Used for temporary work item. Replaces `cells` once done. cells_dup: Vec, npcs: Vec, + npc_map: Vec>, width: usize, height: usize, } pub enum ScatterTypes { - RANDOM = 0, + Random = 0, + HalfVertical = 1, } impl Stage { @@ -32,6 +34,7 @@ impl Stage { cells: vec![Cell::default(); size], cells_dup: vec![Cell::default(); size], npcs: vec![], + npc_map: vec![None; size], width, height, } @@ -54,7 +57,7 @@ impl Stage { pub fn scatter(&mut self, scatter: ScatterTypes) { match scatter { - ScatterTypes::RANDOM => { + ScatterTypes::Random => { let seed = Self::generate_seed(); let mut rng: randomize::PCG32 = PCG32::new(seed.0, seed.1); @@ -79,6 +82,21 @@ impl Stage { variance = CellVariance::NIGHT; } + let cell = self.cells.get_mut(x + y * self.width).unwrap(); + *cell = Cell::new(variance); + } + } + } + ScatterTypes::HalfVertical => { + for y in 0..self.height { + for x in 0..self.width { + let is_day = x < (self.width / 2); + let variance = if is_day { + CellVariance::DAY + } else { + CellVariance::NIGHT + }; + let cell = self.cells.get_mut(x + y * self.width).unwrap(); *cell = Cell::new(variance); } @@ -89,17 +107,17 @@ impl Stage { self.update(); } - pub fn spawn_npc(&mut self, pos_x: isize, pos_y: isize) { + pub fn spawn_npc(&mut self, pos_x: usize, pos_y: usize) { let cell = self.get_cell(pos_x, pos_y); - + let npc: NPC; match cell.variance { CellVariance::DAY => { npc = NPC::new_day(pos_x, pos_y, Direction::new(-1, -1)); - }, + } CellVariance::NIGHT => { npc = NPC::new_night(pos_x, pos_y, Direction::new(-1, -1)); - }, + } CellVariance::VOID => { // Ignore this stupid request. return; @@ -111,37 +129,70 @@ impl Stage { self.npcs.push(npc); } - pub fn draw(&self, screen: &mut [u8]) { + pub fn draw(&mut self, screen: &mut [u8]) { debug_assert_eq!(screen.len(), 4 * self.cells.len()); - for (c, pix) in self.cells.iter().zip(screen.chunks_exact_mut(4)) { + + // Draw NPCs + self.npc_map.fill(None); + for (i, npc) in self.npcs.iter().enumerate() { + let map_pos = npc.pos_x + npc.pos_y * self.width; + // let color = match npc.walk_on { + // CellVariance::DAY => [0x10, 0x41, 0x4F, 0xFF], + // CellVariance::NIGHT => [0xD3, 0xE3, 0xD3, 0xFF], + // _ => { + // panic!("This NPC shouldn't even exist!"); + // } + // }; + + self.npc_map[map_pos] = Some(Cell::new(npc.obstructed_from[0])); + } + + // Draw background + for (i, (mut c, pix)) in self.cells.iter().zip(screen.chunks_exact_mut(4)).enumerate() { + let npc_cell = self.npc_map.get(i).unwrap(); + if let Some(npc_cell) = npc_cell { + c = &npc_cell; + } + let color = match c.variance { CellVariance::VOID => [0x0, 0x0, 0x0, 0xFF], CellVariance::DAY => [0xD3, 0xE3, 0xD3, 0xFF], CellVariance::NIGHT => [0x10, 0x41, 0x4F, 0xFF], }; - pix.copy_from_slice(&color); - } - - for (n, pix) in self.npcs.iter().zip(screen.chunks_exact_mut(4)) { - let color = match n.walk_on { - CellVariance::DAY => [0x10, 0x41, 0x4F, 0xFF], - CellVariance::NIGHT => [0xD3, 0xE3, 0xD3, 0xFF], - _ => { - panic!("This NPC shouldn't even exist!"); - } - }; pix.copy_from_slice(&color); } } - pub fn get_cell(&self, pos_x: isize, pos_y: isize) -> Cell { - self.cells[(pos_x + pos_y) as usize * self.width] + pub fn get_cell(&self, pos_x: usize, pos_y: usize) -> Cell { + self.cells[pos_x + (pos_y * self.width)] } pub fn update(&mut self) { // TODO: Flying balls - + for npc in self.npcs.iter_mut() { + let next_pos = ((npc.pos_x as isize + npc.direction.x), (npc.pos_y as isize + npc.direction.y)); + if next_pos.0 < 0 || next_pos.1 < 0 { + // TODO: Bounce + continue; + } + + let index = next_pos.0 as usize + next_pos.1 as usize * self.width; + let next_cell = self.cells_dup[index]; + + // If our next cell would be one that we collide with. + if npc.obstructed_from.contains(&next_cell.variance) { + // TODO: Bounce + continue; + } + + npc.pos_x = next_pos.0 as usize; + npc.pos_y = next_pos.1 as usize; + + // We can move freely for now. + self.npc_map[index] = Some(Cell::new(npc.obstructed_from[0])); + } + for y in 0..self.height { for x in 0..self.width { let idx = x + y * self.width;