diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/constants.rs | 3 | ||||
-rw-r--r-- | src/entity.rs | 52 | ||||
-rw-r--r-- | src/math.rs | 8 | ||||
-rw-r--r-- | src/player.rs | 92 | ||||
-rw-r--r-- | src/state.rs | 3 |
5 files changed, 109 insertions, 49 deletions
diff --git a/src/constants.rs b/src/constants.rs index c154066..8767bb0 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -3,6 +3,9 @@ pub const TILE_HEIGHT: f32 = 16.0; pub const TILE_SCALE: f32 = 3.0; pub const PLAYER_SPEED: f32 = 5.0; +pub const ENTITY_SPEED: f32 = 2.5; +pub const WANDER_DISTANCE: f32 = 150.0; +pub const GOAL_DISTANCE: f32 = 6.0; pub const FLIP_HORIZONTAL_FLAG: usize = 0x8000_0000; pub const FLIP_VERTICAL_FLAG: usize = 0x4000_0000; diff --git a/src/entity.rs b/src/entity.rs index bd29a84..1c0aa35 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -1,12 +1,15 @@ use ggez::graphics::{spritebatch::SpriteBatch, DrawParam, Rect}; -use ggez::nalgebra::{Point2, Vector2}; +use ggez::nalgebra::{distance, Point2, Vector2}; +use std::time::Instant; use crate::constants; use crate::map::Map; +use crate::math::random_nearby_point; use crate::tileset::Tileset; #[derive(Clone)] pub struct Entity { + behavior: Behavior, position: Point2<f32>, source: Rect, spawn: Point2<f32>, @@ -18,12 +21,49 @@ impl Entity { source.h += tileset.get_tile_by_entity_keyframe("player-bottom", 0).h; Entity { - position: spawn, - source, spawn, + source, + position: spawn, + behavior: Behavior::Wandering(None), + } + } + + pub fn update(&mut self) { + match self.behavior { + Behavior::Wandering(destination) => self.wandering(destination), + Behavior::Waiting(time) => (), } } + pub fn wandering(&mut self, destination: Option<Point2<f32>>) { + match destination { + Some(destination) => { + if distance(&self.position, &destination) < constants::GOAL_DISTANCE { + self.behavior = Behavior::Waiting(Instant::now()) + } else { + if self.position.x < destination.x { + self.position.x += constants::ENTITY_SPEED; + } else { + self.position.x -= constants::ENTITY_SPEED; + } + if self.position.y < destination.y { + self.position.y += constants::ENTITY_SPEED; + } else { + self.position.y -= constants::ENTITY_SPEED; + } + } + } + None => { + self.behavior = Behavior::Wandering(Some(random_nearby_point( + self.spawn, + constants::WANDER_DISTANCE, + ))) + } + } + } + + pub fn waiting(&mut self) {} + pub fn draw(&self, spritebatch: &mut SpriteBatch) { let draw_param = DrawParam::default() .src(self.source) @@ -43,3 +83,9 @@ impl Entity { entities } } + +#[derive(Clone)] +enum Behavior { + Waiting(Instant), + Wandering(Option<Point2<f32>>), +} diff --git a/src/math.rs b/src/math.rs index c747cce..ff652ea 100644 --- a/src/math.rs +++ b/src/math.rs @@ -1,4 +1,6 @@ use ggez::graphics::Rect; +use ggez::nalgebra::Point2; +use rand::Rng; use std::f32::consts::PI; use std::time::Instant; @@ -27,3 +29,9 @@ pub fn next_source(source: Rect, animation: &[(usize, Rect)], timer: Instant) -> (source, timer) } } + +pub fn random_nearby_point(origin: Point2<f32>, within_radius: f32) -> Point2<f32> { + let w = within_radius * rand::thread_rng().gen_range(0.0, 1.0); + let t = 2.0 * PI * rand::thread_rng().gen_range(0.0, 1.0); + Point2::new(origin.x + w * t.cos(), origin.y + w * t.sin()) +} diff --git a/src/player.rs b/src/player.rs index 1f941be..6440587 100644 --- a/src/player.rs +++ b/src/player.rs @@ -10,11 +10,11 @@ use crate::tileset::Tileset; pub struct Player { pub position: Point2<f32>, - state: PlayerState, + state: AnimationState, source: Rect, timer: Instant, animation: Vec<(usize, Rect)>, - animations: HashMap<PlayerState, Vec<(usize, Rect)>>, + animations: HashMap<AnimationState, Vec<(usize, Rect)>>, map_height: f32, map_width: f32, } @@ -23,7 +23,7 @@ impl Player { pub fn new(tileset: &Tileset, dimensions: (f32, f32)) -> Player { Player { position: Point2::new(0.0, 0.0), - state: PlayerState::IdleLeft, + state: AnimationState::IdleLeft, source: Rect::zero(), timer: Instant::now(), animation: Vec::new(), @@ -33,38 +33,38 @@ impl Player { } } - fn build_animations(tileset: &Tileset) -> HashMap<PlayerState, Vec<(usize, Rect)>> { + fn build_animations(tileset: &Tileset) -> HashMap<AnimationState, Vec<(usize, Rect)>> { let mut animations = HashMap::new(); let mut source = tileset.get_tile_by_entity_keyframe("player-top", 0); source.h += tileset.get_tile_by_entity_keyframe("player-bottom", 0).h; - animations.insert(PlayerState::IdleLeft, vec![(1, source)]); + animations.insert(AnimationState::IdleLeft, vec![(1, source)]); let mut moving = tileset.get_tile_by_entity_keyframe("player-top", 1); moving.h += tileset.get_tile_by_entity_keyframe("player-bottom", 1).h; - animations.insert(PlayerState::MovingLeft, vec![(100, source), (100, moving)]); + animations.insert(AnimationState::MovingLeft, vec![(100, source), (100, moving)]); animations.insert( - PlayerState::MovingUpLeft, + AnimationState::MovingUpLeft, vec![(100, source), (100, moving)], ); animations.insert( - PlayerState::MovingDownLeft, + AnimationState::MovingDownLeft, vec![(100, source), (100, moving)], ); source = flip(source); moving = flip(moving); - animations.insert(PlayerState::IdleRight, vec![(1, source)]); + animations.insert(AnimationState::IdleRight, vec![(1, source)]); - animations.insert(PlayerState::MovingRight, vec![(100, source), (100, moving)]); + animations.insert(AnimationState::MovingRight, vec![(100, source), (100, moving)]); animations.insert( - PlayerState::MovingUpRight, + AnimationState::MovingUpRight, vec![(100, source), (100, moving)], ); animations.insert( - PlayerState::MovingDownRight, + AnimationState::MovingDownRight, vec![(100, source), (100, moving)], ); @@ -95,27 +95,27 @@ impl Player { fn move_position(&mut self) { match self.state { - PlayerState::MovingUp => self.position.y -= constants::PLAYER_SPEED, - PlayerState::MovingUpLeft => { + AnimationState::MovingUp => self.position.y -= constants::PLAYER_SPEED, + AnimationState::MovingUpLeft => { self.position.x -= constants::PLAYER_SPEED / 2.0_f32.sqrt(); self.position.y -= constants::PLAYER_SPEED / 2.0_f32.sqrt(); } - PlayerState::MovingUpRight => { + AnimationState::MovingUpRight => { self.position.x += constants::PLAYER_SPEED / 2.0_f32.sqrt(); self.position.y -= constants::PLAYER_SPEED / 2.0_f32.sqrt(); } - PlayerState::MovingLeft => self.position.x -= constants::PLAYER_SPEED, - PlayerState::MovingDown => self.position.y += constants::PLAYER_SPEED, - PlayerState::MovingDownLeft => { + AnimationState::MovingLeft => self.position.x -= constants::PLAYER_SPEED, + AnimationState::MovingDown => self.position.y += constants::PLAYER_SPEED, + AnimationState::MovingDownLeft => { self.position.x -= constants::PLAYER_SPEED / 2.0_f32.sqrt(); self.position.y += constants::PLAYER_SPEED / 2.0_f32.sqrt(); } - PlayerState::MovingDownRight => { + AnimationState::MovingDownRight => { self.position.x += constants::PLAYER_SPEED / 2.0_f32.sqrt(); self.position.y += constants::PLAYER_SPEED / 2.0_f32.sqrt(); } - PlayerState::MovingRight => self.position.x += constants::PLAYER_SPEED, - PlayerState::IdleLeft | PlayerState::IdleRight => (), + AnimationState::MovingRight => self.position.x += constants::PLAYER_SPEED, + AnimationState::IdleLeft | AnimationState::IdleRight => (), } let pixel_width = constants::TILE_WIDTH * constants::TILE_SCALE; @@ -139,24 +139,24 @@ impl Player { self.state = match keycode { KeyCode::W => match original_state { - PlayerState::MovingLeft => PlayerState::MovingUpLeft, - PlayerState::MovingRight => PlayerState::MovingUpRight, - _ => PlayerState::MovingUp, + AnimationState::MovingLeft => AnimationState::MovingUpLeft, + AnimationState::MovingRight => AnimationState::MovingUpRight, + _ => AnimationState::MovingUp, }, KeyCode::A => match original_state { - PlayerState::MovingUp => PlayerState::MovingUpLeft, - PlayerState::MovingDown => PlayerState::MovingDownLeft, - _ => PlayerState::MovingLeft, + AnimationState::MovingUp => AnimationState::MovingUpLeft, + AnimationState::MovingDown => AnimationState::MovingDownLeft, + _ => AnimationState::MovingLeft, }, KeyCode::S => match original_state { - PlayerState::MovingLeft => PlayerState::MovingDownLeft, - PlayerState::MovingRight => PlayerState::MovingDownRight, - _ => PlayerState::MovingDown, + AnimationState::MovingLeft => AnimationState::MovingDownLeft, + AnimationState::MovingRight => AnimationState::MovingDownRight, + _ => AnimationState::MovingDown, }, KeyCode::D => match original_state { - PlayerState::MovingUp => PlayerState::MovingUpRight, - PlayerState::MovingDown => PlayerState::MovingDownRight, - _ => PlayerState::MovingRight, + AnimationState::MovingUp => AnimationState::MovingUpRight, + AnimationState::MovingDown => AnimationState::MovingDownRight, + _ => AnimationState::MovingRight, }, _ => original_state, } @@ -167,24 +167,24 @@ impl Player { self.state = match keycode { KeyCode::W => match original_state { - PlayerState::MovingUpLeft => PlayerState::MovingLeft, - PlayerState::MovingUpRight => PlayerState::MovingRight, - _ => PlayerState::IdleLeft, + AnimationState::MovingUpLeft => AnimationState::MovingLeft, + AnimationState::MovingUpRight => AnimationState::MovingRight, + _ => AnimationState::IdleLeft, }, KeyCode::A => match original_state { - PlayerState::MovingUpLeft => PlayerState::MovingUp, - PlayerState::MovingDownLeft => PlayerState::MovingDown, - _ => PlayerState::IdleLeft, + AnimationState::MovingUpLeft => AnimationState::MovingUp, + AnimationState::MovingDownLeft => AnimationState::MovingDown, + _ => AnimationState::IdleLeft, }, KeyCode::S => match original_state { - PlayerState::MovingDownLeft => PlayerState::MovingLeft, - PlayerState::MovingDownRight => PlayerState::MovingRight, - _ => PlayerState::IdleRight, + AnimationState::MovingDownLeft => AnimationState::MovingLeft, + AnimationState::MovingDownRight => AnimationState::MovingRight, + _ => AnimationState::IdleRight, }, KeyCode::D => match original_state { - PlayerState::MovingUpRight => PlayerState::MovingUp, - PlayerState::MovingDownRight => PlayerState::MovingDown, - _ => PlayerState::IdleRight, + AnimationState::MovingUpRight => AnimationState::MovingUp, + AnimationState::MovingDownRight => AnimationState::MovingDown, + _ => AnimationState::IdleRight, }, _ => original_state, } @@ -192,7 +192,7 @@ impl Player { } #[derive(Clone, Hash, Eq, PartialEq)] -enum PlayerState { +enum AnimationState { IdleLeft, IdleRight, MovingUp, diff --git a/src/state.rs b/src/state.rs index 1eb5e17..a541a02 100644 --- a/src/state.rs +++ b/src/state.rs @@ -41,6 +41,9 @@ impl EventHandler for State { fn update(&mut self, _context: &mut Context) -> GameResult { self.map.update(); self.player.update(); + for entity in self.entities.iter_mut() { + entity.update(); + } self.camera.give_center(self.player.position); Ok(()) } |