add state machine and have player use it

This commit is contained in:
2022-04-11 13:30:51 -04:00
parent 6d2d1178a7
commit ecd6fe45b2
28 changed files with 1303 additions and 416 deletions

View File

@@ -0,0 +1,78 @@
#include "player/states/PlayerFall.h"
#include "player/Player.h"
using namespace godot;
using namespace player;
void PlayerFall::_register_methods()
{
register_method("_state_enter", &PlayerFall::_state_enter);
register_method("_state_exit", &PlayerFall::_state_exit);
register_method("_physics_process", &PlayerFall::_physics_process);
}
PlayerFall::PlayerFall()
{
}
PlayerFall::~PlayerFall()
{
}
void PlayerFall::_init()
{
_input = Input::get_singleton();
}
void PlayerFall::_state_enter()
{
animated_sprite = get_parent()->get_node<AnimatedSprite>("AnimatedSprite");
animated_sprite->stop();
animated_sprite->set_animation("air");
}
void PlayerFall::_state_exit()
{
animated_sprite->set_animation("move");
animated_sprite->set_frame(1);
}
void PlayerFall::_physics_process(float delta)
{
auto parent = Object::cast_to<player::Player>(get_parent());
if (parent->is_on_floor())
{
get_state_machine()->change("Move");
return;
}
auto current_speed = parent->get_speed();
auto velocity = parent->get_velocity();
velocity.x = 0;
if (_input->is_action_pressed("run"))
{
current_speed *= parent->get_run_speed();
}
if (_input->is_action_pressed("right"))
{
velocity.x += current_speed;
}
if (_input->is_action_pressed("left"))
{
velocity.x += -current_speed;
}
if (velocity.x > 0)
{
animated_sprite->set_flip_h(true);
}
else if (velocity.x < 0)
{
animated_sprite->set_flip_h(false);
}
parent->set_velocity(velocity);
}

View File

@@ -0,0 +1,44 @@
#ifndef JUEGO_PLAYER_FALL_H
#define JUEGO_PLAYER_FALL_H
#include "state_machine/State.h"
#include <Godot.hpp>
#include <Input.hpp>
#include <AnimatedSprite.hpp>
namespace godot
{
namespace player
{
class PlayerFall : public State
{
GODOT_CLASS(PlayerFall, State)
private:
Input *_input;
AnimatedSprite *animated_sprite;
public:
static void _register_methods();
PlayerFall();
~PlayerFall();
/**
* @brief Initialize the class from Godot.
* @details This method is called just once when the Godot engine connects to the instance of the class.
*/
void _init();
void _state_enter();
void _state_exit();
void _physics_process(float delta);
};
}
}
#endif

View File

@@ -0,0 +1,65 @@
#include "player/states/PlayerIdle.h"
#include "player/Player.h"
using namespace godot;
using namespace player;
void PlayerIdle::_register_methods()
{
register_method("_state_enter", &PlayerIdle::_state_enter);
register_method("_state_exit", &PlayerIdle::_state_exit);
register_method("_physics_process", &PlayerIdle::_physics_process);
}
PlayerIdle::PlayerIdle()
{
}
PlayerIdle::~PlayerIdle()
{
}
void PlayerIdle::_init()
{
_input = Input::get_singleton();
}
void PlayerIdle::_state_enter()
{
animated_sprite = get_parent()->get_node<AnimatedSprite>("AnimatedSprite");
animated_sprite->stop();
animated_sprite->set_animation("idle");
}
void PlayerIdle::_state_exit()
{
}
void PlayerIdle::_physics_process(float delta)
{
auto parent = Object::cast_to<player::Player>(get_parent());
if (_input->is_action_pressed("right"))
{
get_state_machine()->change("Move");
return;
}
if (_input->is_action_pressed("left"))
{
get_state_machine()->change("Move");
return;
}
if (_input->is_action_just_pressed("jump"))
{
get_state_machine()->change("Jump");
return;
}
if (!parent->is_on_floor())
{
get_state_machine()->change("Fall");
return;
}
}

View File

@@ -0,0 +1,45 @@
#ifndef JUEGO_PLAYER_IDLE_H
#define JUEGO_PLAYER_IDLE_H
#include "state_machine/State.h"
#include <Godot.hpp>
#include <Node.hpp>
#include <Input.hpp>
#include <AnimatedSprite.hpp>
namespace godot
{
namespace player
{
class PlayerIdle : public State
{
GODOT_CLASS(PlayerIdle, State)
private:
Input *_input;
AnimatedSprite *animated_sprite;
public:
static void _register_methods();
PlayerIdle();
~PlayerIdle();
/**
* @brief Initialize the class from Godot.
* @details This method is called just once when the Godot engine connects to the instance of the class.
*/
void _init();
void _state_enter();
void _state_exit();
void _physics_process(float delta);
};
}
}
#endif

View File

@@ -0,0 +1,105 @@
#include "player/states/PlayerJump.h"
#include "player/Player.h"
using namespace godot;
using namespace player;
void PlayerJump::_register_methods()
{
register_method("_state_enter", &PlayerJump::_state_enter);
register_method("_state_exit", &PlayerJump::_state_exit);
register_method("_physics_process", &PlayerJump::_physics_process);
}
PlayerJump::PlayerJump()
{
}
PlayerJump::~PlayerJump()
{
}
void PlayerJump::_init()
{
_input = Input::get_singleton();
}
void PlayerJump::_state_enter(const String state)
{
animated_sprite = get_parent()->get_node<AnimatedSprite>("AnimatedSprite");
animated_sprite->stop();
animated_sprite->set_animation("air");
if (state == "Jump")
{
double_jumped = true;
}
else
{
double_jumped = false;
}
auto parent = Object::cast_to<player::Player>(get_parent());
auto velocity = parent->get_velocity();
velocity.y = -parent->get_jump_force();
parent->set_velocity(velocity);
}
void PlayerJump::_state_exit()
{
animated_sprite->set_animation("move");
animated_sprite->set_frame(1);
}
void PlayerJump::_physics_process(float delta)
{
auto parent = Object::cast_to<player::Player>(get_parent());
if (parent->is_on_floor())
{
get_state_machine()->change("Move");
return;
}
auto current_speed = parent->get_speed();
auto velocity = parent->get_velocity();
velocity.x = 0;
if (_input->is_action_pressed("run"))
{
current_speed *= parent->get_run_speed();
}
if (_input->is_action_pressed("right"))
{
velocity.x += current_speed;
}
if (_input->is_action_pressed("left"))
{
velocity.x += -current_speed;
}
if (_input->is_action_just_released("jump"))
{
if (velocity.y < -100)
{
velocity.y = -100;
}
}
if (parent->get_double_jump() && !double_jumped && _input->is_action_just_pressed("jump"))
{
get_state_machine()->change("Jump");
return;
}
if (velocity.x > 0)
{
animated_sprite->set_flip_h(true);
}
else if (velocity.x < 0)
{
animated_sprite->set_flip_h(false);
}
parent->set_velocity(velocity);
}

View File

@@ -0,0 +1,45 @@
#ifndef JUEGO_PLAYER_JUMP_H
#define JUEGO_PLAYER_JUMP_H
#include "state_machine/State.h"
#include <Godot.hpp>
#include <Input.hpp>
#include <AnimatedSprite.hpp>
namespace godot
{
namespace player
{
class PlayerJump : public State
{
GODOT_CLASS(PlayerJump, State)
private:
Input *_input;
AnimatedSprite *animated_sprite;
bool double_jumped;
public:
static void _register_methods();
PlayerJump();
~PlayerJump();
/**
* @brief Initialize the class from Godot.
* @details This method is called just once when the Godot engine connects to the instance of the class.
*/
void _init();
void _state_enter(const String state);
void _state_exit();
void _physics_process(float delta);
};
}
}
#endif

View File

@@ -0,0 +1,94 @@
#include "player/states/PlayerMove.h"
#include "player/Player.h"
using namespace godot;
using namespace player;
void PlayerMove::_register_methods()
{
register_method("_state_enter", &PlayerMove::_state_enter);
register_method("_state_exit", &PlayerMove::_state_exit);
register_method("_physics_process", &PlayerMove::_physics_process);
}
PlayerMove::PlayerMove()
{
}
PlayerMove::~PlayerMove()
{
}
void PlayerMove::_init()
{
_input = Input::get_singleton();
}
void PlayerMove::_state_enter(String state, Array args)
{
animated_sprite = get_parent()->get_node<AnimatedSprite>("AnimatedSprite");
animated_sprite->set_animation("move");
animated_sprite->play();
}
void PlayerMove::_state_exit()
{
}
void PlayerMove::_physics_process(float delta)
{
auto parent = Object::cast_to<player::Player>(get_parent());
auto direction_pressed = false;
auto current_speed = parent->get_speed();
auto velocity = parent->get_velocity();
velocity.x = 0;
if (_input->is_action_pressed("run"))
{
current_speed *= parent->get_run_speed();
}
if (_input->is_action_pressed("right"))
{
direction_pressed = true;
velocity.x += current_speed;
}
if (_input->is_action_pressed("left"))
{
direction_pressed = true;
velocity.x += -current_speed;
}
if (_input->is_action_just_pressed("jump"))
{
get_state_machine()->change("Jump");
return;
}
if (velocity.x > 0)
{
animated_sprite->set_flip_h(true);
}
else if (velocity.x < 0)
{
animated_sprite->set_flip_h(false);
}
else
{
if (!direction_pressed)
{
get_state_machine()->change("Idle");
}
return;
}
parent->set_velocity(velocity);
if (!parent->is_on_floor())
{
get_state_machine()->change("Fall");
return;
}
}

View File

@@ -0,0 +1,46 @@
#ifndef JUEGO_PLAYER_MOVE_H
#define JUEGO_PLAYER_MOVE_H
#include "state_machine/State.h"
#include <Godot.hpp>
#include <Input.hpp>
#include <AnimatedSprite.hpp>
namespace godot
{
namespace player
{
class PlayerMove : public State
{
GODOT_CLASS(PlayerMove, State)
private:
Input *_input;
AnimatedSprite *animated_sprite;
public:
static void _register_methods();
PlayerMove();
~PlayerMove();
/**
* @brief Initialize the class from Godot.
* @details This method is called just once when the Godot engine connects to the instance of the class.
*/
void _init();
void _state_enter(String state, Array args);
void _state_exit();
void _physics_process(float delta);
Vector2 move_player(Vector2 velocity);
};
}
}
#endif