151 lines
4.3 KiB
Rust
151 lines
4.3 KiB
Rust
//! This module contains the scene struct which holds everything needed during a game.
|
|
|
|
use std::time::Duration;
|
|
|
|
use crate::engine::character::Character;
|
|
use crate::engine::map::Map;
|
|
use crate::engine::texture::SPRITE_SIZE;
|
|
|
|
/// Contains everything needed to play.
|
|
pub struct Scene {
|
|
/// The characters contained in the scene.
|
|
characters: Vec<Character>,
|
|
|
|
/// The map of the 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 {
|
|
Scene {
|
|
characters: vec![],
|
|
map,
|
|
}
|
|
}
|
|
|
|
/// Adds a character to the scene.
|
|
pub fn add(&mut self, character: Character) {
|
|
let mut character = character;
|
|
character.position.x = self.map.entrance().1 * SPRITE_SIZE;
|
|
character.position.y = self.map.entrance().0 * SPRITE_SIZE;
|
|
|
|
self.characters.push(character);
|
|
}
|
|
|
|
/// Returns the controlable.
|
|
fn controlable(&self) -> Option<&Character> {
|
|
for character in &self.characters {
|
|
if character.controls().is_some() {
|
|
return Some(&character);
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
// /// Returns the right view.
|
|
// pub fn view(&self) -> Option<View> {
|
|
// let view = self.controlable()?.view();
|
|
// let mut center = view.center();
|
|
// let size = view.size();
|
|
|
|
// // Clamp center so that the view doesn't show things outside the level.
|
|
// if center.x - size.x / 2.0 < 0.0 {
|
|
// center.x = size.x / 2.0;
|
|
// }
|
|
|
|
// if center.y - size.y / 2.0 < 0.0 {
|
|
// center.y = size.y / 2.0;
|
|
// }
|
|
|
|
// let right_limit = self.map.cols() as f32 * SPRITE_SIZE_F32;
|
|
// let bottom_limit = self.map.rows() as f32 * SPRITE_SIZE_F32;
|
|
|
|
// if center.x + size.x / 2.0 > right_limit {
|
|
// center.x = right_limit - size.x / 2.0;
|
|
// }
|
|
|
|
// if center.y + size.y / 2.0 > bottom_limit {
|
|
// center.y = bottom_limit - size.y / 2.0;
|
|
// }
|
|
|
|
// Some(View::new(center, size))
|
|
// }
|
|
|
|
/// Updates the whole scene.
|
|
pub fn update(&mut self, duration: &Duration) -> State {
|
|
let mut state = State::Finished;
|
|
|
|
for c in &mut self.characters {
|
|
// Don't need to update if the character is dead
|
|
// if c.is_alive() {
|
|
if true {
|
|
let old = c.bbox();
|
|
|
|
// Compute the offset between position and bbox
|
|
let offset = old.position - c.position;
|
|
|
|
c.update(duration);
|
|
|
|
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;
|
|
}
|
|
if axis.is_y() {
|
|
c.speed.y = 0.0;
|
|
c.ground_collision();
|
|
}
|
|
|
|
c.die();
|
|
} else {
|
|
c.fall_off();
|
|
}
|
|
|
|
// If a character is alive and still have controls, the game should continue
|
|
if c.controls().is_some() {
|
|
state = State::Running;
|
|
}
|
|
}
|
|
}
|
|
|
|
state
|
|
}
|
|
|
|
// /// Transfers an event to the elements contained in the scene that should receive events.
|
|
// pub fn manage_event(&mut self, event: &Event) {
|
|
// for c in &mut self.characters {
|
|
// c.manage_event(event);
|
|
// }
|
|
// }
|
|
|
|
/// Returns a reference to the characters of the scene.
|
|
pub fn characters(&self) -> &Vec<Character> {
|
|
&self.characters
|
|
}
|
|
|
|
/// Returns a reference to the map.
|
|
pub fn map(&self) -> &Map {
|
|
&self.map
|
|
}
|
|
}
|
|
|
|
/// Trait that needs to be implemented for everything that can be updatable.
|
|
pub trait Updatable {
|
|
/// Updates the thing depending on the duration since last frame.
|
|
fn update(&mut self, duration: &Duration);
|
|
|
|
// /// Called when an event arrives.
|
|
// fn manage_event(&mut self, event: &Event);
|
|
}
|