Move common code to Player-trait

This commit is contained in:
Sofia 2026-07-18 00:55:46 +03:00
parent cb0fa40d1a
commit 1761d730fc
3 changed files with 65 additions and 22 deletions

View File

@ -34,8 +34,6 @@ mesh = SubResource("PlaneMesh_1cgct")
shape = SubResource("BoxShape3D_1cgct")
[node name="player" parent="." unique_id=1910472598 instance=ExtResource("1_y4ph1")]
look_sensitivity = 1.5
move_speed = 10.0
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.4560637, 0)
[node name="directional_light_3d" type="DirectionalLight3D" parent="." unique_id=793524416]

View File

@ -4,8 +4,8 @@
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"]
[node name="player" type="Player" unique_id=1910472598 node_paths=PackedStringArray("camera")]
look_sensitivity = 1.0
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera")]
look_sensitivity = 1.5
camera = NodePath("camera_3d")
move_speed = 5.0
@ -17,3 +17,4 @@ shape = SubResource("CapsuleShape3D_1cgct")
[node name="camera_3d" type="Camera3D" parent="." unique_id=1773137418]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5391109, 0)
current = true

View File

@ -5,14 +5,51 @@ use godot::{
Camera3D, CharacterBody3D, ICharacterBody3D, Input, InputEvent, InputEventMouseMotion,
input::MouseMode,
},
obj::WithBaseField,
prelude::*,
};
use crate::ui::cli::CommandLinePanel;
pub trait Player: ICharacterBody3D + WithBaseField {
fn get_y_speed(&self) -> f32;
fn set_y_speed(&mut self, speed: f32);
fn get_movement_dir(&self) -> Vector3;
fn get_move_speed(&self) -> f32;
}
pub trait PlayerMovement {
fn player_update(&mut self, delta: f64);
fn jump(&mut self);
}
impl<T: Player + WithBaseField> PlayerMovement for T {
fn player_update(&mut self, delta: f64) {
self.set_y_speed(self.get_y_speed() - 9.8 * delta as f32);
if self.base().is_on_floor() && self.get_y_speed() < 0. {
self.set_y_speed(0.);
}
let speed = Vector3::UP * self.get_y_speed()
+ self
.get_movement_dir()
.try_normalized()
.unwrap_or_default()
.rotated(Vector3::UP, self.base().get_rotation().y)
* self.get_move_speed();
self.base_mut().set_velocity(speed);
self.base_mut().move_and_slide();
}
fn jump(&mut self) {
self.set_y_speed(5.);
}
}
#[derive(GodotClass)]
#[class(base=CharacterBody3D, init)]
pub struct Player {
pub struct LocalPlayer {
#[export]
look_sensitivity: f32,
#[export]
@ -20,6 +57,7 @@ pub struct Player {
#[export]
move_speed: f32,
movement_dir: Vector3,
y_speed: f32,
locked: bool,
@ -27,8 +65,26 @@ pub struct Player {
base: Base<CharacterBody3D>,
}
impl Player for LocalPlayer {
fn get_y_speed(&self) -> f32 {
self.y_speed
}
fn set_y_speed(&mut self, speed: f32) {
self.y_speed = speed;
}
fn get_movement_dir(&self) -> Vector3 {
self.movement_dir
}
fn get_move_speed(&self) -> f32 {
self.move_speed
}
}
#[godot_api]
impl ICharacterBody3D for Player {
impl ICharacterBody3D for LocalPlayer {
fn ready(&mut self) {
if !CommandLinePanel::singleton().bind().opened {
self.set_lock(true);
@ -47,16 +103,11 @@ impl ICharacterBody3D for Player {
}
fn process(&mut self, delta: f64) {
self.y_speed -= 9.8 * delta as f32;
if self.base().is_on_floor() && self.y_speed < 0. {
self.y_speed = 0.;
}
let input_direction = if self.locked {
let input = Input::singleton();
if self.base().is_on_floor() && input.is_action_just_pressed("jump") {
self.y_speed = 5.;
self.jump();
}
Vector3::RIGHT * input.is_action_pressed("right") as u32 as f32
@ -66,16 +117,9 @@ impl ICharacterBody3D for Player {
} else {
Vector3::ZERO
};
self.movement_dir = input_direction;
let speed = Vector3::UP * self.y_speed
+ input_direction
.try_normalized()
.unwrap_or_default()
.rotated(Vector3::UP, self.base().get_rotation().y)
* self.move_speed;
self.base_mut().set_velocity(speed);
self.base_mut().move_and_slide();
self.player_update(delta);
}
fn input(&mut self, event: Gd<InputEvent>) {
@ -98,7 +142,7 @@ impl ICharacterBody3D for Player {
}
}
impl Player {
impl LocalPlayer {
fn set_lock(&mut self, locked: bool) {
self.locked = locked;
if self.locked {