summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/constants.rs3
-rw-r--r--src/entity.rs52
-rw-r--r--src/math.rs8
-rw-r--r--src/player.rs92
-rw-r--r--src/state.rs3
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(())
}