Added jumping and Jump animation state

Former-commit-id: 6ae9f7e9c9fb2bc519a0ef2c1c8195376616ed4c
This commit is contained in:
Joshua Barretto 2019-05-01 17:55:29 +01:00
parent 5aa8a67800
commit e6a40bbda2
9 changed files with 90 additions and 28 deletions

View File

@ -1,14 +1,21 @@
use vek::*;
pub enum InputEvent {
Jump,
}
pub struct Input {
// TODO: Use this type to manage client input
pub move_dir: Vec2<f32>,
pub jumping: bool,
pub events: Vec<InputEvent>,
}
impl Default for Input {
fn default() -> Self {
Input {
move_dir: Vec2::zero(),
jumping: false,
events: Vec::new(),
}
}
}

View File

@ -4,7 +4,7 @@ pub mod error;
pub mod input;
// Reexports
pub use crate::{error::Error, input::Input};
pub use crate::{error::Error, input::{Input, InputEvent}};
pub use specs::join::Join;
pub use specs::Entity as EcsEntity;
@ -152,6 +152,7 @@ impl Client {
self.entity,
comp::Control {
move_dir: input.move_dir,
jumping: input.jumping,
},
);

View File

@ -13,12 +13,14 @@ impl Component for Agent {
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub struct Control {
pub move_dir: Vec2<f32>,
pub jumping: bool,
}
impl Default for Control {
fn default() -> Self {
Self {
move_dir: Vec2::zero(),
jumping: false,
}
}
}

View File

@ -119,6 +119,7 @@ pub struct AnimationHistory {
pub enum Animation {
Idle,
Run,
Jump,
}
impl Component for Character {

View File

@ -1,11 +1,15 @@
// Library
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
use specs::{Entities, Join, Read, ReadStorage, ReadExpect, System, WriteStorage};
use vek::*;
// Crate
use crate::comp::{
phys::{Dir, Pos, Vel},
Animation, AnimationHistory, Control,
use crate::{
comp::{
phys::{Dir, Pos, Vel},
Animation, AnimationHistory, Control,
},
terrain::TerrainMap,
vol::{ReadVol, Vox},
};
// Basic ECS AI agent system
@ -13,26 +17,47 @@ pub struct Sys;
impl<'a> System<'a> for Sys {
type SystemData = (
ReadExpect<'a, TerrainMap>,
Entities<'a>,
ReadStorage<'a, Pos>,
WriteStorage<'a, Vel>,
WriteStorage<'a, Dir>,
WriteStorage<'a, AnimationHistory>,
ReadStorage<'a, Control>,
);
fn run(&mut self, (entities, mut vels, mut dirs, mut anims, controls): Self::SystemData) {
for (entity, mut vel, mut dir, control) in
(&entities, &mut vels, &mut dirs, &controls).join()
fn run(&mut self, (terrain, entities, pos, mut vels, mut dirs, mut anims, controls): Self::SystemData) {
for (entity, pos, mut vel, mut dir, control) in
(&entities, &pos, &mut vels, &mut dirs, &controls).join()
{
// TODO: Don't hard-code this
// Apply physics to the player: acceleration and non-linear decceleration
vel.0 += control.move_dir * 2.0 - vel.0.map(|e| e * e.abs() + e) * 0.03;
let on_ground = terrain
.get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32))
.map(|vox| !vox.is_empty())
.unwrap_or(false) && vel.0.z <= 0.0;
let animation = if control.move_dir.magnitude() > 0.01 {
dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0);
Animation::Run
if on_ground {
// TODO: Don't hard-code this
// Apply physics to the player: acceleration and non-linear decceleration
vel.0 += control.move_dir * 2.0 - vel.0.map(|e| e * e.abs() + e) * 0.03;
if control.jumping {
vel.0.z += 16.0;
}
} else {
Animation::Idle
// TODO: Don't hard-code this
// Apply physics to the player: acceleration and non-linear decceleration
vel.0 += control.move_dir * 0.2;
}
let animation = if on_ground {
if control.move_dir.magnitude() > 0.01 {
dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0);
Animation::Run
} else {
Animation::Idle
}
} else {
Animation::Jump
};
let last_animation = anims.get_mut(entity).map(|h| h.current);

View File

@ -10,7 +10,7 @@ use vek::*;
// Basic ECS physics system
pub struct Sys;
const GRAVITY: f32 = 9.81 * 2.0;
const GRAVITY: f32 = 9.81 * 4.0;
impl<'a> System<'a> for Sys {
type SystemData = (

View File

@ -25,8 +25,4 @@ impl KeyState {
if self.up { 1.0 } else { 0.0 } + if self.down { -1.0 } else { 0.0 },
)
}
pub fn jump(&self) -> bool {
self.jump
}
}

View File

@ -208,10 +208,15 @@ impl FigureCache {
let target_skeleton = match animation_history.current {
comp::character::Animation::Idle => {
IdleAnimation::update_skeleton(&mut state.skeleton, time)
}
},
comp::character::Animation::Run => {
RunAnimation::update_skeleton(&mut state.skeleton, time)
}
},
comp::character::Animation::Jump => {
// TODO
// JumpAnimation::update_skeleton(&mut state.skeleton, time)
state.skeleton.clone()
},
};
state.skeleton.interpolate(&target_skeleton);

View File

@ -1,3 +1,17 @@
use std::{
cell::RefCell,
rc::Rc,
time::Duration,
mem,
};
use vek::*;
use common::clock::Clock;
use client::{
self,
Client,
Input,
InputEvent,
};
use crate::{
hud::{Event as HudEvent, Hud},
key_state::KeyState,
@ -7,10 +21,6 @@ use crate::{
window::{Event, Key, Window},
Direction, Error, GlobalState, PlayState, PlayStateResult,
};
use client::{self, Client};
use common::clock::Clock;
use std::{cell::RefCell, rc::Rc, time::Duration};
use vek::*;
const FPS: u64 = 60;
@ -18,6 +28,7 @@ pub struct SessionState {
scene: Scene,
client: Rc<RefCell<Client>>,
key_state: KeyState,
input_events: Vec<InputEvent>,
hud: Hud,
}
@ -32,6 +43,7 @@ impl SessionState {
client,
key_state: KeyState::new(),
hud: Hud::new(window, settings),
input_events: Vec::new(),
}
}
}
@ -56,10 +68,18 @@ impl SessionState {
let dir_vec = self.key_state.dir_vec();
let move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1];
// Take the input events
let mut input_events = Vec::new();
mem::swap(&mut self.input_events, &mut input_events);
for event in self
.client
.borrow_mut()
.tick(client::Input { move_dir }, dt)?
.tick(Input {
move_dir,
jumping: self.key_state.jump,
events: input_events,
}, dt)?
{
match event {
client::Event::Chat(msg) => {
@ -132,11 +152,16 @@ impl PlayState for SessionState {
Event::KeyDown(Key::MoveBack) => self.key_state.down = true,
Event::KeyDown(Key::MoveLeft) => self.key_state.left = true,
Event::KeyDown(Key::MoveRight) => self.key_state.right = true,
Event::KeyDown(Key::Jump) => {
self.input_events.push(InputEvent::Jump);
self.key_state.jump = true;
},
// Movement Key Released
Event::KeyUp(Key::MoveForward) => self.key_state.up = false,
Event::KeyUp(Key::MoveBack) => self.key_state.down = false,
Event::KeyUp(Key::MoveLeft) => self.key_state.left = false,
Event::KeyUp(Key::MoveRight) => self.key_state.right = false,
Event::KeyUp(Key::Jump) => self.key_state.jump = false,
// Pass all other events to the scene
event => {
self.scene.handle_input_event(event);