Collisions with border of level, death
This commit is contained in:
parent
2ff29eb0c6
commit
93171a5123
|
@ -8,7 +8,7 @@ use rusty::engine::character::Character;
|
|||
use rusty::engine::controls::Controls;
|
||||
use rusty::engine::renderer::Renderer;
|
||||
use rusty::engine::map::Map;
|
||||
use rusty::engine::scene::Scene;
|
||||
use rusty::engine::scene::{Scene, State};
|
||||
|
||||
fn parse_resolution(res: &str) -> Result<(u32, u32), String> {
|
||||
let split = res.split('x').collect::<Vec<_>>();
|
||||
|
@ -99,7 +99,9 @@ fn main() {
|
|||
let duration = Instant::now().duration_since(after_loop);
|
||||
after_loop = Instant::now();
|
||||
|
||||
scene.update(&duration);
|
||||
if scene.update(&duration) == State::Finished {
|
||||
running = false;
|
||||
}
|
||||
|
||||
// Update the view
|
||||
if let Some(view) = scene.view() {
|
||||
|
|
|
@ -20,6 +20,19 @@ pub enum Side {
|
|||
Right,
|
||||
}
|
||||
|
||||
/// This enum represents the type of damages that the character can get.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Damage {
|
||||
/// No damage were made
|
||||
None,
|
||||
|
||||
/// A single point of life has been taken from the character.
|
||||
One,
|
||||
|
||||
/// The character died.
|
||||
Death,
|
||||
}
|
||||
|
||||
impl Side {
|
||||
/// Returns the side corresponding to the force.
|
||||
///
|
||||
|
@ -57,6 +70,9 @@ pub struct Character {
|
|||
/// The side of the character.
|
||||
side: Side,
|
||||
|
||||
/// The number of hp of the character.
|
||||
hp: u32,
|
||||
|
||||
/// The counter of jumps.
|
||||
///
|
||||
/// When it's 0, the character can no longer jump.
|
||||
|
@ -82,6 +98,7 @@ impl Character {
|
|||
speed: Vector2::new(0.0, 0.0),
|
||||
controls,
|
||||
side: Side::Right,
|
||||
hp: 1,
|
||||
jump_counter: 1,
|
||||
max_jump: 1,
|
||||
animation_timer: None,
|
||||
|
@ -138,6 +155,30 @@ impl Character {
|
|||
pub fn bbox(&self) -> FloatRect {
|
||||
FloatRect::new(self.position.x + 8.0, self.position.y + 16.0, 16.0, 16.0)
|
||||
}
|
||||
|
||||
/// Returns the number of hp of the character.
|
||||
pub fn hp(&self) -> u32 {
|
||||
self.hp
|
||||
}
|
||||
|
||||
/// Returns true if the character is alive.
|
||||
pub fn is_alive(&self) -> bool {
|
||||
self.hp > 0
|
||||
}
|
||||
|
||||
/// Returns true if the character is dead.
|
||||
pub fn is_dead(&self) -> bool {
|
||||
self.hp == 0
|
||||
}
|
||||
|
||||
/// Takes the corresponding damage.
|
||||
pub fn take_damage(&mut self, damage: Damage) {
|
||||
match damage {
|
||||
Damage::None => (),
|
||||
Damage::One => self.hp -= 1,
|
||||
Damage::Death => self.hp = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Updatable for Character {
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::{Error, Result};
|
|||
use crate::engine::math::{clamp, Matrix};
|
||||
use crate::engine::renderer::Drawable;
|
||||
use crate::engine::texture::Texture;
|
||||
use crate::engine::character::Damage;
|
||||
|
||||
/// This enum represents if the collision happens on the X axis or the Y axis.
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -436,7 +437,10 @@ impl Map {
|
|||
&self,
|
||||
old: FloatRect,
|
||||
new: FloatRect,
|
||||
) -> Option<(CollisionAxis, Vector2<f32>)> {
|
||||
) -> Option<(CollisionAxis, Vector2<f32>, Damage)> {
|
||||
|
||||
let mut damage = Damage::None;
|
||||
|
||||
let cols = self.tiles.cols() - 1;
|
||||
let rows = self.tiles.rows() - 1;
|
||||
|
||||
|
@ -511,11 +515,30 @@ impl Map {
|
|||
}
|
||||
}
|
||||
|
||||
// Collision between the player and left border of the level
|
||||
if new.left < 0.0 {
|
||||
new.left = 0.0;
|
||||
collision_x = true;
|
||||
}
|
||||
|
||||
// Collision between the player and right border of the level
|
||||
if new.left > cols as f32 * 16.0 {
|
||||
new.left = cols as f32 * 16.0;
|
||||
collision_x = true;
|
||||
}
|
||||
|
||||
// Collision between the player and the void
|
||||
if new.top > self.tiles.rows() as f32 * 16.0 {
|
||||
new.top = self.tiles.rows() as f32 * 16.0;
|
||||
collision_y = true;
|
||||
damage = Damage::Death;
|
||||
}
|
||||
|
||||
let new_pos = Vector2::new(new.left, new.top);
|
||||
match (collision_x, collision_y) {
|
||||
(true, true) => Some((CollisionAxis::Both, new_pos)),
|
||||
(true, false) => Some((CollisionAxis::X, new_pos)),
|
||||
(false, true) => Some((CollisionAxis::Y, new_pos)),
|
||||
(true, true) => Some((CollisionAxis::Both, new_pos, damage)),
|
||||
(true, false) => Some((CollisionAxis::X, new_pos, damage)),
|
||||
(false, true) => Some((CollisionAxis::Y, new_pos, damage)),
|
||||
(false, false) => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,16 @@ pub struct Scene {
|
|||
map: Map,
|
||||
}
|
||||
|
||||
/// The type used to represent whether a a scene is running or finished.
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum State {
|
||||
/// The scene is running.
|
||||
Running,
|
||||
|
||||
/// The scene is finished.
|
||||
Finished,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
/// Creates a scene from a map level.
|
||||
pub fn from_map(map: Map) -> Scene {
|
||||
|
@ -74,7 +84,10 @@ impl Scene {
|
|||
}
|
||||
|
||||
/// Updates the whole scene.
|
||||
pub fn update(&mut self, duration: &Duration) {
|
||||
pub fn update(&mut self, duration: &Duration) -> State {
|
||||
|
||||
let mut state = State::Finished;
|
||||
|
||||
for c in &mut self.characters {
|
||||
let old = c.bbox();
|
||||
|
||||
|
@ -83,7 +96,7 @@ impl Scene {
|
|||
|
||||
c.update(duration);
|
||||
|
||||
if let Some((axis, position)) = self.map.collides_bbox(old, c.bbox()) {
|
||||
if let Some((axis, position, damage)) = self.map.collides_bbox(old, c.bbox()) {
|
||||
c.position = position - offset;
|
||||
if axis.is_x() {
|
||||
c.speed.x = 0.0;
|
||||
|
@ -92,10 +105,19 @@ impl Scene {
|
|||
c.speed.y = 0.0;
|
||||
c.ground_collision();
|
||||
}
|
||||
|
||||
c.take_damage(damage);
|
||||
|
||||
} else {
|
||||
c.fall_off();
|
||||
}
|
||||
|
||||
if c.controls().is_some() && c.is_alive() {
|
||||
state = State::Running;
|
||||
}
|
||||
}
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
/// Transfers an event to the elements contained in the scene that should receive events.
|
||||
|
|
Loading…
Reference in New Issue