red_dragon_pon/game/src/player.rs

145 lines
4.6 KiB
Rust

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));
}
}
}
}