feat: TEST DAY TEST DAY TEST DAY

This commit is contained in:
Sara 2025-06-02 17:17:49 +02:00
parent 7af00521df
commit 9dca189fa5
38 changed files with 592 additions and 102 deletions

33
modules/going/game_ui.cpp Normal file
View file

@ -0,0 +1,33 @@
#include "game_ui.h"
GameUI *GameUI::singleton_instance{nullptr};
void GameUI::_bind_methods() {
ClassDB::bind_method(D_METHOD("display_message", "text"), &self_type::display_message);
ClassDB::bind_static_method("GameUI", D_METHOD("get_singleton"), &self_type::get_singleton);
}
void GameUI::_notification(int what) {
if(Engine::get_singleton()->is_editor_hint()) {
return;
}
if(what == NOTIFICATION_ENTER_TREE) {
ERR_FAIL_COND_EDMSG(self_type::singleton_instance != nullptr, "GameUI instance already exists, deleting second instance");
self_type::singleton_instance = this;
} else if(what == NOTIFICATION_EXIT_TREE) {
self_type::singleton_instance = nullptr;
}
if(what == NOTIFICATION_READY) {
this->message = Object::cast_to<RichTextLabel>(this->get_node(NodePath("%MessageLabel")));
this->clear_message_timer = Object::cast_to<Timer>(this->get_node(NodePath("%ClearMessageTimer")));
}
}
GameUI *GameUI::get_singleton() {
return self_type::singleton_instance;
}
void GameUI::display_message(String text) {
this->message->set_text(text);
this->clear_message_timer->start(0.0);
}

22
modules/going/game_ui.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef GAME_UI_H
#define GAME_UI_H
#include "core/string/ustring.h"
#include "scene/main/canvas_layer.h"
#include "scene/gui/rich_text_label.h"
#include "scene/main/timer.h"
class GameUI : public CanvasLayer {
GDCLASS(GameUI, CanvasLayer);
static void _bind_methods();
void _notification(int what);
static GameUI *singleton_instance;
public:
static GameUI *get_singleton();
void display_message(String text);
private:
RichTextLabel *message{nullptr};
Timer *clear_message_timer{nullptr};
};
#endif // !GAME_UI_H

View file

@ -28,6 +28,8 @@ void PlayerBody::_bind_methods() {
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);
}
void PlayerBody::_notification(int what) {
@ -189,3 +191,19 @@ void PlayerBody::set_model_lean_speed(float value) {
float PlayerBody::get_model_lean_speed() const {
return this->model_lean_speed;
}
void PlayerBody::set_game_over_speed(float value) {
this->game_over_speed = value;
}
float PlayerBody::get_game_over_speed() const {
return this->game_over_speed;
}
void PlayerBody::set_can_jump(bool value) {
this->can_jump = value;
}
bool PlayerBody::get_can_jump() const {
return this->can_jump;
}

View file

@ -44,6 +44,10 @@ public:
float get_model_lean() const;
void set_model_lean_speed(float value);
float get_model_lean_speed() const;
void set_game_over_speed(float value);
float get_game_over_speed() const;
void set_can_jump(bool value);
bool get_can_jump() const;
private:
Vector2 movement{0.f, 0.f};
@ -65,6 +69,8 @@ private:
double max_delta_fov{100.f};
float model_lean{0.25f};
float model_lean_speed{0.25f};
double game_over_speed{1.0/4.0};
bool can_jump{false};
public:
static char *const split_step_action;
static char *const move_left_action;

View file

@ -3,6 +3,8 @@
#include "core/math/math_funcs.h"
#include "core/typedefs.h"
#include "going/player_body.h"
#include "scene/main/scene_tree.h"
#include "servers/rendering_server.h"
PlayerBody *PlayerState::get_body() const {
@ -21,6 +23,18 @@ PlayerState::StateID StandingState::get_next_state() const {
void StandingState::state_entered() {
this->get_body()->get_anim()->play("RESET", 0.1);
this->game_over_timer = 0.0;
}
void StandingState::process(double delta) {
this->game_over_timer += delta * this->get_body()->get_game_over_speed();
if(this->game_over_timer > 1.0) {
RenderingServer::get_singleton()->global_shader_parameter_set(this->game_over_param, 0.0);
SceneTree::get_singleton()->reload_current_scene();
} else {
RenderingServer::get_singleton()->global_shader_parameter_set(this->game_over_param, float(this->game_over_timer));
this->game_over_timer = MIN(this->game_over_timer, 1.f);
}
}
void StandingState::physics_process(double delta) {
@ -29,6 +43,10 @@ void StandingState::physics_process(double delta) {
this->get_body()->set_velocity(current.move_toward(Vector3(), speed_delta));
}
void StandingState::state_exited() {
RenderingServer::get_singleton()->global_shader_parameter_set(this->game_over_param, 0.0f);
}
PlayerState::StateID RunningState::get_next_state() const {
Vector3 const velocity{this->get_body()->get_velocity()};
Vector3 const desired{this->get_body()->get_desired_velocity()};
@ -47,7 +65,7 @@ void RunningState::state_entered() {
this->get_body()->get_anim()->play("run", 0.1);
}
void RunningState::process(double delta) {
void RunningState::process_lean(double delta) {
Vector3 const current{this->get_body()->get_velocity()};
if(!current.is_zero_approx()) {
Vector3 const cross{Vector3{0.f, 1.f, 0.f}.cross(current).normalized()};
@ -77,6 +95,7 @@ void RunningState::physics_process(double delta) {
)
};
this->get_body()->set_velocity(current.move_toward(desired, speed_delta) + Vector3{0.f, -0.01f, 0.f});
this->process_lean(delta);
}
void RunningState::state_exited() {
@ -91,7 +110,7 @@ void RunningState::state_exited() {
PlayerState::StateID SplitStepState::get_next_state() const {
if(!this->get_body()->is_on_floor()) {
return FallingState::get_class_static();
} else if(this->timer <= 0.0 && Input::get_singleton()->is_action_pressed("jump")) {
} else if(this->get_body()->get_can_jump() && this->jump && this->timer <= 0.0) {
return JumpingState::get_class_static();
} else if(this->timer <= 0.0) {
return RunningState::get_class_static();
@ -101,6 +120,7 @@ PlayerState::StateID SplitStepState::get_next_state() const {
}
void SplitStepState::state_entered() {
this->jump = false;
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);
@ -111,17 +131,21 @@ void SplitStepState::process(double delta) {
this->timer -= delta;
this->get_body()->set_velocity(this->get_body()->get_velocity()
.move_toward(Vector3(), this->get_body()->get_target_speed() / this->get_body()->get_split_step_stop_time() * delta));
this->jump |= Input::get_singleton()->is_action_pressed("jump");
}
void SplitStepState::state_exited() {
if(this->get_body()->is_on_floor()) {
Vector3 const desired_direction{this->get_body()->get_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()
);
Vector3 desired_direction{0.f, 0.f, 0.f};
if(this->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();
}
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()
);
}
PlayerState::StateID FallingState::get_next_state() const {
@ -133,13 +157,29 @@ PlayerState::StateID FallingState::get_next_state() const {
}
void FallingState::state_entered() {
this->game_over_timer = 0.0;
this->get_body()->get_anim()->play("falling", 0.1);
}
void FallingState::process(double delta) {
Vector3 const current{this->get_body()->get_velocity()};
Vector3 const flattened{current.x, 0.f, current.z};
this->get_body()->set_velocity((flattened - (flattened * 0.025f)) + Vector3{0.f, current.y - float(9.8 * delta), 0.f});
this->get_body()->set_velocity((flattened - (flattened * 0.015f)) + Vector3{0.f, current.y - float(9.8 * delta), 0.f});
if(this->can_game_over_falling) {
this->game_over_timer += delta * this->get_body()->get_game_over_speed();
if(this->game_over_timer > 1.0) {
RenderingServer::get_singleton()->global_shader_parameter_set(this->game_over_param, 0.0);
SceneTree::get_singleton()->reload_current_scene();
} else {
RenderingServer::get_singleton()->global_shader_parameter_set(this->game_over_param, float(this->game_over_timer));
this->game_over_timer = MIN(this->game_over_timer, 1.f);
}
}
}
void FallingState::state_exited() {
RenderingServer::get_singleton()->global_shader_parameter_set(this->game_over_param, 0.0);
this->can_game_over_falling = true;
}
PlayerState::StateID JumpingState::get_next_state() const {
@ -153,18 +193,17 @@ PlayerState::StateID JumpingState::get_next_state() const {
void JumpingState::state_entered() {
Vector3 const current{this->get_body()->get_velocity()};
Vector2 const impulse{this->get_body()->get_jump_impulse()};
float const force{(Vector2{current.x, current.z}.length() / this->get_body()->get_target_speed())};
this->get_body()->set_velocity( (
Vector3{current.x, impulse.y, current.z}
+ current.normalized() * impulse.x
) * force);
));
this->get_body()->get_anim()->play("jump");
}
void JumpingState::process(double delta) {
Vector3 const current{this->get_body()->get_velocity()};
Vector3 const flattened{current.x, 0.f, current.z};
this->get_body()->set_velocity((flattened - (flattened * 0.025f)) + Vector3{0.f, current.y - float(9.8 * delta), 0.f});
this->get_body()->set_velocity((flattened - (flattened * 0.015f)) + Vector3{0.f, current.y - float(9.8 * delta), 0.f});
}
void PlayerStateMachine::_bind_methods() {
@ -194,10 +233,10 @@ void PlayerStateMachine::ready() {
this->set_process(true);
this->set_physics_process(true);
this->body = Object::cast_to<PlayerBody>(this->get_parent());
this->add_state<FallingState>();
this->add_state<StandingState>();
this->add_state<RunningState>();
this->add_state<SplitStepState>();
this->add_state<FallingState>();
this->add_state<JumpingState>();
}

View file

@ -30,7 +30,12 @@ class StandingState : public 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:
double game_over_timer{0.0};
StringName game_over_param{"game_over_percentage"};
};
class RunningState : public PlayerState {
@ -38,7 +43,7 @@ class RunningState : public PlayerState {
public:
virtual StateID get_next_state() const override;
virtual void state_entered() override;
virtual void process(double delta) override;
void process_lean(double delta);
virtual void physics_process(double delta) override;
virtual void state_exited() override;
private:
@ -55,6 +60,7 @@ public:
private:
Vector3 last_velocity{0.f, 0.f, 0.f};
double timer{0.0};
bool jump{false};
};
class FallingState : public PlayerState {
@ -63,6 +69,11 @@ public:
virtual StateID get_next_state() const override;
virtual void state_entered() override;
virtual void process(double delta) override;
virtual void state_exited() override;
private:
bool can_game_over_falling{false};
double game_over_timer{0.0};
StringName game_over_param{"game_over_percentage"};
};
class JumpingState : public PlayerState {

View file

@ -1,6 +1,7 @@
#include "register_types.h"
#include "core/object/class_db.h"
#include "going/game_ui.h"
#include "going/player_body.h"
#include "going/player_states.h"
@ -16,6 +17,7 @@ void initialize_going_module(ModuleInitializationLevel p_level) {
ClassDB::register_class<FallingState>();
ClassDB::register_class<JumpingState>();
ClassDB::register_class<PlayerStateMachine>();
ClassDB::register_class<GameUI>();
}
void uninitialize_going_module(ModuleInitializationLevel p_level) {