diff --git a/data/player.rgs b/data/player.rgs new file mode 100644 index 0000000..50d1d72 Binary files /dev/null and b/data/player.rgs differ diff --git a/data/scene.rgs b/data/scene.rgs index 3b96f9f..9bb1c4d 100644 Binary files a/data/scene.rgs and b/data/scene.rgs differ diff --git a/game/src/lib.rs b/game/src/lib.rs index 4692ecd..f17fa75 100644 --- a/game/src/lib.rs +++ b/game/src/lib.rs @@ -1,4 +1,7 @@ //! Game project. + +use crate::{player::Player}; + use fyrox::{ core::pool::Handle, core::visitor::prelude::*, core::reflect::prelude::*, event::Event, @@ -11,14 +14,20 @@ use std::path::Path; // Re-export the engine. pub use fyrox; +pub mod player; + #[derive(Default, Visit, Reflect, Debug)] pub struct Game { scene: Handle, } impl Plugin for Game { - fn register(&self, _context: PluginRegistrationContext) { + fn register(&self, context: PluginRegistrationContext) { // Register your scripts here. + context + .serialization_context + .script_constructors + .add::("Player"); } fn init(&mut self, scene_path: Option<&str>, context: PluginContext) { diff --git a/game/src/player.rs b/game/src/player.rs new file mode 100644 index 0000000..4f80bf5 --- /dev/null +++ b/game/src/player.rs @@ -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, +} + +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::(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)); + } + } + } +} + diff --git a/settings.ron b/settings.ron index 49e99ab..c8bc9a9 100644 --- a/settings.ron +++ b/settings.ron @@ -491,9 +491,9 @@ scene_settings: { "data/scene.rgs": ( camera_settings: ( - position: (-1.2582655, 0.37696767, -0.41422594), - yaw: 2.317344, - pitch: 0.2702732, + position: (0.6421091, 0.11491381, 1.7991738), + yaw: 4.735702, + pitch: 0.11656319, projection: Perspective(( fov: 1.3089969, z_near: 0.025, @@ -502,7 +502,7 @@ ), node_infos: { ( - index: 1, + index: 45, generation: 1, ): ( is_expanded: true, @@ -519,17 +519,75 @@ ): ( is_expanded: true, ), + ( + index: 46, + generation: 1, + ): ( + is_expanded: true, + ), + ( + index: 1, + generation: 1, + ): ( + is_expanded: true, + ), + ( + index: 69, + generation: 1, + ): ( + is_expanded: true, + ), + }, + ), + "/home/secondbeam/workspace/rust/fyrox/red_dragon_pon/data/player.rgs": ( + camera_settings: ( + position: (-1.9930856, 0.5251903, 1.349509), + yaw: 2.3208973, + pitch: 0.38800758, + projection: Perspective(( + fov: 1.3089969, + z_near: 0.025, + z_far: 128.0, + )), + ), + node_infos: {}, + ), + "data/player.rgs": ( + camera_settings: ( + position: (0.0, 1.0, 0.0), + yaw: 0.0, + pitch: 0.0, + projection: Perspective(( + fov: 1.3089969, + z_near: 0.025, + z_far: 128.0, + )), + ), + node_infos: { + ( + index: 1, + generation: 1, + ): ( + is_expanded: true, + ), + ( + index: 0, + generation: 1, + ): ( + is_expanded: true, + ), }, ), }, recent: ( scenes: [ + "data/player.rgs", "data/scene.rgs", ], ), windows: ( window_position: (0.0, 0.0), - window_size: (979.0, 505.0), + window_size: (1093.0, 505.0), window_maximized: false, layout: None, ),