181 lines
6.0 KiB
Rust
181 lines
6.0 KiB
Rust
use fyrox::{
|
|
animation::spritesheet::SpriteSheetAnimation,
|
|
core::{
|
|
algebra::{Vector2, Vector3},
|
|
pool::Handle,
|
|
reflect::prelude::*,
|
|
uuid::{uuid, Uuid},
|
|
visitor::prelude::*,
|
|
TypeUuidProvider,
|
|
},
|
|
keyboard::KeyCode,
|
|
scene::dim2::{rectangle::Rectangle, rigidbody::RigidBody},
|
|
scene::node::Node,
|
|
script::ScriptContext,
|
|
};
|
|
|
|
#[derive(Visit, Reflect, Debug, Clone, Default)]
|
|
pub struct Player {
|
|
sprite: Handle<Node>,
|
|
move_left: bool,
|
|
move_right: bool,
|
|
jump: bool,
|
|
animations: Vec<SpriteSheetAnimation>,
|
|
current_animation: u32,
|
|
current_frame: u32,
|
|
|
|
start_y_position: f32,
|
|
prev_y_velosity: f32,
|
|
}
|
|
|
|
impl TypeUuidProvider for Player {
|
|
// Returns unique script id for serialization needs.
|
|
fn type_uuid() -> Uuid {
|
|
uuid!("c5671d19-9f1a-4286-8486-add4ebaadaec")
|
|
}
|
|
}
|
|
|
|
impl Player {
|
|
pub fn init(&mut self, context: &mut ScriptContext) {
|
|
let rigid_body = context.scene.graph[context.handle].cast_mut::<RigidBody>();
|
|
match rigid_body {
|
|
Some(rigid_data) => {
|
|
self.start_y_position = rigid_data.global_position().y;
|
|
}
|
|
None => {}
|
|
}
|
|
}
|
|
|
|
pub fn loop_over(&mut self, context: &mut ScriptContext) {
|
|
let rigid_body = context.scene.graph[context.handle].cast_mut::<RigidBody>();
|
|
match rigid_body {
|
|
Some(rigid_data) => {
|
|
self.prev_y_velosity = rigid_data.lin_vel().y;
|
|
}
|
|
None => {}
|
|
}
|
|
}
|
|
|
|
pub fn key_checker(&mut self, keycode: KeyCode, is_pressed: bool) {
|
|
match keycode {
|
|
KeyCode::ArrowLeft => self.move_left = is_pressed,
|
|
KeyCode::ArrowRight => self.move_right = is_pressed,
|
|
KeyCode::ArrowUp => self.jump = is_pressed,
|
|
_ => (),
|
|
}
|
|
}
|
|
|
|
fn get_speed(&self) -> f32 {
|
|
return if self.move_left {
|
|
3.0
|
|
} else if self.move_right {
|
|
-3.0
|
|
} else {
|
|
0.0
|
|
};
|
|
}
|
|
|
|
pub fn move_do(&mut self, context: &mut ScriptContext) {
|
|
let rigid_body = context.scene.graph[context.handle].cast_mut::<RigidBody>();
|
|
match rigid_body {
|
|
Some(rigid_data) => {
|
|
let x_speed = self.get_speed();
|
|
rigid_data.set_lin_vel(Vector2::new(x_speed, rigid_data.lin_vel().y));
|
|
}
|
|
None => {}
|
|
}
|
|
}
|
|
|
|
pub fn is_in_fly(&self, rigid_data: &RigidBody) -> bool {
|
|
let dif_y = self.prev_y_velosity - rigid_data.lin_vel().y;
|
|
if dif_y > 0.0 && dif_y > 0.1 {
|
|
return true;
|
|
}
|
|
if dif_y < 0.0 && dif_y < -0.1 {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
pub fn jump_do(&mut self, context: &mut ScriptContext) {
|
|
let rigid_body = context.scene.graph[context.handle].cast_mut::<RigidBody>();
|
|
match rigid_body {
|
|
Some(rigid_data) => {
|
|
if self.jump && !self.is_in_fly(rigid_data) {
|
|
self.start_y_position = rigid_data.global_position().y;
|
|
rigid_data.set_lin_vel(Vector2::new(rigid_data.lin_vel().x, 6.0));
|
|
return;
|
|
}
|
|
if rigid_data.lin_vel().y == 0.0 && !self.is_in_fly(rigid_data) {
|
|
self.start_y_position = rigid_data.global_position().y;
|
|
}
|
|
|
|
// Log::info(format!(
|
|
// "pos {}, dif_height: {}, lin_vel: {}, jump: {}, is_jumping: {}",
|
|
// self.prev_y_velosity - rigid_data.lin_vel().y,
|
|
// self.dif_height(rigid_data),
|
|
// rigid_data.lin_vel().y,
|
|
// self.prev_y_velosity - rigid_data.lin_vel().y,
|
|
// self.is_in_fly(rigid_data),
|
|
// ));
|
|
}
|
|
None => {}
|
|
}
|
|
}
|
|
|
|
pub fn change_orientation(&self, context: &mut ScriptContext) {
|
|
let sprite = context.scene.graph.try_get_mut(self.sprite);
|
|
match sprite {
|
|
Some(sprite_data) => {
|
|
let x_speed = self.get_speed();
|
|
if x_speed == 0.0 {
|
|
return;
|
|
}
|
|
// It is always a good practice to check whether the handles are valid, at this point we don't know
|
|
// for sure what's the value of the `sprite` field. It can be unassigned and the following code won't
|
|
// execute. A simple `context.scene.graph[self.sprite]` would just panicked in this case.
|
|
let local_transform: &mut fyrox::scene::transform::Transform =
|
|
sprite_data.local_transform_mut();
|
|
let current_scale = **local_transform.scale();
|
|
local_transform.set_scale(Vector3::new(
|
|
// Just change X scaling to mirror player's sprite.
|
|
current_scale.x.copysign(-x_speed),
|
|
current_scale.y,
|
|
current_scale.z,
|
|
));
|
|
}
|
|
None => {}
|
|
}
|
|
}
|
|
|
|
fn animate_choose(&mut self) {
|
|
let x_speed = self.get_speed();
|
|
|
|
if x_speed != 0.0 {
|
|
self.current_animation = 0;
|
|
} else {
|
|
self.current_animation = 1;
|
|
}
|
|
}
|
|
|
|
pub fn animation_do(&mut self, context: &mut ScriptContext) {
|
|
self.animate_choose();
|
|
let current_animation = self.animations.get_mut(self.current_animation as usize);
|
|
match current_animation {
|
|
Some(animation_data) => {
|
|
animation_data.update(context.dt);
|
|
if let Some(sprite) = context
|
|
.scene
|
|
.graph
|
|
.try_get_mut(self.sprite)
|
|
.and_then(|n| n.cast_mut::<Rectangle>())
|
|
{
|
|
sprite.set_texture(animation_data.texture());
|
|
sprite.set_uv_rect(animation_data.current_frame_uv_rect().unwrap_or_default());
|
|
}
|
|
}
|
|
None => {}
|
|
}
|
|
}
|
|
}
|