dungeonanddeamon/DungeonAndDeamonScript/DungeonAndDemaonScript/GestionPlayer.cpp
2020-05-03 15:35:51 +02:00

318 lines
8.0 KiB
C++

#include "GestionPlayer.h"
#include <SpriteFrames.hpp>
#include <ConfigFile.hpp>
#include <Input.hpp>
#include <ResourceLoader.hpp>
#include <Texture.hpp>
#include <InputEventKey.hpp>
GestionPlayer::GestionPlayer()
{
sprite_player_ptr = AnimatedSprite::_new();
texture_player_ptr.instance();
texture_player_ptr->_new();
}
void GestionPlayer::_register_methods()
{
Godot::print("register Player...");
register_method("_physics_process", &GestionPlayer::_physics_process);
register_method("_process", &GestionPlayer::_process);
register_method("_init", &GestionPlayer::_init);
register_method("_ready", &GestionPlayer::_ready);
Godot::print("register Player OK!");
}
//fonction _pgysics_process meilleur rafraichissement de 60 fps comparé à 30 pour la fonction _process meilleur pour les mouvements plus fluides du mob
void GestionPlayer::_physics_process(float dt) // dt = deltaTime
{
p.velocity = move_and_slide(p.velocity);
}
void GestionPlayer::_process(float dt) // dt = deltaTime
{
PlayerLogic_AutoReset();
traitementInput();
PlayerLogic(dt);
}
void GestionPlayer::_init()
{
createPlayer();
}
void GestionPlayer::_ready()
{
setupPlayer();
playerState.Reset();
}
void GestionPlayer::createPlayer()
{
add_child(sprite_player_ptr);
}
//setup des textures et des animations avec l'extension .tres qu'on a créé grâce à l'interface Godot et les fonctions animated sprite
void GestionPlayer::setupPlayer()
{
//Chargement de la texture
//Godot::print("SetUp de Texture");
texture_player_ptr = ResourceLoader::get_singleton()->load("res://Character/Hero Knight/HeroKnight/Layer 1_sprite_01.png");
//setup du sprite
//Godot::print("SetUp de Sprite");
Ref<SpriteFrames> spriteFrames = ResourceLoader::get_singleton()->load("res://Character/Hero Knight/HeroKnight/HeroKnight.tres");
sprite_player_ptr->set_sprite_frames(spriteFrames);
PoolStringArray AnimNames = spriteFrames->get_animation_names();
PoolStringArray::Read r = AnimNames.read();
Godot::print("Animations Names");
for (int i = 0; i < AnimNames.size(); ++i)
{
Godot::print(r[i]);
}
}
//Fonction traitement des touches pour le déplacement du joueur, is_action_pressed fonction godot ou l'on peut changer les contrôles dans le menu godot. projet->Parametre du projet ->Contrôles
//Traitement des inputs avec des boulleen de la structure du joueur pour créer un arbre d'état et simplifier la mise en place des animations
void GestionPlayer::traitementInput()
{
// manage Inputs
Input* i = Input::get_singleton();
// move in X directions
p.velocity.x = 0.0f; // rest x, keyboard action will change this
if (i->is_action_pressed("ui_left"))
playerState.Flags.left = true;
if (i->is_action_pressed("ui_right"))
playerState.Flags.right = true;
if (i->is_action_pressed("dash"))
playerState.Flags.dash = true;
if (i->is_action_pressed("attack"))
playerState.Flags.attack = true;
if (i->is_action_pressed("attack2"))
playerState.Flags.bigattack = true;
if (i->is_action_pressed("block"))
playerState.Flags.block = true;
// move in Y directions
if (i->is_action_pressed("ui_select"))
playerState.Flags.jump = true;
}
//Fonction pour savoir si les animations sont terminé pour éviter les loops et les problèmes d'animation non términé
//mettre en place un flag isInBlockingAnimation
//tant que ce flag est a true on block la player logic pour ne pas interrompre l'animation avec une autre anim(marche / saut par exemple)
//d'où le besoin de tester la fin de l'animation dans PlayerLogic_AutoReset) pour debloquer le isInBlockingAnimation = false;
//et au debut de player logic on sort si on est en blocking anim
void GestionPlayer::PlayerLogic_AutoReset()
{
playerState.Flags.right = false;
playerState.Flags.left = false;
if (on_ground)
{
playerState.Flags.jump = false;
playerState.Flags.freefall = false;
}
if (playerState.Flags.isInBlockingAnimation)
{
int64_t frame = sprite_player_ptr->get_frame();
String animation = sprite_player_ptr->get_animation();
CharString name = animation.ascii();
const char* nameascii = name.get_data();
int64_t frame_count = sprite_player_ptr->get_sprite_frames()->get_frame_count(animation);
if (frame == frame_count-1)
{
playerState.Flags.isInBlockingAnimation = false;
}
}
}
//Etat du joueur pour détérminer les futurs action, saut, au sol, chute libre et pour gérer les différentes animations avec les drapeaux
void GestionPlayer::PlayerLogic(float dt)
{
Godot::print("PlayerLogic");
if (playerState.Flags.isInBlockingAnimation)
{
// do nothing until blocking animation is finished
Godot::print("\t Blocking Animation");
return;
}
if (playerState.Flags.jump)
{
// attack en l'air
PlayerLogic_Jump(dt);
}
else
{
// attack au sol
if (on_ground)
{
PlayerLogic_OnGround(dt);
}
else
{ // we fall from the ground
playerState.Flags.freefall = true;
}
}
if(playerState.Flags.freefall)
{
// attack en freefall
PlayerLogic_FreeFall(dt);
}
}
//Fonction gérant le saut du joueur et ces animations en fonctions des Flags et si le joueur est en contacte avec le sol ou non
//Fonction gérant la gravité avec dt= delta time
//fonction qui gere aussi le sens des aniamtions en fonction de la vitesse
void GestionPlayer::PlayerLogic_Jump(float dt)
{
Godot::print("\t Jump");
if (on_ground)
{
p.velocity.y = power_jump;
}
else
{
p.velocity.y += gravity * dt;
}
if (p.velocity.y > 0.0f)
{
playerState.Flags.jump = false;
playerState.Flags.freefall = true;
}
else
{
if (playerState.Flags.left)
{
Godot::print("\t\t Jump left");
p.velocity.x = -speed;
sprite_player_ptr->play("Jump Up");
sprite_player_ptr->set_flip_h(true);
}
else if (playerState.Flags.right)
{
Godot::print("\t\t Jump right");
p.velocity.x = +speed;
sprite_player_ptr->play("Jump Up");
sprite_player_ptr->set_flip_h(false);
}
}
}
//Fonction des animations possibles si le joueur se trouve au sol
//avec les animations qui se trouve dans le fichier "HeroKnight.tres"
//en fonction dss flags des booleens isinblockinganiamtion pour éviter toute loop
void GestionPlayer::PlayerLogic_OnGround(float dt)
{
Godot::print("\t OnGround");
p.velocity.y = 0.0f;
if (playerState.Flags.attack)
{
sprite_player_ptr->play("attack");
playerState.Flags.isInBlockingAnimation = true;
playerState.Flags.attack = false;
}
else if (playerState.Flags.bigattack)
{
sprite_player_ptr->play("attack2");
p.velocity.y = -5.0f;
playerState.Flags.isInBlockingAnimation = true;
playerState.Flags.bigattack = false;
}
else if (playerState.Flags.dash)
{
sprite_player_ptr->play("dash");
p.velocity.x =+ 1000.0f;
playerState.Flags.isInBlockingAnimation = true;
playerState.Flags.dash = false;
}
else if (playerState.Flags.block)
{
sprite_player_ptr->play("block");
playerState.Flags.isInBlockingAnimation = true;
playerState.Flags.block = false;
}
else if (playerState.Flags.left)
{
p.velocity.x = -speed;
sprite_player_ptr->play("Walk");
sprite_player_ptr->set_flip_h(true);
}
else if (playerState.Flags.right)
{
p.velocity.x = +speed;
sprite_player_ptr->play("Walk");
sprite_player_ptr->set_flip_h(false);
}
else if (pv <= 0)
{
sprite_player_ptr->play("mort");
}
else
{
sprite_player_ptr->play("Idle");
}
}
//Fonction qui gere les animations si le joueur est en chute libre, dans le bon sens en fonction de la velocité
void GestionPlayer::PlayerLogic_FreeFall(float dt)
{
Godot::print("\t FreeFall");
if (playerState.Flags.left)
{
Godot::print("\t\t tFreeFall left");
p.velocity.x = -speed;
sprite_player_ptr->play("jump Down");
sprite_player_ptr->set_flip_h(true);
}
else if (playerState.Flags.right)
{
Godot::print("\t\t tFreeFall right");
p.velocity.x = +speed;
sprite_player_ptr->play("jump Down");
sprite_player_ptr->set_flip_h(false);
}
p.velocity.y += gravity * dt;
}
//Fonction qui inisalise la position du joueur
void GestionPlayer::setPosition(float x, float y)
{
Transform2D t;
Vector2 pos;
Size2 s;
//setup de la size
s.x = 1.0f;
s.y = 1.0f;
pos.x = x;
pos.y = y;
t.set_origin(pos);
t.scale(s);
set_transform(t);
//init Velocity
p.velocity = Vector2(0.0f, 0.0f);
}