Tutorial-driven player movement and camera
This commit is contained in:
parent
97e20064dd
commit
9470f3dd1f
5 changed files with 218 additions and 6 deletions
145
game/src/player.rs
Normal file
145
game/src/player.rs
Normal file
|
@ -0,0 +1,145 @@
|
|||
use fyrox::{
|
||||
core::{
|
||||
algebra::{UnitQuaternion, UnitVector3, Vector3},
|
||||
pool::Handle,
|
||||
reflect::prelude::*,
|
||||
visitor::prelude::*,
|
||||
variable::InheritableVariable,
|
||||
type_traits::prelude::*
|
||||
},
|
||||
event::{DeviceEvent, ElementState, MouseButton, WindowEvent, Event},
|
||||
script::{ScriptContext, ScriptDeinitContext, ScriptTrait},
|
||||
graph::SceneGraph,
|
||||
keyboard::{KeyCode, PhysicalKey},
|
||||
scene::{node::Node, rigidbody::RigidBody},
|
||||
};
|
||||
|
||||
#[derive(Visit, Reflect, Default, Debug, Clone, TypeUuidProvider, ComponentProvider)]
|
||||
#[type_uuid(id = "d14f7a07-1ea0-4d20-ad74-017b2497c88e")]
|
||||
#[visit(optional)]
|
||||
pub struct Player {
|
||||
#[reflect(hidden)]
|
||||
move_forward: bool,
|
||||
|
||||
#[reflect(hidden)]
|
||||
move_backward: bool,
|
||||
|
||||
#[reflect(hidden)]
|
||||
move_left: bool,
|
||||
|
||||
#[reflect(hidden)]
|
||||
move_right: bool,
|
||||
|
||||
#[reflect(hidden)]
|
||||
yaw: f32,
|
||||
|
||||
#[reflect(hidden)]
|
||||
pitch: f32,
|
||||
|
||||
camera: Handle<Node>,
|
||||
}
|
||||
|
||||
impl ScriptTrait for Player {
|
||||
fn on_init(&mut self, context: &mut ScriptContext) {
|
||||
// Put initialization logic here.
|
||||
}
|
||||
|
||||
fn on_start(&mut self, context: &mut ScriptContext) {
|
||||
// There should be a logic that depends on other scripts in scene.
|
||||
// It is called right after **all** scripts were initialized.
|
||||
}
|
||||
|
||||
fn on_deinit(&mut self, context: &mut ScriptDeinitContext) {
|
||||
// Put de-initialization logic here.
|
||||
}
|
||||
|
||||
fn on_os_event(&mut self, event: &Event<()>, context: &mut ScriptContext) {
|
||||
match event {
|
||||
Event::DeviceEvent {
|
||||
event:
|
||||
DeviceEvent::MouseMotion {
|
||||
delta: (dx, dy), ..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
let mouse_speed = 0.35;
|
||||
self.pitch = (self.pitch + *dy as f32 * mouse_speed).clamp(-89.9, 89.9);
|
||||
self.yaw -= *dx as f32 * mouse_speed;
|
||||
},
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::KeyboardInput { event, .. },
|
||||
..
|
||||
} => {
|
||||
if let PhysicalKey::Code(code) = event.physical_key {
|
||||
let is_pressed = event.state == ElementState::Pressed;
|
||||
match code {
|
||||
KeyCode::KeyW => {
|
||||
self.move_forward = is_pressed;
|
||||
},
|
||||
KeyCode::KeyS => {
|
||||
self.move_backward = is_pressed;
|
||||
},
|
||||
KeyCode::KeyA => {
|
||||
self.move_left = is_pressed;
|
||||
},
|
||||
KeyCode::KeyD => {
|
||||
self.move_right = is_pressed;
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn on_update(&mut self, context: &mut ScriptContext) {
|
||||
let mut look_vector = Vector3::default();
|
||||
let mut side_vector = Vector3::default();
|
||||
|
||||
if let Some(camera) = context.scene.graph.try_get_mut(self.camera) {
|
||||
look_vector = camera.look_vector();
|
||||
side_vector = camera.side_vector();
|
||||
|
||||
let yaw = UnitQuaternion::from_axis_angle(
|
||||
&Vector3::y_axis(), self.yaw.to_radians()
|
||||
);
|
||||
let transform = camera.local_transform_mut();
|
||||
transform.set_rotation(
|
||||
UnitQuaternion::from_axis_angle(
|
||||
&UnitVector3::new_normalize(yaw * Vector3::x()),
|
||||
self.pitch.to_radians(),
|
||||
) * yaw,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(rigid_body) = context.scene.graph.try_get_mut_of_type::<RigidBody>(context.handle) {
|
||||
let mut velocity = Vector3::new(0.0, 0.0, 0.0);
|
||||
if self.move_forward {
|
||||
velocity += look_vector;
|
||||
}
|
||||
if self.move_backward {
|
||||
velocity -= look_vector;
|
||||
}
|
||||
if self.move_left {
|
||||
velocity += side_vector;
|
||||
}
|
||||
if self.move_right {
|
||||
velocity -= side_vector;
|
||||
}
|
||||
|
||||
let y_vel = rigid_body.lin_vel().y;
|
||||
if let Some(normalized_velocity) = velocity.try_normalize(f32::EPSILON) {
|
||||
let movement_speed = 240.0 * context.dt;
|
||||
rigid_body.set_lin_vel(Vector3::new(
|
||||
normalized_velocity.x * movement_speed,
|
||||
y_vel,
|
||||
normalized_velocity.z * movement_speed,
|
||||
));
|
||||
} else {
|
||||
rigid_body.set_lin_vel(Vector3::new(0.0, y_vel, 0.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue