monsters move and attack the player

This commit is contained in:
2023-12-26 19:11:41 +01:00
parent 2098bedabe
commit b88bc67c50
5 changed files with 57 additions and 12 deletions

View File

@@ -9,6 +9,8 @@ use crate::monster::Monster;
use crate::player::Player;
use crate::position::HasPosition;
use crate::position::Position;
use rand::Rng;
use rand::rngs::ThreadRng;
pub const LEVEL_WIDTH: usize = 50;
pub const LEVEL_HEIGHT: usize = 25;
@@ -34,6 +36,7 @@ pub struct Level {
pub(crate) start: (usize, usize),
/// the position of the end in the level (either stair down or end point)
pub(crate) end: (usize, usize),
pub(crate) rng: ThreadRng,
}
impl Level {
@@ -108,7 +111,7 @@ impl Level {
}
}
}
pub fn update(&mut self) {
pub fn update(&mut self, ticks: u128, player: &mut Player) {
for (index, a) in &mut self.artifacts.iter().enumerate() {
if a.was_collected() {
self.artifacts.remove(index);
@@ -122,17 +125,43 @@ impl Level {
}
}
for index in 0..self.monsters.len() {
if self.can_monster_move(self.monsters[index].as_ref(), 0, 1) {
self.monsters[index].get_position().change(0, 1);
} else if self.can_monster_move(self.monsters[index].as_ref(), 0, -1) {
self.monsters[index].get_position().change(0, -1);
if ticks % self.monsters[index].get_ticks_between_steps() != 0 {
continue;
}
loop {
// calculate the direction the monster will try to walk
let (dx, dy) = match self.rng.gen_range(0..5) {
1 => { (1, 0) }
2 => { (-1, 0) }
3 => { (0, 1) }
4 => { (0, -1) }
_ => { (0, 0) }
};
if self.can_monster_move(self.monsters[index].as_ref(), dx, dy) {
let (new_x, new_y) = self.monsters[index].get_position().change(dx, dy);
if player.get_immutable_position().get_x() == new_x && player.get_immutable_position().get_y() == new_y {
self.monsters[index].decrease_life(1);
player.change_life(-1);
}
break;
}
}
}
}
pub fn can_monster_move(&self, agent: &dyn Monster, dx: i16, dy: i16) -> bool {
let agent_pos = agent.get_immutable_position();
let new_x: usize = (agent_pos.get_x() as i16 + dx) as usize;
let new_y: usize = (agent_pos.get_y() as i16 + dy) as usize;
if new_x < 0 || new_y < 0 || new_x >= LEVEL_WIDTH || new_y >= LEVEL_HEIGHT {
return false;
}
for index in 0..self.monsters.len() {
let pos = self.monsters[index].get_immutable_position();
if pos.get_x() == new_x && pos.get_y() == new_y { return false; }
}
self.structure[new_x][new_y] != StructureElement::Wall
}
pub fn can_player_move(&self, agent: &Player, dx: i16, dy: i16) -> bool {
@@ -157,6 +186,7 @@ impl Level {
artifacts: Vec::with_capacity(10),
start: (0, 0),
end: (0, 0),
rng: rand::thread_rng(),
}
}
#[cfg(test)]