Something that compiles
This commit is contained in:
parent
96f3b3f33c
commit
466760c6a7
@ -3,6 +3,7 @@
|
||||
use crate::engine::vector::Vector;
|
||||
|
||||
/// This struct represents a bounding box.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Bbox {
|
||||
/// The position of the top right corner of the box.
|
||||
pub position: Vector,
|
||||
|
@ -3,17 +3,13 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::controls::Controls;
|
||||
use crate::engine::event::Keyboard;
|
||||
use crate::engine::math::{clamp, duration_as_f64};
|
||||
use crate::engine::physics;
|
||||
use crate::engine::scene::Updatable;
|
||||
use crate::engine::vector::Vector;
|
||||
|
||||
use crate::engine::controls::Controls;
|
||||
use crate::engine::math::{clamp, duration_as_f64, duration_as_frame};
|
||||
// use crate::engine::physics;
|
||||
// use crate::engine::renderer::Drawable;
|
||||
// use crate::engine::scene::Updatable;
|
||||
// use crate::engine::texture::Texture;
|
||||
|
||||
/// The different sides a character can face.
|
||||
pub enum Side {
|
||||
/// The character looks to the left.
|
||||
@ -148,11 +144,11 @@ impl Character {
|
||||
}
|
||||
|
||||
impl Updatable for Character {
|
||||
fn update(&mut self, duration: &Duration) {
|
||||
fn update(&mut self, duration: &Duration, keyboard: &Keyboard) {
|
||||
let mut force = Vector::new(0.0, 0.0);
|
||||
|
||||
if let Some(ref controls) = self.controls {
|
||||
force += controls.direction();
|
||||
force += controls.direction(keyboard);
|
||||
}
|
||||
|
||||
if let Some(side) = Side::from_force(force) {
|
||||
@ -182,7 +178,7 @@ impl Updatable for Character {
|
||||
}
|
||||
|
||||
let limit = match self.controls {
|
||||
Some(controls) if controls.is_running() => physics::MAXIMUM_RUNNING_SPEED,
|
||||
Some(ref controls) if controls.is_running() => physics::MAXIMUM_RUNNING_SPEED,
|
||||
_ => physics::MAXIMUM_WALKING_SPEED,
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! This module helps to deal with controls.
|
||||
|
||||
use crate::engine::event::{Event, Key};
|
||||
use crate::engine::event::{Event, Key, Keyboard};
|
||||
use crate::engine::vector::Vector;
|
||||
|
||||
/// The different actions that a user can do.
|
||||
@ -52,9 +52,9 @@ impl Controls {
|
||||
}
|
||||
|
||||
/// Returns the direction of the controls.
|
||||
pub fn direction(&self) -> Vector {
|
||||
pub fn direction(&self, keyboard: &Keyboard) -> Vector {
|
||||
match self {
|
||||
Controls::Keyboard(ref map) => map.direction(),
|
||||
Controls::Keyboard(ref map) => map.direction(keyboard),
|
||||
// Controls::Gamepad(ref map) => map.direction(),
|
||||
}
|
||||
}
|
||||
@ -106,14 +106,14 @@ impl KeyboardMap {
|
||||
}
|
||||
|
||||
/// Returns the direction of the keys.
|
||||
pub fn direction(&self) -> Vector {
|
||||
pub fn direction(&self, keyboard: &Keyboard) -> Vector {
|
||||
let mut ret = Vector::new(0.0, 0.0);
|
||||
const RIGHT: Vector = Vector { x: 1.0, y: 0.0 };
|
||||
|
||||
if self.right_key.is_pressed() {
|
||||
if keyboard.is_key_pressed(self.right_key) {
|
||||
ret += RIGHT;
|
||||
}
|
||||
if self.left_key.is_pressed() {
|
||||
if keyboard.is_key_pressed(self.left_key) {
|
||||
ret -= RIGHT;
|
||||
}
|
||||
ret
|
||||
|
@ -1 +0,0 @@
|
||||
//! A module that makes it easier to deal with images.
|
@ -4,14 +4,66 @@ use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
||||
use sfml::graphics::{FloatRect, IntRect};
|
||||
use sfml::system::Vector2;
|
||||
|
||||
use crate::engine::character::Damage;
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::math::{clamp, Matrix};
|
||||
use crate::engine::renderer::Drawable;
|
||||
use crate::engine::texture::{byte_to_index, Texture, SPRITE_SIZE_F32, SPRITE_SIZE_I32};
|
||||
use crate::{Error, Result};
|
||||
use crate::engine::texture::SPRITE_SIZE;
|
||||
use crate::engine::vector::Vector;
|
||||
use crate::Result;
|
||||
|
||||
/// Converts the byte with bits corresponding to the neighbours to the offset on the generated
|
||||
/// tileset.
|
||||
pub fn byte_to_index(byte: u8) -> i32 {
|
||||
match byte {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
4 => 2,
|
||||
5 => 3,
|
||||
7 => 4,
|
||||
16 => 5,
|
||||
17 => 6,
|
||||
20 => 7,
|
||||
21 => 8,
|
||||
23 => 9,
|
||||
28 => 10,
|
||||
29 => 11,
|
||||
31 => 12,
|
||||
64 => 13,
|
||||
65 => 14,
|
||||
68 => 15,
|
||||
69 => 16,
|
||||
71 => 17,
|
||||
80 => 18,
|
||||
81 => 19,
|
||||
84 => 20,
|
||||
85 => 21,
|
||||
87 => 22,
|
||||
92 => 23,
|
||||
93 => 24,
|
||||
95 => 25,
|
||||
112 => 26,
|
||||
113 => 27,
|
||||
116 => 28,
|
||||
117 => 29,
|
||||
119 => 30,
|
||||
124 => 31,
|
||||
125 => 32,
|
||||
127 => 33,
|
||||
193 => 34,
|
||||
197 => 35,
|
||||
199 => 36,
|
||||
209 => 37,
|
||||
213 => 38,
|
||||
215 => 39,
|
||||
221 => 40,
|
||||
223 => 41,
|
||||
241 => 42,
|
||||
245 => 43,
|
||||
247 => 44,
|
||||
253 => 45,
|
||||
255 => 46,
|
||||
_ => panic!("Incorrect byte {}", byte),
|
||||
}
|
||||
}
|
||||
|
||||
/// This enum represents if the collision happens on the X axis or the Y axis.
|
||||
#[derive(Copy, Clone)]
|
||||
@ -175,23 +227,23 @@ pub struct PositionedTile {
|
||||
pub collision: CollisionTile,
|
||||
|
||||
/// The position of the positioned tile.
|
||||
pub position: (f32, f32),
|
||||
pub position: Vector,
|
||||
}
|
||||
|
||||
impl Drawable for PositionedTile {
|
||||
fn texture(&self) -> Texture {
|
||||
Texture::Overworld
|
||||
}
|
||||
|
||||
fn texture_rect(&self) -> IntRect {
|
||||
let offset = self.graphic.offset();
|
||||
IntRect::new(offset.0, offset.1, SPRITE_SIZE_I32, SPRITE_SIZE_I32)
|
||||
}
|
||||
|
||||
fn position(&self) -> Vector2<f32> {
|
||||
self.position.into()
|
||||
}
|
||||
}
|
||||
// impl Drawable for PositionedTile {
|
||||
// fn texture(&self) -> Texture {
|
||||
// Texture::Overworld
|
||||
// }
|
||||
//
|
||||
// fn texture_rect(&self) -> Bbox {
|
||||
// let offset = self.graphic.offset();
|
||||
// Bbox::new(offset.x, offset.x, SPRITE_SIZE, SPRITE_SIZE)
|
||||
// }
|
||||
//
|
||||
// fn position(&self) -> Vector {
|
||||
// self.position
|
||||
// }
|
||||
// }
|
||||
|
||||
/// The map represents the tiles contained in a level.
|
||||
#[derive(Clone)]
|
||||
@ -219,14 +271,6 @@ impl Map {
|
||||
Map::from_collision_tiles(tiles)
|
||||
}
|
||||
|
||||
/// Loads a map from a file.
|
||||
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Map> {
|
||||
let mut file = File::open(path.as_ref()).map_err(Error::Load)?;
|
||||
let mut s = String::new();
|
||||
file.read_to_string(&mut s).map_err(Error::Load)?;
|
||||
Map::from_str(&s)
|
||||
}
|
||||
|
||||
/// Loads a map from a string.
|
||||
pub fn from_str(text: &str) -> Result<Map> {
|
||||
let split = text.split('\n').collect::<Vec<_>>();
|
||||
@ -390,7 +434,7 @@ impl Map {
|
||||
PositionedTile {
|
||||
collision: self.collision_tiles[(row, col)],
|
||||
graphic: self.graphic_tiles[(row, col)],
|
||||
position: (col as f32 * SPRITE_SIZE_F32, row as f32 * SPRITE_SIZE_F32),
|
||||
position: Vector::new(col as f64 * SPRITE_SIZE, row as f64 * SPRITE_SIZE),
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,21 +451,26 @@ impl Map {
|
||||
/// Checks whether the bounding box collides with elements of the map.
|
||||
///
|
||||
/// Returns the new correct position.
|
||||
pub fn collides_bbox(
|
||||
&self,
|
||||
old: Bbox,
|
||||
new: Bbox,
|
||||
) -> Option<(CollisionAxis, Vector2<f32>, Damage)> {
|
||||
let mut damage = Damage::None;
|
||||
pub fn collides_bbox(&self, old: Bbox, new: Bbox) -> Option<(CollisionAxis, Vector, bool)> {
|
||||
let mut death = false;
|
||||
|
||||
let cols = self.collision_tiles.cols() - 1;
|
||||
let rows = self.collision_tiles.rows() - 1;
|
||||
|
||||
let min_col = clamp(new.left / SPRITE_SIZE_F32, 0.0, cols as f32) as usize;
|
||||
let min_row = clamp(new.top / SPRITE_SIZE_F32, 0.0, rows as f32) as usize;
|
||||
let min_col = clamp(new.position.x / SPRITE_SIZE, 0.0, cols as f64) as usize;
|
||||
let min_row = clamp(new.position.y / SPRITE_SIZE, 0.0, rows as f64) as usize;
|
||||
|
||||
let max_col = clamp((new.left + new.width) / SPRITE_SIZE_F32, 0.0, cols as f32) as usize;
|
||||
let max_row = clamp((new.top + new.height) / SPRITE_SIZE_F32, 0.0, rows as f32) as usize;
|
||||
let max_col = clamp(
|
||||
(new.position.x + new.size.x) / SPRITE_SIZE,
|
||||
0.0,
|
||||
cols as f64,
|
||||
) as usize;
|
||||
|
||||
let max_row = clamp(
|
||||
(new.position.y + new.size.y) / SPRITE_SIZE,
|
||||
0.0,
|
||||
rows as f64,
|
||||
) as usize;
|
||||
|
||||
let mut collision_x = false;
|
||||
let mut collision_y = false;
|
||||
@ -429,10 +478,10 @@ impl Map {
|
||||
|
||||
for col in min_col..=max_col {
|
||||
for row in min_row..=max_row {
|
||||
let tile_left = col as f32 * SPRITE_SIZE_F32;
|
||||
let tile_top = row as f32 * SPRITE_SIZE_F32;
|
||||
let tile_left = col as f64 * SPRITE_SIZE;
|
||||
let tile_top = row as f64 * SPRITE_SIZE;
|
||||
|
||||
let tile = Bbox::new(tile_left, tile_top, SPRITE_SIZE_F32, SPRITE_SIZE_F32);
|
||||
let tile = Bbox::new(tile_left, tile_top, SPRITE_SIZE, SPRITE_SIZE);
|
||||
|
||||
if !overlap(new, tile) {
|
||||
continue;
|
||||
@ -440,11 +489,11 @@ impl Map {
|
||||
|
||||
// Collisions between feet and ground
|
||||
if self.collision_tiles[(row, col)].from_top
|
||||
&& old.top + old.height <= tile_top
|
||||
&& new.top + new.height >= tile_top
|
||||
&& old.position.y + old.size.y <= tile_top
|
||||
&& new.position.y + new.size.y >= tile_top
|
||||
{
|
||||
collision_y = true;
|
||||
new.top = tile_top - new.height;
|
||||
new.position.y = tile_top - new.size.y;
|
||||
}
|
||||
|
||||
if !overlap(new, tile) {
|
||||
@ -453,11 +502,11 @@ impl Map {
|
||||
|
||||
// Collisions between right and right wall
|
||||
if self.collision_tiles[(row, col)].from_left
|
||||
&& old.left + old.width <= tile_left
|
||||
&& new.left + new.width >= tile_left
|
||||
&& old.position.x + old.size.x <= tile_left
|
||||
&& new.position.x + new.size.x >= tile_left
|
||||
{
|
||||
collision_x = true;
|
||||
new.left = tile_left - new.width;
|
||||
new.position.x = tile_left - new.size.x;
|
||||
}
|
||||
|
||||
if !overlap(new, tile) {
|
||||
@ -466,11 +515,11 @@ impl Map {
|
||||
|
||||
// Collisions between left and left wall
|
||||
if self.collision_tiles[(row, col)].from_right
|
||||
&& old.left >= tile_left + SPRITE_SIZE_F32
|
||||
&& new.left <= tile_left + SPRITE_SIZE_F32
|
||||
&& old.position.x >= tile_left + SPRITE_SIZE
|
||||
&& new.position.x <= tile_left + SPRITE_SIZE
|
||||
{
|
||||
collision_x = true;
|
||||
new.left = tile_left + SPRITE_SIZE_F32;
|
||||
new.position.x = tile_left + SPRITE_SIZE;
|
||||
}
|
||||
|
||||
if !overlap(new, tile) {
|
||||
@ -479,39 +528,38 @@ impl Map {
|
||||
|
||||
// Collisions between head and roof
|
||||
if self.collision_tiles[(row, col)].from_bottom
|
||||
&& old.top >= tile_top + SPRITE_SIZE_F32
|
||||
&& new.top <= tile_top + SPRITE_SIZE_F32
|
||||
&& old.position.y >= tile_top + SPRITE_SIZE
|
||||
&& new.position.y <= tile_top + SPRITE_SIZE
|
||||
{
|
||||
collision_y = true;
|
||||
new.top = tile_top + SPRITE_SIZE_F32;
|
||||
new.position.y = tile_top + SPRITE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collision between the player and left border of the level
|
||||
if new.left < 0.0 {
|
||||
new.left = 0.0;
|
||||
if new.position.x < 0.0 {
|
||||
new.position.x = 0.0;
|
||||
collision_x = true;
|
||||
}
|
||||
|
||||
// Collision between the player and right border of the level
|
||||
if new.left > cols as f32 * SPRITE_SIZE_F32 {
|
||||
new.left = cols as f32 * SPRITE_SIZE_F32;
|
||||
if new.position.x > cols as f64 * SPRITE_SIZE {
|
||||
new.position.x = cols as f64 * SPRITE_SIZE;
|
||||
collision_x = true;
|
||||
}
|
||||
|
||||
// Collision between the player and the void
|
||||
if new.top > self.collision_tiles.rows() as f32 * SPRITE_SIZE_F32 {
|
||||
new.top = self.collision_tiles.rows() as f32 * SPRITE_SIZE_F32;
|
||||
if new.position.y > self.collision_tiles.rows() as f64 * SPRITE_SIZE {
|
||||
new.position.y = self.collision_tiles.rows() as f64 * SPRITE_SIZE;
|
||||
collision_y = true;
|
||||
damage = Damage::Death;
|
||||
death = true;
|
||||
}
|
||||
|
||||
let new_pos = Vector2::new(new.left, new.top);
|
||||
match (collision_x, collision_y) {
|
||||
(true, true) => Some((CollisionAxis::Both, new_pos, damage)),
|
||||
(true, false) => Some((CollisionAxis::X, new_pos, damage)),
|
||||
(false, true) => Some((CollisionAxis::Y, new_pos, damage)),
|
||||
(true, true) => Some((CollisionAxis::Both, new.position, death)),
|
||||
(true, false) => Some((CollisionAxis::X, new.position, death)),
|
||||
(false, true) => Some((CollisionAxis::Y, new.position, death)),
|
||||
(false, false) => None,
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ pub mod bbox;
|
||||
pub mod character;
|
||||
pub mod controls;
|
||||
pub mod event;
|
||||
pub mod map;
|
||||
pub mod math;
|
||||
pub mod physics;
|
||||
pub mod scene;
|
||||
|
@ -3,6 +3,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::engine::character::Character;
|
||||
use crate::engine::event::Keyboard;
|
||||
use crate::engine::map::Map;
|
||||
use crate::engine::texture::SPRITE_SIZE;
|
||||
|
||||
@ -37,8 +38,8 @@ impl Scene {
|
||||
/// 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;
|
||||
character.position.x = self.map.entrance().1 as f64 * SPRITE_SIZE;
|
||||
character.position.y = self.map.entrance().0 as f64 * SPRITE_SIZE;
|
||||
|
||||
self.characters.push(character);
|
||||
}
|
||||
@ -83,7 +84,7 @@ impl Scene {
|
||||
// }
|
||||
|
||||
/// Updates the whole scene.
|
||||
pub fn update(&mut self, duration: &Duration) -> State {
|
||||
pub fn update(&mut self, duration: &Duration, keyboard: &Keyboard) -> State {
|
||||
let mut state = State::Finished;
|
||||
|
||||
for c in &mut self.characters {
|
||||
@ -95,7 +96,7 @@ impl Scene {
|
||||
// Compute the offset between position and bbox
|
||||
let offset = old.position - c.position;
|
||||
|
||||
c.update(duration);
|
||||
c.update(duration, keyboard);
|
||||
|
||||
if let Some((axis, position, damage)) = self.map.collides_bbox(old, c.bbox()) {
|
||||
c.position = position - offset;
|
||||
@ -143,7 +144,7 @@ impl Scene {
|
||||
/// 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);
|
||||
fn update(&mut self, duration: &Duration, keyboard: &Keyboard);
|
||||
|
||||
// /// Called when an event arrives.
|
||||
// fn manage_event(&mut self, event: &Event);
|
||||
|
Loading…
x
Reference in New Issue
Block a user