Apparently the bounce is still broken. It always was.
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Direction {
|
pub struct Coord {
|
||||||
pub x: isize,
|
pub x: isize,
|
||||||
pub y: isize
|
pub y: isize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Direction {
|
impl Coord {
|
||||||
pub fn new(x: isize, y: isize) -> Self {
|
pub fn new(x: isize, y: isize) -> Self {
|
||||||
Self { x, y }
|
Self { x, y }
|
||||||
}
|
}
|
||||||
|
|||||||
179
src/npc.rs
179
src/npc.rs
@@ -1,10 +1,26 @@
|
|||||||
use std::cell;
|
use std::cell;
|
||||||
|
|
||||||
use crate::{cell::{Cell, CellVariance}, direction::Direction, stage::{self, Stage}, HEIGHT, WIDTH};
|
use crate::{
|
||||||
|
cell::{Cell, CellVariance},
|
||||||
|
direction::Coord,
|
||||||
|
stage::{self, Stage},
|
||||||
|
HEIGHT, WIDTH,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum Direction {
|
||||||
|
TOP, /* 💪 */
|
||||||
|
BOTTOM, /* 👉👈🥺 */
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Neighbour {
|
pub struct Neighbour {
|
||||||
|
pub cell: Cell,
|
||||||
|
pub direction: Direction,
|
||||||
|
pub pos_x: usize,
|
||||||
|
pub pos_y: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@@ -13,11 +29,11 @@ pub struct NPC {
|
|||||||
pub obstructed_from: Vec<CellVariance>,
|
pub obstructed_from: Vec<CellVariance>,
|
||||||
pub pos_x: usize,
|
pub pos_x: usize,
|
||||||
pub pos_y: usize,
|
pub pos_y: usize,
|
||||||
pub direction: Direction,
|
pub direction: Coord,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NPC {
|
impl NPC {
|
||||||
pub fn new_day(pos_x: usize, pos_y: usize, direction: Direction) -> Self {
|
pub fn new_day(pos_x: usize, pos_y: usize, direction: Coord) -> Self {
|
||||||
Self {
|
Self {
|
||||||
walk_on: CellVariance::DAY,
|
walk_on: CellVariance::DAY,
|
||||||
obstructed_from: vec![CellVariance::NIGHT, CellVariance::VOID],
|
obstructed_from: vec![CellVariance::NIGHT, CellVariance::VOID],
|
||||||
@@ -27,7 +43,7 @@ impl NPC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_night(pos_x: usize, pos_y: usize, direction: Direction) -> Self {
|
pub fn new_night(pos_x: usize, pos_y: usize, direction: Coord) -> Self {
|
||||||
Self {
|
Self {
|
||||||
walk_on: CellVariance::NIGHT,
|
walk_on: CellVariance::NIGHT,
|
||||||
obstructed_from: vec![CellVariance::DAY, CellVariance::VOID],
|
obstructed_from: vec![CellVariance::DAY, CellVariance::VOID],
|
||||||
@@ -42,77 +58,112 @@ impl NPC {
|
|||||||
Cell::new(self.obstructed_from[0])
|
Cell::new(self.obstructed_from[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_bounce(&mut self, map: &Vec<Cell>) {
|
pub fn process_bounce(&mut self, map: &Vec<Cell>) -> Option<Neighbour> {
|
||||||
// Get the current and next positions
|
// Get the current and next positions
|
||||||
let (curr_x, curr_y) = (self.pos_x, self.pos_y);
|
|
||||||
let next: (Option<usize>, Option<usize>) = self.next_position();
|
|
||||||
|
|
||||||
let mut next_direction = self.direction.clone();
|
let mut next_direction = self.direction.clone();
|
||||||
|
|
||||||
let mut out_of_bounds_top = false;
|
|
||||||
let mut out_of_bounds_left = false;
|
|
||||||
let mut next_x: usize = 0;
|
|
||||||
let mut next_y: usize = 0;
|
|
||||||
|
|
||||||
// Both tuples of `next` will be none if they are out of bounds.
|
|
||||||
if next.0.is_some() && next.1.is_some() {
|
|
||||||
(next_x, next_y) = (next.0.unwrap(), next.1.unwrap());
|
|
||||||
|
|
||||||
// If we stay on our stage
|
|
||||||
if (next_x <= WIDTH - 1 && next_y <= HEIGHT - 1) {
|
|
||||||
let Cell { variance } = map.get(next_x + next_y * WIDTH).unwrap();
|
|
||||||
|
|
||||||
if !self.obstructed_from.contains(variance) {
|
|
||||||
// If our next cell is not obstructing us, nor is out of screen (see above) then we don't
|
|
||||||
// need to bounce around and can simply move to the next position.
|
|
||||||
self.move_next();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if next.0.is_none() {
|
|
||||||
out_of_bounds_left = true;
|
|
||||||
} else {
|
|
||||||
out_of_bounds_top = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are here, we know that we hit something.
|
// If we are here, we know that we hit something.
|
||||||
|
match self.check_neighborhood(map) {
|
||||||
|
None => {
|
||||||
|
self.move_next();
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(neighbour) => {
|
||||||
|
if neighbour.direction == Direction::LEFT || neighbour.direction == Direction::RIGHT
|
||||||
|
{
|
||||||
|
next_direction.x *= -1;
|
||||||
|
} else {
|
||||||
|
next_direction.y *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Check our left and right
|
// Return the new bounce direction
|
||||||
if out_of_bounds_left {
|
self.direction = next_direction;
|
||||||
next_direction.x *= -1;
|
|
||||||
} else {
|
|
||||||
let variance_left = map.get((self.pos_x.checked_sub(1).unwrap_or(0)) + self.pos_y * WIDTH).unwrap_or(&Cell { variance: CellVariance::VOID }).variance;
|
|
||||||
let variance_right = map.get((self.pos_x.checked_add(1).unwrap_or(0)) + self.pos_y * WIDTH).unwrap_or(&Cell { variance: CellVariance::VOID }).variance;
|
|
||||||
|
|
||||||
if self.obstructed_from.contains(&variance_left) || self.obstructed_from.contains(&variance_right) {
|
self.move_next();
|
||||||
next_direction.x *= -1;
|
|
||||||
|
// Don't tell update function that we hit a void block, to avoid overriding it.
|
||||||
|
// We changed direction anyway.
|
||||||
|
if neighbour.cell.variance != CellVariance::VOID {
|
||||||
|
return Some(neighbour);
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check top and bottom
|
|
||||||
if out_of_bounds_top {
|
|
||||||
next_direction.y *= -1;
|
|
||||||
} else {
|
|
||||||
let variance_top = map.get(self.pos_x + (self.pos_y.checked_sub(1).unwrap_or(0)) * WIDTH).unwrap_or(&Cell { variance: CellVariance::VOID }).variance;
|
|
||||||
let variance_bottom = map.get(self.pos_x + (self.pos_y.checked_add(1).unwrap_or(0)) * WIDTH).unwrap_or(&Cell { variance: CellVariance::VOID }).variance;
|
|
||||||
|
|
||||||
if self.obstructed_from.contains(&variance_top) || self.obstructed_from.contains(&variance_bottom) {
|
|
||||||
next_direction.y *= -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Return the new bounce direction
|
|
||||||
self.direction = next_direction;
|
|
||||||
|
|
||||||
self.move_next();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_bounce(&mut self, next_x: usize) {
|
fn check_neighborhood(&self, map: &Vec<Cell>) -> Option<Neighbour> {
|
||||||
|
if self.pos_y == 0 && self.direction.y == -1 {
|
||||||
|
return Some(Neighbour {
|
||||||
|
cell: map[0],
|
||||||
|
direction: Direction::TOP,
|
||||||
|
pos_x: 0,
|
||||||
|
pos_y: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.pos_x == 0 && self.direction.x == -1 {
|
||||||
|
return Some(Neighbour {
|
||||||
|
cell: map[0],
|
||||||
|
direction: Direction::LEFT,
|
||||||
|
pos_x: 0,
|
||||||
|
pos_y: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let left = (self.pos_x.checked_sub(1).unwrap_or(0), self.pos_y);
|
||||||
|
let right = (self.pos_x.checked_add(1).unwrap_or(0), self.pos_y);
|
||||||
|
let top = (self.pos_x, self.pos_y.checked_sub(1).unwrap_or(0));
|
||||||
|
let bottom = (self.pos_x, (self.pos_y.checked_add(1).unwrap_or(0)));
|
||||||
|
|
||||||
|
let cell_left = map.get(left.0 + left.1 * WIDTH).unwrap_or(&Cell {
|
||||||
|
variance: CellVariance::VOID,
|
||||||
|
});
|
||||||
|
let cell_right = map.get(right.0 + right.1 * WIDTH).unwrap_or(&Cell {
|
||||||
|
variance: CellVariance::VOID,
|
||||||
|
});
|
||||||
|
let cell_top = map.get(top.0 + top.1 * WIDTH).unwrap_or(&Cell {
|
||||||
|
variance: CellVariance::VOID,
|
||||||
|
});
|
||||||
|
let cell_bottom = map.get(bottom.0 + bottom.1 * WIDTH).unwrap_or(&Cell {
|
||||||
|
variance: CellVariance::VOID,
|
||||||
|
});
|
||||||
|
|
||||||
|
if self.obstructed_from.contains(&cell_left.variance) {
|
||||||
|
return Some(Neighbour {
|
||||||
|
cell: cell_left.clone(),
|
||||||
|
direction: Direction::LEFT,
|
||||||
|
pos_x: left.0,
|
||||||
|
pos_y: left.1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if self.obstructed_from.contains(&cell_right.variance) {
|
||||||
|
return Some(Neighbour {
|
||||||
|
cell: cell_right.clone(),
|
||||||
|
direction: Direction::RIGHT,
|
||||||
|
pos_x: right.0,
|
||||||
|
pos_y: right.1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if self.obstructed_from.contains(&cell_top.variance) {
|
||||||
|
return Some(Neighbour {
|
||||||
|
cell: cell_top.clone(),
|
||||||
|
direction: Direction::TOP,
|
||||||
|
pos_x: top.0,
|
||||||
|
pos_y: top.1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if self.obstructed_from.contains(&cell_bottom.variance) {
|
||||||
|
return Some(Neighbour {
|
||||||
|
cell: cell_bottom.clone(),
|
||||||
|
direction: Direction::BOTTOM,
|
||||||
|
pos_x: bottom.0,
|
||||||
|
pos_y: bottom.1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_next(&mut self) {
|
pub fn move_next(&mut self) {
|
||||||
|
|||||||
14
src/stage.rs
14
src/stage.rs
@@ -10,7 +10,7 @@ use randomize::PCG32;
|
|||||||
|
|
||||||
use crate::cell::Cell;
|
use crate::cell::Cell;
|
||||||
use crate::cell::CellVariance;
|
use crate::cell::CellVariance;
|
||||||
use crate::direction::Direction;
|
use crate::direction::Coord;
|
||||||
use crate::npc::NPC;
|
use crate::npc::NPC;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -116,10 +116,10 @@ impl Stage {
|
|||||||
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, Coord::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, Coord::new(-1, -1));
|
||||||
}
|
}
|
||||||
CellVariance::VOID => {
|
CellVariance::VOID => {
|
||||||
// Ignore this stupid request.
|
// Ignore this stupid request.
|
||||||
@@ -173,7 +173,13 @@ impl Stage {
|
|||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
// Process bounce logic
|
// Process bounce logic
|
||||||
for npc in self.npcs.iter_mut() {
|
for npc in self.npcs.iter_mut() {
|
||||||
npc.process_bounce(&self.cells_dup);
|
match npc.process_bounce(&self.cells_dup) {
|
||||||
|
Some(n) => {
|
||||||
|
let c = self.cells[n.pos_x + n.pos_y * self.width];
|
||||||
|
self.cells[n.pos_x + n.pos_y * self.width] = c.invert();
|
||||||
|
},
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write current background
|
// Write current background
|
||||||
|
|||||||
Reference in New Issue
Block a user