From feac27c6b6b76871e91d0d57c85034f787990b37 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 24 Jul 2020 18:56:48 -0400 Subject: [PATCH] Finished 3.2 Animations --- src/components.rs | 32 +++++++++++++++++++++- src/entities.rs | 47 +++++++++++++++++++++++++-------- src/main.rs | 10 +++++-- src/resources.rs | 7 +++++ src/systems/rendering_system.rs | 32 +++++++++++++++++++--- 5 files changed, 110 insertions(+), 18 deletions(-) diff --git a/src/components.rs b/src/components.rs index 395bc30..e48a6dc 100644 --- a/src/components.rs +++ b/src/components.rs @@ -19,6 +19,11 @@ impl Display for BoxColor { } } +pub enum RenderableKind { + Static, + Animated, +} + #[derive(Debug, Component, Clone, Copy)] #[storage(VecStorage)] pub struct Position { @@ -40,7 +45,32 @@ impl Position { #[derive(Component)] #[storage(VecStorage)] pub struct Renderable { - pub path: String, + paths: Vec, +} + +impl Renderable { + pub fn new_static(path: String) -> Self { + Self { paths: vec![path] } + } + + pub fn new_animated(paths: Vec) -> Self { + Self { paths } + } + + pub fn kind(&self) -> RenderableKind { + match self.paths.len() { + 0 => panic!("invalid renderable"), + 1 => RenderableKind::Static, + _ => RenderableKind::Animated, + } + } + + pub fn path(&self, path_index: usize) -> String { + // If we get asked for a path that is larger than the + // number of paths we actually have, we simply mod the index + // with the length to get an index that is in range + self.paths[path_index % self.paths.len()].clone() + } } #[derive(Component)] diff --git a/src/entities.rs b/src/entities.rs index d85ff85..550a917 100644 --- a/src/entities.rs +++ b/src/entities.rs @@ -2,34 +2,54 @@ use crate::components::*; use specs::{Builder, EntityBuilder, World, WorldExt}; /// Cut down on the common syntax boilerplate -fn common_entity<'w>( +fn static_entity<'w>( world: &'w mut World, position: Position, z: u8, sprite_path: &str, ) -> EntityBuilder<'w> { - return world + let sprite_path = sprite_path.to_string(); + world .create_entity() .with(position.with_z(z)) - .with(Renderable { - path: sprite_path.to_string(), - }); + .with(Renderable::new_static(sprite_path)) +} + +/// Cut down on animated entity boilerplate, +/// and accept vectors of `&str` and `String` +fn animated_entity( + world: &mut World, + position: Position, + z: u8, + sprites: Vec, +) -> EntityBuilder +where + S: Into, +{ + let sprites: Vec = sprites.into_iter().map(|s| s.into()).collect(); + world + .create_entity() + .with(position.with_z(z)) + .with(Renderable::new_animated(sprites)) } pub fn create_wall(world: &mut World, position: Position) { - common_entity(world, position, 10, "/images/wall.png") + static_entity(world, position, 10, "/images/wall.png") .with(Wall {}) .with(Immovable) .build(); } pub fn create_floor(world: &mut World, position: Position) { - common_entity(world, position, 5, "/images/floor.png").build(); + static_entity(world, position, 5, "/images/floor.png").build(); } pub fn create_box(world: &mut World, position: Position, color: BoxColor) { - let path = format!("/images/box_{}.png", color); - common_entity(world, position, 10, &path) + let mut sprites: Vec = vec![]; + for x in 1..=2 { + sprites.push(format!("/images/box_{}_{}.png", color, x)); + } + animated_entity(world, position, 10, sprites) .with(Box { color }) .with(Movable) .build(); @@ -37,13 +57,18 @@ pub fn create_box(world: &mut World, position: Position, color: BoxColor) { pub fn create_box_spot(world: &mut World, position: Position, color: BoxColor) { let path = format!("/images/box_spot_{}.png", color); - common_entity(world, position, 9, &path) + static_entity(world, position, 9, &path) .with(BoxSpot { color }) .build(); } pub fn create_player(world: &mut World, position: Position) { - common_entity(world, position, 10, "/images/player.png") + let sprites = vec![ + "/images/player_1.png", + "/images/player_2.png", + "/images/player_3.png", + ]; + animated_entity(world, position, 10, sprites) .with(Player {}) .with(Movable) .build(); diff --git a/src/main.rs b/src/main.rs index defa079..4eedd07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use ggez; use ggez::event::KeyCode; use ggez::event::KeyMods; -use ggez::{conf, event, Context, GameResult}; +use ggez::{conf, event, timer, Context, GameResult}; use specs::{RunNow, World, WorldExt}; use std::path; @@ -23,7 +23,7 @@ struct Game { } impl event::EventHandler for Game { - fn update(&mut self, _context: &mut Context) -> GameResult { + fn update(&mut self, context: &mut Context) -> GameResult { // Run input system { let mut is = InputSystem {}; @@ -36,6 +36,12 @@ impl event::EventHandler for Game { gss.run_now(&self.world); } + // Get an update time resource + { + let mut time = self.world.write_resource::