From 54fafe8742933e70aeff65ae12db64fddf210c49 Mon Sep 17 00:00:00 2001 From: Nicolas Klier Date: Wed, 8 May 2024 12:32:16 +0200 Subject: [PATCH] Broken but funny bouncing. --- src/cell.rs | 8 ++++++ src/direction.rs | 5 ++++ src/npc.rs | 66 +++++++++++++++++++++++++++++++++++++++++++----- src/stage.rs | 49 +++++++++++++++++++++++++++-------- 4 files changed, 111 insertions(+), 17 deletions(-) diff --git a/src/cell.rs b/src/cell.rs index 6365701..44afcac 100644 --- a/src/cell.rs +++ b/src/cell.rs @@ -33,4 +33,12 @@ impl Cell { pub fn new(variance: CellVariance) -> Self { Self { variance } } + + pub fn invert(&self) -> Self { + Cell::new(match self.variance { + CellVariance::DAY => CellVariance::NIGHT, + CellVariance::NIGHT => CellVariance::DAY, + CellVariance::VOID => CellVariance::VOID + }) + } } \ No newline at end of file diff --git a/src/direction.rs b/src/direction.rs index e46b223..8351ff5 100644 --- a/src/direction.rs +++ b/src/direction.rs @@ -8,4 +8,9 @@ impl Direction { pub fn new(x: isize, y: isize) -> Self { Self { x, y } } + + pub fn invert(&mut self) { + self.x *= -1; + self.y *= -1; + } } \ No newline at end of file diff --git a/src/npc.rs b/src/npc.rs index 2409ff7..8306c72 100644 --- a/src/npc.rs +++ b/src/npc.rs @@ -6,19 +6,73 @@ pub struct NPC { pub obstructed_from: Vec, pub pos_x: usize, pub pos_y: usize, - pub direction: Direction + pub direction: Direction, } impl NPC { - 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( + 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: 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: 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, + } } -} \ No newline at end of file + + pub fn bounce(&mut self) -> Direction { + // Get the current and next positions + let (curr_x, curr_y) = (self.pos_x as isize, self.pos_y as isize); + let (next_x, next_y) = self.next_position(); + let mut next_direction = self.direction.clone(); + + // Hit top from below || Hit bottom from above + if curr_y < next_y || curr_y > next_y { + next_direction.y *= -1; + } + + // Hit right from left || Hit left from right + if next_x > curr_x || curr_x > next_x { + next_direction.x *= -1; + } + + // Return the new bounce direction + self.direction = next_direction; + + println!("Next: {:?}", self.direction); + self.direction.clone() + } + + pub fn next_position(&self) -> (isize, isize) { + ( + (self.pos_x as isize + self.direction.x), + (self.pos_y as isize + self.direction.y), + ) + } +} diff --git a/src/stage.rs b/src/stage.rs index d171583..a053928 100644 --- a/src/stage.rs +++ b/src/stage.rs @@ -148,7 +148,12 @@ impl Stage { } // Draw background - for (i, (mut c, pix)) in self.cells.iter().zip(screen.chunks_exact_mut(4)).enumerate() { + 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; @@ -169,25 +174,43 @@ impl Stage { } pub fn update(&mut self) { - // TODO: Flying balls + let mut hit_cells: Vec<(usize, usize)> = vec![]; + 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; + // if (npc.next_position().0 < 0 || npc.next_position().0 > self.width as isize) || + // (npc.next_position().1 < 0 || npc.next_position().1 > self.height as isize) { + // npc.bounce(); + // } + + // Check for collision with window borders + if npc.pos_x <= 0 || npc.pos_x >= self.width { + // Bounce off horizontally + npc.direction.x = -npc.direction.x; + // Move object back inside the window + npc.pos_x = npc.pos_x.clamp(0, self.width - 1); + } - let index = next_pos.0 as usize + next_pos.1 as usize * self.width; + if npc.pos_y <= 0 || npc.pos_y >= self.height { + // Bounce off vertically + npc.direction.y = -npc.direction.y; + // Move object back inside the window + npc.pos_y = npc.pos_y.clamp(0, self.height - 1); + } + + let index = + npc.next_position().0 as usize + npc.next_position().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 + npc.direction.invert(); + hit_cells.push((npc.next_position().0 as usize, npc.next_position().1 as usize)); continue; } - npc.pos_x = next_pos.0 as usize; - npc.pos_y = next_pos.1 as usize; + npc.pos_x = npc.next_position().0 as usize; + npc.pos_y = npc.next_position().1 as usize; // We can move freely for now. self.npc_map[index] = Some(Cell::new(npc.obstructed_from[0])); @@ -198,7 +221,11 @@ impl Stage { let idx = x + y * self.width; // Write into scratch_cells, since we're still reading from `self.cells` - self.cells_dup[idx] = self.cells[idx]; + if hit_cells.contains(&(x, y)) { + self.cells_dup[idx] = self.cells[idx].invert(); + } else { + self.cells_dup[idx] = self.cells[idx]; + } } }