NPCs can fly now but can't bounce.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::fmt::write;
|
use std::fmt::write;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub enum CellVariance {
|
pub enum CellVariance {
|
||||||
VOID = 0,
|
VOID = 0,
|
||||||
DAY = 1,
|
DAY = 1,
|
||||||
|
|||||||
17
src/main.rs
17
src/main.rs
@@ -13,9 +13,9 @@ use winit::{
|
|||||||
};
|
};
|
||||||
use winit_input_helper::WinitInputHelper;
|
use winit_input_helper::WinitInputHelper;
|
||||||
|
|
||||||
const WIDTH: u32 = 350;
|
const WIDTH: u32 = 64;
|
||||||
const HEIGHT: u32 = 350;
|
const HEIGHT: u32 = 64;
|
||||||
const SCALE_FACTOR: f64 = 3.0;
|
const SCALE_FACTOR: f64 = 10.0;
|
||||||
|
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
@@ -43,7 +43,7 @@ fn main() -> Result<(), Error> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut stage = Stage::new(WIDTH as usize, HEIGHT as usize);
|
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;
|
let mut paused = false;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ fn main() -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::R) {
|
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
|
// Handle mouse. This is a bit involved since support some simple
|
||||||
@@ -105,8 +105,11 @@ fn main() -> Result<(), Error> {
|
|||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
if input.mouse_pressed(0) {
|
if input.mouse_pressed(0) {
|
||||||
println!("Mouse click at {mouse_cell:?}");
|
if mouse_cell.0 < 0 || mouse_cell.1 < 0 {
|
||||||
stage.spawn_npc(mouse_cell.0, mouse_cell.1);
|
panic!("Oh no!");
|
||||||
|
}
|
||||||
|
|
||||||
|
stage.spawn_npc(mouse_cell.0 as usize, mouse_cell.1 as usize);
|
||||||
|
|
||||||
stage.update();
|
stage.update();
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/npc.rs
12
src/npc.rs
@@ -1,26 +1,24 @@
|
|||||||
use vec2d::{Coord, Vec2D};
|
|
||||||
|
|
||||||
use crate::{cell::CellVariance, direction::Direction};
|
use crate::{cell::CellVariance, direction::Direction};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct NPC {
|
pub struct NPC {
|
||||||
pub walk_on: CellVariance,
|
pub walk_on: CellVariance,
|
||||||
pub obstructed_from: Vec<CellVariance>,
|
pub obstructed_from: Vec<CellVariance>,
|
||||||
pub pos_x: isize,
|
pub pos_x: usize,
|
||||||
pub pos_y: isize,
|
pub pos_y: usize,
|
||||||
pub direction: Direction
|
pub direction: Direction
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NPC {
|
impl NPC {
|
||||||
pub fn new(pos_x: isize, pos_y: isize, direction: Direction, walk_on: CellVariance, obstructed_from: Vec<CellVariance>) -> Self {
|
pub fn new(pos_x: usize, pos_y: usize, direction: Direction, walk_on: CellVariance, obstructed_from: Vec<CellVariance>) -> Self {
|
||||||
Self { walk_on, obstructed_from, pos_x, pos_y, direction }
|
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 }
|
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 }
|
Self { walk_on: CellVariance::NIGHT, obstructed_from: vec![CellVariance::DAY], pos_x, pos_y, direction }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
91
src/stage.rs
91
src/stage.rs
@@ -15,12 +15,14 @@ pub struct Stage {
|
|||||||
/// Used for temporary work item. Replaces `cells` once done.
|
/// Used for temporary work item. Replaces `cells` once done.
|
||||||
cells_dup: Vec<Cell>,
|
cells_dup: Vec<Cell>,
|
||||||
npcs: Vec<NPC>,
|
npcs: Vec<NPC>,
|
||||||
|
npc_map: Vec<Option<Cell>>,
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ScatterTypes {
|
pub enum ScatterTypes {
|
||||||
RANDOM = 0,
|
Random = 0,
|
||||||
|
HalfVertical = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stage {
|
impl Stage {
|
||||||
@@ -32,6 +34,7 @@ impl Stage {
|
|||||||
cells: vec![Cell::default(); size],
|
cells: vec![Cell::default(); size],
|
||||||
cells_dup: vec![Cell::default(); size],
|
cells_dup: vec![Cell::default(); size],
|
||||||
npcs: vec![],
|
npcs: vec![],
|
||||||
|
npc_map: vec![None; size],
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
}
|
}
|
||||||
@@ -54,7 +57,7 @@ impl Stage {
|
|||||||
|
|
||||||
pub fn scatter(&mut self, scatter: ScatterTypes) {
|
pub fn scatter(&mut self, scatter: ScatterTypes) {
|
||||||
match scatter {
|
match scatter {
|
||||||
ScatterTypes::RANDOM => {
|
ScatterTypes::Random => {
|
||||||
let seed = Self::generate_seed();
|
let seed = Self::generate_seed();
|
||||||
let mut rng: randomize::PCG32 = PCG32::new(seed.0, seed.1);
|
let mut rng: randomize::PCG32 = PCG32::new(seed.0, seed.1);
|
||||||
|
|
||||||
@@ -79,6 +82,21 @@ impl Stage {
|
|||||||
variance = CellVariance::NIGHT;
|
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();
|
let cell = self.cells.get_mut(x + y * self.width).unwrap();
|
||||||
*cell = Cell::new(variance);
|
*cell = Cell::new(variance);
|
||||||
}
|
}
|
||||||
@@ -89,17 +107,17 @@ impl Stage {
|
|||||||
self.update();
|
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 cell = self.get_cell(pos_x, pos_y);
|
||||||
|
|
||||||
let npc: NPC;
|
let npc: NPC;
|
||||||
match cell.variance {
|
match cell.variance {
|
||||||
CellVariance::DAY => {
|
CellVariance::DAY => {
|
||||||
npc = NPC::new_day(pos_x, pos_y, Direction::new(-1, -1));
|
npc = NPC::new_day(pos_x, pos_y, Direction::new(-1, -1));
|
||||||
},
|
}
|
||||||
CellVariance::NIGHT => {
|
CellVariance::NIGHT => {
|
||||||
npc = NPC::new_night(pos_x, pos_y, Direction::new(-1, -1));
|
npc = NPC::new_night(pos_x, pos_y, Direction::new(-1, -1));
|
||||||
},
|
}
|
||||||
CellVariance::VOID => {
|
CellVariance::VOID => {
|
||||||
// Ignore this stupid request.
|
// Ignore this stupid request.
|
||||||
return;
|
return;
|
||||||
@@ -111,36 +129,69 @@ impl Stage {
|
|||||||
self.npcs.push(npc);
|
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());
|
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 {
|
let color = match c.variance {
|
||||||
CellVariance::VOID => [0x0, 0x0, 0x0, 0xFF],
|
CellVariance::VOID => [0x0, 0x0, 0x0, 0xFF],
|
||||||
CellVariance::DAY => [0xD3, 0xE3, 0xD3, 0xFF],
|
CellVariance::DAY => [0xD3, 0xE3, 0xD3, 0xFF],
|
||||||
CellVariance::NIGHT => [0x10, 0x41, 0x4F, 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);
|
pix.copy_from_slice(&color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cell(&self, pos_x: isize, pos_y: isize) -> Cell {
|
pub fn get_cell(&self, pos_x: usize, pos_y: usize) -> Cell {
|
||||||
self.cells[(pos_x + pos_y) as usize * self.width]
|
self.cells[pos_x + (pos_y * self.width)]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
// TODO: Flying balls
|
// 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 y in 0..self.height {
|
||||||
for x in 0..self.width {
|
for x in 0..self.width {
|
||||||
|
|||||||
Reference in New Issue
Block a user