Save / Load levels

This commit is contained in:
2019-03-30 13:34:09 +01:00
parent ae601720e3
commit 2ff29eb0c6
12 changed files with 277 additions and 128 deletions
+40 -5
View File
@@ -1,6 +1,15 @@
use std::path::Path;
use std::fs::File;
use std::io::{BufWriter, BufReader};
use serde::{Serialize, Deserialize};
use bincode::{serialize, deserialize, serialize_into, deserialize_from};
use sfml::graphics::{FloatRect, IntRect};
use sfml::system::Vector2;
use crate::{Error, Result};
use crate::engine::math::{clamp, Matrix};
use crate::engine::renderer::Drawable;
use crate::engine::texture::Texture;
@@ -37,7 +46,7 @@ impl CollisionAxis {
}
/// This struct represents the different sides from which a collision can occur.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CollisionTile {
/// If the character comes from the top, it will collide if this bool is true.
pub from_top: bool,
@@ -75,7 +84,7 @@ impl CollisionTile {
}
/// This struct represents a renderable tile linking to its part in the tileset texture.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum GraphicTile {
/// There is nothing to draw.
Hidden,
@@ -273,6 +282,7 @@ impl Drawable for PositionedTile {
}
/// The map represents the tiles contained in a level.
#[derive(Serialize, Deserialize)]
pub struct Map {
/// The entrace point of the character in the map.
entrance: (usize, usize),
@@ -294,8 +304,33 @@ impl Map {
Map::from_collision_tiles(tiles)
}
/// Encodes the map into a binary format.
pub fn encode(&self) -> Result<Vec<u8>> {
serialize(&self).map_err(Error::Encoding)
}
/// Decodes a map from bytes.
pub fn decode(content: &[u8]) -> Result<Map> {
deserialize(content).map_err(Error::Decoding)
}
/// Saves the map to a file.
pub fn save<P: AsRef<Path>>(&self, path: P) -> Result<()> {
let file = File::create(path.as_ref()).map_err(Error::Save)?;
let mut writer = BufWriter::new(file);
serialize_into(&mut writer, &self).map_err(Error::Encoding)?;
Ok(())
}
/// Loads a map from a file.
pub fn load<P: AsRef<Path>>(path: P) -> Result<Map> {
let file = File::open(path.as_ref()).map_err(Error::Load)?;
let mut reader = BufReader::new(file);
Ok(deserialize_from(&mut reader).map_err(Error::Decoding)?)
}
/// Creates a map from a txt file.
pub fn from_str(text: &str) -> Result<Map, ()> {
pub fn from_str(text: &str) -> Result<Map> {
let split = text.split('\n').collect::<Vec<_>>();
// First two usize are the size of the map
@@ -356,8 +391,8 @@ impl Map {
}
/// Returns a tile of the map.
pub fn tile(&self, i: usize, j: usize) -> CollisionTile {
self.tiles[(i, j)].0
pub fn tile(&self, i: usize, j: usize) -> Option<CollisionTile> {
self.tiles.get((i, j)).map(|x| x.0)
}
/// Changes a tile of the map.
+3 -1
View File
@@ -1,7 +1,8 @@
use std::time::Duration;
use std::ops::{Index, IndexMut};
use serde::{Serialize, Deserialize};
/// Clamp a number between two boundaries.
pub fn clamp(number: f32, min: f32, max: f32) -> f32 {
if number < min {
@@ -26,6 +27,7 @@ pub fn duration_as_f32(duration: &Duration) -> f32 {
}
/// A generic matrix type, useful for levels.
#[derive(Serialize, Deserialize)]
pub struct Matrix<T> {
/// The number of rows of the matrix.
rows: usize,
+3 -3
View File
@@ -17,11 +17,11 @@ pub struct Scene {
}
impl Scene {
/// Creates an empty scene.
pub fn new() -> Scene {
/// Creates a scene from a map level.
pub fn from_map(map: Map) -> Scene {
Scene {
characters: vec![],
map: Map::from_str(include_str!("../../../assets/levels/level2.txt")).unwrap(),
map,
}
}