mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added jumping and Jump animation state
Former-commit-id: 6ae9f7e9c9fb2bc519a0ef2c1c8195376616ed4c
This commit is contained in:
@ -1,14 +1,21 @@
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
|
pub enum InputEvent {
|
||||||
|
Jump,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Input {
|
pub struct Input {
|
||||||
// TODO: Use this type to manage client input
|
|
||||||
pub move_dir: Vec2<f32>,
|
pub move_dir: Vec2<f32>,
|
||||||
|
pub jumping: bool,
|
||||||
|
pub events: Vec<InputEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Input {
|
impl Default for Input {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Input {
|
Input {
|
||||||
move_dir: Vec2::zero(),
|
move_dir: Vec2::zero(),
|
||||||
|
jumping: false,
|
||||||
|
events: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ pub mod error;
|
|||||||
pub mod input;
|
pub mod input;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use crate::{error::Error, input::Input};
|
pub use crate::{error::Error, input::{Input, InputEvent}};
|
||||||
pub use specs::join::Join;
|
pub use specs::join::Join;
|
||||||
pub use specs::Entity as EcsEntity;
|
pub use specs::Entity as EcsEntity;
|
||||||
|
|
||||||
@ -152,6 +152,7 @@ impl Client {
|
|||||||
self.entity,
|
self.entity,
|
||||||
comp::Control {
|
comp::Control {
|
||||||
move_dir: input.move_dir,
|
move_dir: input.move_dir,
|
||||||
|
jumping: input.jumping,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -13,12 +13,14 @@ impl Component for Agent {
|
|||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Control {
|
pub struct Control {
|
||||||
pub move_dir: Vec2<f32>,
|
pub move_dir: Vec2<f32>,
|
||||||
|
pub jumping: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Control {
|
impl Default for Control {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
move_dir: Vec2::zero(),
|
move_dir: Vec2::zero(),
|
||||||
|
jumping: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ pub struct AnimationHistory {
|
|||||||
pub enum Animation {
|
pub enum Animation {
|
||||||
Idle,
|
Idle,
|
||||||
Run,
|
Run,
|
||||||
|
Jump,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for Character {
|
impl Component for Character {
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
// Library
|
// Library
|
||||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
use specs::{Entities, Join, Read, ReadStorage, ReadExpect, System, WriteStorage};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
// Crate
|
// Crate
|
||||||
use crate::comp::{
|
use crate::{
|
||||||
|
comp::{
|
||||||
phys::{Dir, Pos, Vel},
|
phys::{Dir, Pos, Vel},
|
||||||
Animation, AnimationHistory, Control,
|
Animation, AnimationHistory, Control,
|
||||||
|
},
|
||||||
|
terrain::TerrainMap,
|
||||||
|
vol::{ReadVol, Vox},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Basic ECS AI agent system
|
// Basic ECS AI agent system
|
||||||
@ -13,26 +17,47 @@ pub struct Sys;
|
|||||||
|
|
||||||
impl<'a> System<'a> for Sys {
|
impl<'a> System<'a> for Sys {
|
||||||
type SystemData = (
|
type SystemData = (
|
||||||
|
ReadExpect<'a, TerrainMap>,
|
||||||
Entities<'a>,
|
Entities<'a>,
|
||||||
|
ReadStorage<'a, Pos>,
|
||||||
WriteStorage<'a, Vel>,
|
WriteStorage<'a, Vel>,
|
||||||
WriteStorage<'a, Dir>,
|
WriteStorage<'a, Dir>,
|
||||||
WriteStorage<'a, AnimationHistory>,
|
WriteStorage<'a, AnimationHistory>,
|
||||||
ReadStorage<'a, Control>,
|
ReadStorage<'a, Control>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, (entities, mut vels, mut dirs, mut anims, controls): Self::SystemData) {
|
fn run(&mut self, (terrain, entities, pos, mut vels, mut dirs, mut anims, controls): Self::SystemData) {
|
||||||
for (entity, mut vel, mut dir, control) in
|
for (entity, pos, mut vel, mut dir, control) in
|
||||||
(&entities, &mut vels, &mut dirs, &controls).join()
|
(&entities, &pos, &mut vels, &mut dirs, &controls).join()
|
||||||
{
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
if on_ground {
|
||||||
// TODO: Don't hard-code this
|
// TODO: Don't hard-code this
|
||||||
// Apply physics to the player: acceleration and non-linear decceleration
|
// 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;
|
vel.0 += control.move_dir * 2.0 - vel.0.map(|e| e * e.abs() + e) * 0.03;
|
||||||
|
|
||||||
let animation = if control.move_dir.magnitude() > 0.01 {
|
if control.jumping {
|
||||||
|
vel.0.z += 16.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 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);
|
dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0);
|
||||||
Animation::Run
|
Animation::Run
|
||||||
} else {
|
} else {
|
||||||
Animation::Idle
|
Animation::Idle
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Animation::Jump
|
||||||
};
|
};
|
||||||
|
|
||||||
let last_animation = anims.get_mut(entity).map(|h| h.current);
|
let last_animation = anims.get_mut(entity).map(|h| h.current);
|
||||||
|
@ -10,7 +10,7 @@ use vek::*;
|
|||||||
// Basic ECS physics system
|
// Basic ECS physics system
|
||||||
pub struct Sys;
|
pub struct Sys;
|
||||||
|
|
||||||
const GRAVITY: f32 = 9.81 * 2.0;
|
const GRAVITY: f32 = 9.81 * 4.0;
|
||||||
|
|
||||||
impl<'a> System<'a> for Sys {
|
impl<'a> System<'a> for Sys {
|
||||||
type SystemData = (
|
type SystemData = (
|
||||||
|
@ -25,8 +25,4 @@ impl KeyState {
|
|||||||
if self.up { 1.0 } else { 0.0 } + if self.down { -1.0 } else { 0.0 },
|
if self.up { 1.0 } else { 0.0 } + if self.down { -1.0 } else { 0.0 },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jump(&self) -> bool {
|
|
||||||
self.jump
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -208,10 +208,15 @@ impl FigureCache {
|
|||||||
let target_skeleton = match animation_history.current {
|
let target_skeleton = match animation_history.current {
|
||||||
comp::character::Animation::Idle => {
|
comp::character::Animation::Idle => {
|
||||||
IdleAnimation::update_skeleton(&mut state.skeleton, time)
|
IdleAnimation::update_skeleton(&mut state.skeleton, time)
|
||||||
}
|
},
|
||||||
comp::character::Animation::Run => {
|
comp::character::Animation::Run => {
|
||||||
RunAnimation::update_skeleton(&mut state.skeleton, time)
|
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);
|
state.skeleton.interpolate(&target_skeleton);
|
||||||
|
@ -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::{
|
use crate::{
|
||||||
hud::{Event as HudEvent, Hud},
|
hud::{Event as HudEvent, Hud},
|
||||||
key_state::KeyState,
|
key_state::KeyState,
|
||||||
@ -7,10 +21,6 @@ use crate::{
|
|||||||
window::{Event, Key, Window},
|
window::{Event, Key, Window},
|
||||||
Direction, Error, GlobalState, PlayState, PlayStateResult,
|
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;
|
const FPS: u64 = 60;
|
||||||
|
|
||||||
@ -18,6 +28,7 @@ pub struct SessionState {
|
|||||||
scene: Scene,
|
scene: Scene,
|
||||||
client: Rc<RefCell<Client>>,
|
client: Rc<RefCell<Client>>,
|
||||||
key_state: KeyState,
|
key_state: KeyState,
|
||||||
|
input_events: Vec<InputEvent>,
|
||||||
hud: Hud,
|
hud: Hud,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +43,7 @@ impl SessionState {
|
|||||||
client,
|
client,
|
||||||
key_state: KeyState::new(),
|
key_state: KeyState::new(),
|
||||||
hud: Hud::new(window, settings),
|
hud: Hud::new(window, settings),
|
||||||
|
input_events: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,10 +68,18 @@ impl SessionState {
|
|||||||
let dir_vec = self.key_state.dir_vec();
|
let dir_vec = self.key_state.dir_vec();
|
||||||
let move_dir = unit_vecs.0 * dir_vec[0] + unit_vecs.1 * dir_vec[1];
|
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
|
for event in self
|
||||||
.client
|
.client
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.tick(client::Input { move_dir }, dt)?
|
.tick(Input {
|
||||||
|
move_dir,
|
||||||
|
jumping: self.key_state.jump,
|
||||||
|
events: input_events,
|
||||||
|
}, dt)?
|
||||||
{
|
{
|
||||||
match event {
|
match event {
|
||||||
client::Event::Chat(msg) => {
|
client::Event::Chat(msg) => {
|
||||||
@ -132,11 +152,16 @@ impl PlayState for SessionState {
|
|||||||
Event::KeyDown(Key::MoveBack) => self.key_state.down = true,
|
Event::KeyDown(Key::MoveBack) => self.key_state.down = true,
|
||||||
Event::KeyDown(Key::MoveLeft) => self.key_state.left = true,
|
Event::KeyDown(Key::MoveLeft) => self.key_state.left = true,
|
||||||
Event::KeyDown(Key::MoveRight) => self.key_state.right = 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
|
// Movement Key Released
|
||||||
Event::KeyUp(Key::MoveForward) => self.key_state.up = false,
|
Event::KeyUp(Key::MoveForward) => self.key_state.up = false,
|
||||||
Event::KeyUp(Key::MoveBack) => self.key_state.down = false,
|
Event::KeyUp(Key::MoveBack) => self.key_state.down = false,
|
||||||
Event::KeyUp(Key::MoveLeft) => self.key_state.left = false,
|
Event::KeyUp(Key::MoveLeft) => self.key_state.left = false,
|
||||||
Event::KeyUp(Key::MoveRight) => self.key_state.right = 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
|
// Pass all other events to the scene
|
||||||
event => {
|
event => {
|
||||||
self.scene.handle_input_event(event);
|
self.scene.handle_input_event(event);
|
||||||
|
Reference in New Issue
Block a user