feat: final bits
This commit is contained in:
parent
d64c8d2b61
commit
cebae80b5c
34 changed files with 1827 additions and 373 deletions
|
|
@ -29,11 +29,14 @@ void PlayerBody::_bind_methods() {
|
|||
BIND_PROPERTY(Variant::FLOAT, target_speed);
|
||||
BIND_PROPERTY(Variant::FLOAT, split_step_time);
|
||||
BIND_PROPERTY(Variant::FLOAT, split_step_stop_time);
|
||||
BIND_PROPERTY(Variant::FLOAT, bash_speed);
|
||||
BIND_PROPERTY(Variant::FLOAT, bash_time);
|
||||
BIND_PROPERTY(Variant::VECTOR2, jump_impulse);
|
||||
BIND_PROPERTY(Variant::FLOAT, model_lean);
|
||||
BIND_PROPERTY(Variant::FLOAT, model_lean_speed);
|
||||
BIND_PROPERTY(Variant::FLOAT, game_over_speed);
|
||||
BIND_PROPERTY(Variant::BOOL, can_jump);
|
||||
BIND_PROPERTY(Variant::BOOL, can_bash);
|
||||
}
|
||||
|
||||
void PlayerBody::_notification(int what) {
|
||||
|
|
@ -191,6 +194,22 @@ double PlayerBody::get_split_step_stop_time() const {
|
|||
return this->split_step_stop_time;
|
||||
}
|
||||
|
||||
void PlayerBody::set_bash_speed(float value) {
|
||||
this->bash_speed = value;
|
||||
}
|
||||
|
||||
float PlayerBody::get_bash_speed() const {
|
||||
return this->bash_speed;
|
||||
}
|
||||
|
||||
void PlayerBody::set_bash_time(double value) {
|
||||
this->bash_time = value;
|
||||
}
|
||||
|
||||
double PlayerBody::get_bash_time() const {
|
||||
return this->bash_time;
|
||||
}
|
||||
|
||||
void PlayerBody::set_jump_impulse(Vector2 value) {
|
||||
this->jump_impulse = value;
|
||||
}
|
||||
|
|
@ -230,3 +249,11 @@ void PlayerBody::set_can_jump(bool value) {
|
|||
bool PlayerBody::get_can_jump() const {
|
||||
return this->can_jump;
|
||||
}
|
||||
|
||||
void PlayerBody::set_can_bash(bool value) {
|
||||
this->can_bash = value;
|
||||
}
|
||||
|
||||
bool PlayerBody::get_can_bash() const {
|
||||
return this->can_bash;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ public:
|
|||
double get_split_step_time() const;
|
||||
void set_split_step_stop_time(double value);
|
||||
double get_split_step_stop_time() const;
|
||||
void set_bash_speed(float value);
|
||||
float get_bash_speed() const;
|
||||
void set_bash_time(double value);
|
||||
double get_bash_time() const;
|
||||
void set_jump_impulse(Vector2 value);
|
||||
Vector2 get_jump_impulse() const;
|
||||
void set_model_lean(float value);
|
||||
|
|
@ -53,6 +57,8 @@ public:
|
|||
float get_game_over_speed() const;
|
||||
void set_can_jump(bool value);
|
||||
bool get_can_jump() const;
|
||||
void set_can_bash(bool value);
|
||||
bool get_can_bash() const;
|
||||
private:
|
||||
Vector2 movement{0.f, 0.f};
|
||||
|
||||
|
|
@ -68,6 +74,8 @@ private:
|
|||
float target_speed{30.f};
|
||||
double split_step_time{0.5};
|
||||
double split_step_stop_time{0.5};
|
||||
float bash_speed{100.f};
|
||||
double bash_time{0.25};
|
||||
Vector2 jump_impulse{5.f, 5.f};
|
||||
float max_speed_fov{100.f};
|
||||
float min_fov{80.f};
|
||||
|
|
@ -75,6 +83,7 @@ private:
|
|||
float model_lean{0.25f};
|
||||
float model_lean_speed{0.25f};
|
||||
double game_over_speed{1.0/4.0};
|
||||
bool can_bash{false};
|
||||
bool can_jump{false};
|
||||
Ref<Checkpoint> last_checkpoint{nullptr};
|
||||
PlayerStateMachine *state{nullptr};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "player_states.h"
|
||||
#include "core/config/engine.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "core/typedefs.h"
|
||||
#include "going/player_body.h"
|
||||
#include "scene/main/scene_tree.h"
|
||||
|
|
@ -109,9 +110,10 @@ void RunningState::state_exited() {
|
|||
}
|
||||
|
||||
PlayerState::StateID SplitStepState::get_next_state() const {
|
||||
bool const jump_input{this->get_body()->get_can_jump() && this->jump};
|
||||
if(jump_input && (this->timer <= 0.0 || !this->get_body()->is_on_floor())) {
|
||||
if(this->next == Jump && (this->timer <= 0.0 || !this->get_body()->is_on_floor())) {
|
||||
return JumpingState::get_class_static();
|
||||
} else if(this->next == Bash && (this->timer <= 0.0 || !this->get_body()->is_on_floor())) {
|
||||
return BashState::get_class_static();
|
||||
} else if(!this->get_body()->is_on_floor()) {
|
||||
return FallingState::get_class_static();
|
||||
} else if(this->timer <= 0.0) {
|
||||
|
|
@ -122,7 +124,7 @@ PlayerState::StateID SplitStepState::get_next_state() const {
|
|||
}
|
||||
|
||||
void SplitStepState::state_entered() {
|
||||
this->jump = false;
|
||||
this->next = Run;
|
||||
this->last_velocity = this->get_body()->get_velocity();
|
||||
this->timer = this->get_body()->get_split_step_time();
|
||||
this->get_body()->set_velocity(last_velocity.normalized() * this->get_body()->get_target_speed() * 0.75f);
|
||||
|
|
@ -131,7 +133,12 @@ void SplitStepState::state_entered() {
|
|||
|
||||
void SplitStepState::process(double delta) {
|
||||
this->timer -= delta;
|
||||
this->jump |= Input::get_singleton()->is_action_pressed("jump");
|
||||
if(this->get_body()->get_can_jump() && Input::get_singleton()->is_action_pressed("jump")) {
|
||||
this->next = Jump;
|
||||
}
|
||||
if(this->get_body()->get_can_bash() && Input::get_singleton()->is_action_pressed("bash")) {
|
||||
this->next = Bash;
|
||||
}
|
||||
}
|
||||
|
||||
void SplitStepState::physics_process(double delta) {
|
||||
|
|
@ -141,12 +148,21 @@ void SplitStepState::physics_process(double delta) {
|
|||
|
||||
void SplitStepState::state_exited() {
|
||||
Vector3 desired_direction{0.f, 0.f, 0.f};
|
||||
if(this->jump) {
|
||||
switch(this->next) {
|
||||
case Jump:
|
||||
desired_direction = Vector3{last_velocity.x, 0.f, last_velocity.z}.normalized();
|
||||
} else if(this->get_body()->is_on_floor()) {
|
||||
desired_direction = this->get_body()->get_desired_direction();
|
||||
break;
|
||||
case Bash:
|
||||
default:
|
||||
if(this->get_body()->is_on_floor()) {
|
||||
desired_direction = this->get_body()->get_desired_direction();
|
||||
}
|
||||
break;
|
||||
}
|
||||
float const dot{this->last_velocity.normalized().dot(desired_direction)};
|
||||
float const dot{this->last_velocity
|
||||
.normalized()
|
||||
.dot(desired_direction)
|
||||
};
|
||||
this->get_body()->set_velocity(dot > -0.8f
|
||||
? desired_direction * MAX(last_velocity.length(), this->get_body()->get_step_boost())
|
||||
: Vector3()
|
||||
|
|
@ -162,7 +178,7 @@ PlayerState::StateID FallingState::get_next_state() const {
|
|||
}
|
||||
|
||||
void FallingState::state_entered() {
|
||||
this->get_body()->get_anim()->play("falling", 0.1);
|
||||
this->get_body()->get_anim()->play("falling", 0.25);
|
||||
}
|
||||
|
||||
void FallingState::physics_process(double delta) {
|
||||
|
|
@ -194,7 +210,48 @@ void JumpingState::physics_process(double delta) {
|
|||
this->get_body()->set_velocity((flattened - (flattened * 0.015f)) + Vector3{0.f, current.y - float(9.8 * delta), 0.f});
|
||||
}
|
||||
|
||||
|
||||
PlayerState::StateID BashState::get_next_state() const {
|
||||
if(!this->get_body()->is_on_floor()) {
|
||||
return FallingState::get_class_static();
|
||||
} else if (this->timer < 0.0) {
|
||||
return StandingState::get_class_static();
|
||||
}
|
||||
return this->get_class();
|
||||
}
|
||||
|
||||
void BashState::state_entered() {
|
||||
this->get_body()->get_anim()->play("bash");
|
||||
this->timer = this->get_body()->get_bash_time();
|
||||
this->speed = this->get_body()->get_bash_speed();
|
||||
(this->vfx = Object::cast_to<Node3D>(this->get_body()->get_node(this->vfx_path)))->set_visible(true);
|
||||
}
|
||||
|
||||
void BashState::process(double delta) {
|
||||
this->timer -= delta;
|
||||
}
|
||||
|
||||
void BashState::physics_process(double delta) {
|
||||
double const progress{1.0 - this->timer / this->get_body()->get_bash_time()};
|
||||
this->get_body()->set_velocity(
|
||||
Math::lerp(
|
||||
this->get_body()->get_bash_speed(),
|
||||
this->get_body()->get_target_speed(),
|
||||
float(progress)
|
||||
) * this->get_body()->get_model()->get_global_basis().get_column(2).normalized()
|
||||
+ Vector3{0, float(-2.0 / delta), 0}
|
||||
);
|
||||
}
|
||||
|
||||
void BashState::state_exited() {
|
||||
this->vfx->set_visible(false);
|
||||
if(!this->get_body()->is_on_floor()) {
|
||||
this->get_body()->set_velocity(this->get_body()->get_velocity() / 2.f);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerStateMachine::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_current_state"), &self_type::get_current_state);
|
||||
}
|
||||
|
||||
void PlayerStateMachine::_notification(int what) {
|
||||
|
|
@ -226,6 +283,7 @@ void PlayerStateMachine::ready() {
|
|||
this->add_state<RunningState>();
|
||||
this->add_state<SplitStepState>();
|
||||
this->add_state<JumpingState>();
|
||||
this->add_state<BashState>();
|
||||
}
|
||||
|
||||
void PlayerStateMachine::try_transition() {
|
||||
|
|
@ -236,3 +294,7 @@ void PlayerStateMachine::try_transition() {
|
|||
this->current_state->state_entered();
|
||||
}
|
||||
}
|
||||
|
||||
StringName PlayerStateMachine::get_current_state() const {
|
||||
return this->current_state->get_class();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,9 +59,12 @@ public:
|
|||
virtual void physics_process(double delta) override;
|
||||
virtual void state_exited() override;
|
||||
private:
|
||||
enum NextAction {
|
||||
Run, Bash, Jump
|
||||
};
|
||||
Vector3 last_velocity{0.f, 0.f, 0.f};
|
||||
double timer{0.0};
|
||||
bool jump{false};
|
||||
NextAction next{Run};
|
||||
};
|
||||
|
||||
class FallingState : public PlayerState {
|
||||
|
|
@ -80,6 +83,21 @@ public:
|
|||
virtual void physics_process(double delta) override;
|
||||
};
|
||||
|
||||
class BashState : public PlayerState {
|
||||
GDCLASS(BashState, PlayerState);
|
||||
public:
|
||||
virtual StateID get_next_state() const override;
|
||||
virtual void state_entered() override;
|
||||
virtual void process(double delta) override;
|
||||
virtual void physics_process(double delta) override;
|
||||
virtual void state_exited() override;
|
||||
private:
|
||||
NodePath vfx_path{"character/bash_attack"};
|
||||
Node3D *vfx{nullptr};
|
||||
double timer{0.0};
|
||||
float speed{0.f};
|
||||
};
|
||||
|
||||
class PlayerStateMachine : public Node {
|
||||
GDCLASS(PlayerStateMachine, Node);
|
||||
static void _bind_methods();
|
||||
|
|
@ -89,6 +107,7 @@ class PlayerStateMachine : public Node {
|
|||
template <class TState>
|
||||
void add_state();
|
||||
public:
|
||||
StringName get_current_state() const;
|
||||
template <class TState>
|
||||
void force_state();
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ void initialize_going_module(ModuleInitializationLevel p_level) {
|
|||
ClassDB::register_class<SplitStepState>();
|
||||
ClassDB::register_class<FallingState>();
|
||||
ClassDB::register_class<JumpingState>();
|
||||
ClassDB::register_class<BashState>();
|
||||
ClassDB::register_class<PlayerStateMachine>();
|
||||
ClassDB::register_class<GameUI>();
|
||||
ClassDB::register_class<Checkpoint>();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue