summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortom barrett <spalf0@gmail.com>2019-06-22 10:11:18 -0500
committertom barrett <spalf0@gmail.com>2019-06-22 10:11:18 -0500
commitcccfb66c7c58bf464252e942ef2b742b41ece19e (patch)
tree8d13331a5cb65343d1a668d6dbb3fa4a62fb598a /src
parent99c6e61a2b8fe66dcef7eada525f6fbdd7a2cd00 (diff)
now draw at the tile level
Diffstat (limited to 'src')
-rw-r--r--src/constants.rs9
-rw-r--r--src/layer.rs31
-rw-r--r--src/lib.rs3
-rw-r--r--src/map.rs75
-rw-r--r--src/math.rs5
-rw-r--r--src/player.rs6
-rw-r--r--src/state.rs10
-rw-r--r--src/tile.rs65
8 files changed, 124 insertions, 80 deletions
diff --git a/src/constants.rs b/src/constants.rs
index 367e595..c154066 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -4,8 +4,7 @@ pub const TILE_SCALE: f32 = 3.0;
pub const PLAYER_SPEED: f32 = 5.0;
-pub const FLIP_HORIZONTALLY_FLAG: u32 = 0x8000_0000;
-pub const FLIP_VERTICALLY_FLAG: u32 = 0x4000_0000;
-pub const FLIP_DIAGONALLY_FLAG: u32 = 0x2000_0000;
-pub const ALL_FLIP_FLAGS: u32 =
- FLIP_DIAGONALLY_FLAG | FLIP_HORIZONTALLY_FLAG | FLIP_VERTICALLY_FLAG;
+pub const FLIP_HORIZONTAL_FLAG: usize = 0x8000_0000;
+pub const FLIP_VERTICAL_FLAG: usize = 0x4000_0000;
+pub const FLIP_DIAGONAL_FLAG: usize = 0x2000_0000;
+pub const ALL_FLIP_FLAGS: usize = FLIP_DIAGONAL_FLAG | FLIP_HORIZONTAL_FLAG | FLIP_VERTICAL_FLAG;
diff --git a/src/layer.rs b/src/layer.rs
new file mode 100644
index 0000000..efecd89
--- /dev/null
+++ b/src/layer.rs
@@ -0,0 +1,31 @@
+use ggez::graphics::spritebatch::SpriteBatch;
+
+use crate::tile::Tile;
+use crate::tileset::Tileset;
+
+pub struct Layer {
+ pub tiles: Vec<Tile>,
+ pub width: usize,
+ pub height: usize,
+}
+
+impl Layer {
+ pub fn new(text: &str, tileset: &Tileset, width: usize, height: usize) -> Layer {
+ Layer {
+ tiles: text
+ .replace("\n", "")
+ .split(',')
+ .enumerate()
+ .map(|(i, s)| Tile::new(s, i, tileset, width, height))
+ .collect(),
+ width,
+ height,
+ }
+ }
+
+ pub fn draw(&self, spritebatch: &mut SpriteBatch) {
+ for tile in self.tiles.iter() {
+ tile.draw(spritebatch);
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 583c6f7..ac7c4f3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,7 +1,10 @@
pub mod camera;
pub mod constants;
+pub mod layer;
pub mod map;
+pub mod math;
pub mod player;
pub mod state;
+pub mod tile;
pub mod tileset;
pub mod xmlelements;
diff --git a/src/map.rs b/src/map.rs
index bb5f694..38fb326 100644
--- a/src/map.rs
+++ b/src/map.rs
@@ -1,10 +1,9 @@
use ggez::filesystem::File;
-use ggez::graphics::{spritebatch::SpriteBatch, DrawParam};
-use ggez::nalgebra::{Point2, Vector2};
-use std::f32::consts::PI;
+use ggez::graphics::spritebatch::SpriteBatch;
use xml::reader::XmlEvent::Characters;
use crate::constants;
+use crate::layer::Layer;
use crate::tileset::Tileset;
use crate::xmlelements::XMLElements;
@@ -15,17 +14,18 @@ pub struct Map {
}
impl Map {
- pub fn new(file: File) -> Map {
+ pub fn new(file: File, tileset: &Tileset) -> Map {
let elements = XMLElements::new(file);
let width = elements.get_element_attribute("map", "width").unwrap();
let height = elements.get_element_attribute("map", "height").unwrap();
+
let layers = elements
.events
.iter()
.filter_map(|e| {
if let Characters(text) = e {
- Some(Layer::new(text.to_string()))
+ Some(Layer::new(text, tileset, width, height))
} else {
None
}
@@ -39,28 +39,9 @@ impl Map {
}
}
- pub fn draw(&self, spritebatch: &mut SpriteBatch, tileset: &Tileset) {
+ pub fn draw(&self, spritebatch: &mut SpriteBatch) {
for layer in self.layers.iter() {
- for x in 0..self.width {
- for y in 0..self.height {
- let tile_id = layer.data[x + (y * self.height)];
- let (tile_id, rotate) = self.decode(tile_id as u32);
-
- let offset = (constants::TILE_WIDTH / 2.0) * constants::TILE_SCALE;
-
- let draw_param = DrawParam::default()
- .src(tileset.tiles[tile_id as usize])
- .rotation(rotate)
- .offset(Point2::new(0.5, 0.5))
- .dest(Point2::new(
- (constants::TILE_WIDTH * constants::TILE_SCALE * x as f32) + offset,
- (constants::TILE_HEIGHT * constants::TILE_SCALE * y as f32) + offset,
- ))
- .scale(Vector2::new(constants::TILE_SCALE, constants::TILE_SCALE));
-
- spritebatch.add(draw_param);
- }
- }
+ layer.draw(spritebatch);
}
}
@@ -70,46 +51,4 @@ impl Map {
(constants::TILE_HEIGHT * constants::TILE_SCALE) * self.height as f32,
)
}
-
- fn decode(&self, tile_id: u32) -> (u32, f32) {
- //let flip_d = (tile_id & constants::FLIP_DIAGONALLY_FLAG) == constants::FLIP_DIAGONALLY_FLAG;
- let flip_h =
- (tile_id & constants::FLIP_HORIZONTALLY_FLAG) == constants::FLIP_HORIZONTALLY_FLAG;
- let flip_v = (tile_id & constants::FLIP_VERTICALLY_FLAG) == constants::FLIP_VERTICALLY_FLAG;
-
- let new_tile_id = if flip_h | flip_v {
- tile_id & !constants::ALL_FLIP_FLAGS
- } else {
- tile_id
- };
-
- let rotate = match (flip_h, flip_v) {
- (true, false) => self.convert_angle_to_rad(90.0),
- (true, true) => self.convert_angle_to_rad(180.0),
- (false, true) => self.convert_angle_to_rad(270.0),
- (false, false) => 0.0,
- };
-
- (new_tile_id, rotate)
- }
-
- fn convert_angle_to_rad(&self, angle: f32) -> f32 {
- angle * (PI / 180.0)
- }
-}
-
-pub struct Layer {
- pub data: Vec<usize>,
-}
-
-impl Layer {
- pub fn new(text: String) -> Layer {
- Layer {
- data: text
- .replace("\n", "")
- .split(',')
- .map(|s| s.parse().unwrap())
- .collect(),
- }
- }
}
diff --git a/src/math.rs b/src/math.rs
new file mode 100644
index 0000000..c7ea7f6
--- /dev/null
+++ b/src/math.rs
@@ -0,0 +1,5 @@
+use std::f32::consts::PI;
+
+pub fn convert_angle_to_rad(angle: f32) -> f32 {
+ angle * (PI / 180.0)
+}
diff --git a/src/player.rs b/src/player.rs
index bc019b9..e9c3a75 100644
--- a/src/player.rs
+++ b/src/player.rs
@@ -11,8 +11,8 @@ pub struct Player {
pub position: Point2<f32>,
state: PlayerState,
tile: Rect,
- animation: Vec<(u32, Rect)>,
- animations: HashMap<PlayerState, Vec<(u32, Rect)>>,
+ animation: Vec<(usize, Rect)>,
+ animations: HashMap<PlayerState, Vec<(usize, Rect)>>,
map_height: f32,
map_width: f32,
}
@@ -106,7 +106,7 @@ impl Player {
let index = match self.animation.iter().position(|a| a.1 == self.tile) {
Some(index) => {
- if check_update_time(context, self.animation[index].0) {
+ if check_update_time(context, self.animation[index].0 as u32) {
index + 1
} else {
index
diff --git a/src/state.rs b/src/state.rs
index b0a497c..20066a8 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -9,7 +9,7 @@ use crate::tileset::Tileset;
pub struct State {
map: Map,
- tileset: Tileset,
+ //tileset: Tileset,
spritebatch: SpriteBatch,
camera: Camera,
player: Player,
@@ -20,12 +20,14 @@ impl State {
let mut image = Image::new(context, "/tileset.png")?;
image.set_filter(FilterMode::Nearest);
- let map = Map::new(filesystem::open(context, "/map.tmx")?);
+ let tileset = Tileset::new(filesystem::open(context, "/tileset.tsx")?);
+
+ let map = Map::new(filesystem::open(context, "/map.tmx")?, &tileset);
let map_dimensions = map.get_dimensions();
Ok(State {
map,
- tileset: Tileset::new(filesystem::open(context, "/tileset.tsx")?),
+ // tileset,
spritebatch: SpriteBatch::new(image),
camera: Camera::new(context, map_dimensions),
player: Player::new(map_dimensions),
@@ -43,7 +45,7 @@ impl EventHandler for State {
fn draw(&mut self, context: &mut Context) -> GameResult {
graphics::clear(context, graphics::BLACK);
- self.map.draw(&mut self.spritebatch, &self.tileset);
+ self.map.draw(&mut self.spritebatch);
self.player.draw(&mut self.spritebatch);
graphics::draw(
diff --git a/src/tile.rs b/src/tile.rs
new file mode 100644
index 0000000..21b6a79
--- /dev/null
+++ b/src/tile.rs
@@ -0,0 +1,65 @@
+use ggez::graphics::{spritebatch::SpriteBatch, DrawParam, Rect};
+use ggez::nalgebra::{Point2, Vector2};
+
+use crate::constants;
+use crate::math::convert_angle_to_rad;
+use crate::tileset::Tileset;
+
+pub struct Tile {
+ //id: u32,
+ source: Rect,
+ //animation: Option<Vec<(u32, Rect)>>,
+ rotate: f32,
+ destination: Point2<f32>,
+}
+
+impl Tile {
+ pub fn new(text: &str, i: usize, tileset: &Tileset, width: usize, height: usize) -> Tile {
+ let id = text.parse::<usize>().unwrap();
+
+ //let flip_d = (id & constants::FLIP_DIAGONAL_FLAG) == constants::FLIP_DIAGONAL_FLAG;
+ let flip_h = (id & constants::FLIP_HORIZONTAL_FLAG) == constants::FLIP_HORIZONTAL_FLAG;
+ let flip_v = (id & constants::FLIP_VERTICAL_FLAG) == constants::FLIP_VERTICAL_FLAG;
+
+ let id = if flip_h | flip_v {
+ id & !constants::ALL_FLIP_FLAGS
+ } else {
+ id
+ };
+
+ let rotate = match (flip_h, flip_v) {
+ (true, false) => convert_angle_to_rad(90.0),
+ (true, true) => convert_angle_to_rad(180.0),
+ (false, true) => convert_angle_to_rad(270.0),
+ (false, false) => 0.0,
+ };
+
+ let x = i as f32 % width as f32;
+ let y = (i as f32 / height as f32).floor();
+ let offset = (constants::TILE_WIDTH / 2.0) * constants::TILE_SCALE;
+
+ let destination = Point2::new(
+ (constants::TILE_WIDTH * constants::TILE_SCALE * x) + offset,
+ (constants::TILE_HEIGHT * constants::TILE_SCALE * y) + offset,
+ );
+
+ Tile {
+ //id,
+ source: tileset.tiles[id as usize],
+ //animation: None,
+ rotate,
+ destination,
+ }
+ }
+
+ pub fn draw(&self, spritebatch: &mut SpriteBatch) {
+ let draw_param = DrawParam::default()
+ .src(self.source)
+ .rotation(self.rotate)
+ .offset(Point2::new(0.5, 0.5))
+ .dest(self.destination)
+ .scale(Vector2::new(constants::TILE_SCALE, constants::TILE_SCALE));
+
+ spritebatch.add(draw_param);
+ }
+}