Compare commits

..

2 Commits

Author SHA1 Message Date
97435fbd4e Apparently the bounce is still broken. It always was. 2024-05-09 00:44:04 +02:00
c75c598a53 Fix bouncing 2024-05-08 23:27:37 +02:00
3 changed files with 156 additions and 55 deletions

View File

@@ -1,10 +1,10 @@
#[derive(Clone, Debug)]
pub struct Direction {
pub struct Coord {
pub x: isize,
pub y: isize
}
impl Direction {
impl Coord {
pub fn new(x: isize, y: isize) -> Self {
Self { x, y }
}

View File

@@ -1,4 +1,27 @@
use crate::{cell::{Cell, CellVariance}, direction::Direction, stage::{self, Stage}, HEIGHT, WIDTH};
use std::cell;
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)]
pub struct Neighbour {
pub cell: Cell,
pub direction: Direction,
pub pos_x: usize,
pub pos_y: usize,
}
#[derive(Clone, Debug)]
pub struct NPC {
@@ -6,40 +29,24 @@ pub struct NPC {
pub obstructed_from: Vec<CellVariance>,
pub pos_x: usize,
pub pos_y: usize,
pub direction: Direction,
pub direction: Coord,
}
impl NPC {
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,
}
}
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 {
walk_on: CellVariance::DAY,
obstructed_from: vec![CellVariance::NIGHT],
obstructed_from: vec![CellVariance::NIGHT, CellVariance::VOID],
pos_x,
pos_y,
direction,
}
}
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 {
walk_on: CellVariance::NIGHT,
obstructed_from: vec![CellVariance::DAY],
obstructed_from: vec![CellVariance::DAY, CellVariance::VOID],
pos_x,
pos_y,
direction,
@@ -51,41 +58,130 @@ impl NPC {
Cell::new(self.obstructed_from[0])
}
pub fn process_bounce(&mut self, mut stage: &Stage) {
println!("Calc bounce for {:?}", self);
let obstacle = self.next_position();
pub fn process_bounce(&mut self, map: &Vec<Cell>) -> Option<Neighbour> {
// Get the current and next positions
let (curr_x, curr_y) = (self.pos_x, self.pos_y);
let (next_x, next_y) = obstacle;
let mut next_direction = self.direction.clone();
// 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;
}
// Hit top from below || Hit bottom from above
let hit_head = next_y > curr_y || curr_y > next_y;
// Return the new bounce direction
self.direction = next_direction;
// Hit right from left || Hit left from right
let hit_side = next_x > curr_x || curr_x > next_x;
self.move_next();
if hit_head {
next_direction.y *= -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
}
}
// Hit right from left || Hit left from right
if hit_side {
next_direction.x *= -1;
}
// Return the new bounce direction
self.direction = next_direction;
let _ = self.pos_x.checked_add_signed(self.direction.x);
let _ = self.pos_y.checked_add_signed(self.direction.y);
}
pub fn next_position(&self) -> (usize, 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) {
let mov_x = self.pos_x.checked_add_signed(self.direction.x);
let mov_y = self.pos_y.checked_add_signed(self.direction.y);
if mov_x.is_none() || mov_y.is_none() {
println!("Illegal move prevented");
} else {
self.pos_x = mov_x.unwrap();
self.pos_y = mov_y.unwrap();
}
}
pub fn next_position(&self) -> (Option<usize>, Option<usize>) {
(
(self.pos_x as isize + self.direction.x).clamp(0, WIDTH.try_into().unwrap()) as usize,
(self.pos_y as isize + self.direction.y).clamp(0, HEIGHT.try_into().unwrap()) as usize
(self.pos_x.checked_add_signed(self.direction.x)),
(self.pos_y.checked_add_signed(self.direction.y)),
)
}
}

View File

@@ -10,7 +10,7 @@ use randomize::PCG32;
use crate::cell::Cell;
use crate::cell::CellVariance;
use crate::direction::Direction;
use crate::direction::Coord;
use crate::npc::NPC;
#[derive(Debug, Clone)]
@@ -116,10 +116,10 @@ impl Stage {
let npc: NPC;
match cell.variance {
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 => {
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 => {
// Ignore this stupid request.
@@ -173,8 +173,13 @@ impl Stage {
pub fn update(&mut self) {
// Process bounce logic
for npc in self.npcs.iter_mut() {
let me = &self;
npc.process_bounce(self);
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