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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user