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::controls::Controls;
|
||||||
use rusty::engine::renderer::Renderer;
|
use rusty::engine::renderer::Renderer;
|
||||||
use rusty::engine::map::Map;
|
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> {
|
fn parse_resolution(res: &str) -> Result<(u32, u32), String> {
|
||||||
let split = res.split('x').collect::<Vec<_>>();
|
let split = res.split('x').collect::<Vec<_>>();
|
||||||
|
@ -99,7 +99,9 @@ fn main() {
|
||||||
let duration = Instant::now().duration_since(after_loop);
|
let duration = Instant::now().duration_since(after_loop);
|
||||||
after_loop = Instant::now();
|
after_loop = Instant::now();
|
||||||
|
|
||||||
scene.update(&duration);
|
if scene.update(&duration) == State::Finished {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the view
|
// Update the view
|
||||||
if let Some(view) = scene.view() {
|
if let Some(view) = scene.view() {
|
||||||
|
|
|
@ -20,6 +20,19 @@ pub enum Side {
|
||||||
Right,
|
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 {
|
impl Side {
|
||||||
/// Returns the side corresponding to the force.
|
/// Returns the side corresponding to the force.
|
||||||
///
|
///
|
||||||
|
@ -57,6 +70,9 @@ pub struct Character {
|
||||||
/// The side of the character.
|
/// The side of the character.
|
||||||
side: Side,
|
side: Side,
|
||||||
|
|
||||||
|
/// The number of hp of the character.
|
||||||
|
hp: u32,
|
||||||
|
|
||||||
/// The counter of jumps.
|
/// The counter of jumps.
|
||||||
///
|
///
|
||||||
/// When it's 0, the character can no longer jump.
|
/// When it's 0, the character can no longer jump.
|
||||||
|
@ -82,6 +98,7 @@ impl Character {
|
||||||
speed: Vector2::new(0.0, 0.0),
|
speed: Vector2::new(0.0, 0.0),
|
||||||
controls,
|
controls,
|
||||||
side: Side::Right,
|
side: Side::Right,
|
||||||
|
hp: 1,
|
||||||
jump_counter: 1,
|
jump_counter: 1,
|
||||||
max_jump: 1,
|
max_jump: 1,
|
||||||
animation_timer: None,
|
animation_timer: None,
|
||||||
|
@ -138,6 +155,30 @@ impl Character {
|
||||||
pub fn bbox(&self) -> FloatRect {
|
pub fn bbox(&self) -> FloatRect {
|
||||||
FloatRect::new(self.position.x + 8.0, self.position.y + 16.0, 16.0, 16.0)
|
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 {
|
impl Updatable for Character {
|
||||||
|
|
|
@ -13,6 +13,7 @@ use crate::{Error, Result};
|
||||||
use crate::engine::math::{clamp, Matrix};
|
use crate::engine::math::{clamp, Matrix};
|
||||||
use crate::engine::renderer::Drawable;
|
use crate::engine::renderer::Drawable;
|
||||||
use crate::engine::texture::Texture;
|
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.
|
/// This enum represents if the collision happens on the X axis or the Y axis.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -436,7 +437,10 @@ impl Map {
|
||||||
&self,
|
&self,
|
||||||
old: FloatRect,
|
old: FloatRect,
|
||||||
new: FloatRect,
|
new: FloatRect,
|
||||||
) -> Option<(CollisionAxis, Vector2<f32>)> {
|
) -> Option<(CollisionAxis, Vector2<f32>, Damage)> {
|
||||||
|
|
||||||
|
let mut damage = Damage::None;
|
||||||
|
|
||||||
let cols = self.tiles.cols() - 1;
|
let cols = self.tiles.cols() - 1;
|
||||||
let rows = self.tiles.rows() - 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);
|
let new_pos = Vector2::new(new.left, new.top);
|
||||||
match (collision_x, collision_y) {
|
match (collision_x, collision_y) {
|
||||||
(true, true) => Some((CollisionAxis::Both, new_pos)),
|
(true, true) => Some((CollisionAxis::Both, new_pos, damage)),
|
||||||
(true, false) => Some((CollisionAxis::X, new_pos)),
|
(true, false) => Some((CollisionAxis::X, new_pos, damage)),
|
||||||
(false, true) => Some((CollisionAxis::Y, new_pos)),
|
(false, true) => Some((CollisionAxis::Y, new_pos, damage)),
|
||||||
(false, false) => None,
|
(false, false) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,16 @@ pub struct Scene {
|
||||||
map: Map,
|
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 {
|
impl Scene {
|
||||||
/// Creates a scene from a map level.
|
/// Creates a scene from a map level.
|
||||||
pub fn from_map(map: Map) -> Scene {
|
pub fn from_map(map: Map) -> Scene {
|
||||||
|
@ -74,7 +84,10 @@ impl Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the whole 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 {
|
for c in &mut self.characters {
|
||||||
let old = c.bbox();
|
let old = c.bbox();
|
||||||
|
|
||||||
|
@ -83,7 +96,7 @@ impl Scene {
|
||||||
|
|
||||||
c.update(duration);
|
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;
|
c.position = position - offset;
|
||||||
if axis.is_x() {
|
if axis.is_x() {
|
||||||
c.speed.x = 0.0;
|
c.speed.x = 0.0;
|
||||||
|
@ -92,10 +105,19 @@ impl Scene {
|
||||||
c.speed.y = 0.0;
|
c.speed.y = 0.0;
|
||||||
c.ground_collision();
|
c.ground_collision();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.take_damage(damage);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
c.fall_off();
|
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.
|
/// Transfers an event to the elements contained in the scene that should receive events.
|
||||||
|
|
Loading…
Reference in New Issue