reglage probleme animations + commentaire

This commit is contained in:
Estrela Allan p1923381 2020-05-03 15:35:51 +02:00
parent c85ccf4f8f
commit d909ecd889
6 changed files with 206 additions and 155 deletions

View File

@ -75,34 +75,29 @@
[resource] [resource]
animations = [ { animations = [ {
"frames": [ ExtResource( 26 ), ExtResource( 28 ), ExtResource( 27 ), ExtResource( 29 ), ExtResource( 25 ), ExtResource( 34 ), ExtResource( 72 ), ExtResource( 71 ) ],
"loop": false,
"name": "shield",
"speed": 5.0
}, {
"frames": [ ExtResource( 36 ), ExtResource( 35 ), ExtResource( 47 ), ExtResource( 54 ) ],
"loop": false,
"name": "degat",
"speed": 5.0
}, {
"frames": [ ExtResource( 33 ), ExtResource( 30 ), ExtResource( 44 ), ExtResource( 56 ), ExtResource( 57 ), ExtResource( 37 ), ExtResource( 31 ), ExtResource( 32 ), ExtResource( 45 ) ],
"loop": false,
"name": "mort",
"speed": 5.0
}, {
"frames": [ ExtResource( 11 ), ExtResource( 7 ), ExtResource( 8 ), ExtResource( 4 ), ExtResource( 14 ), ExtResource( 5 ), ExtResource( 1 ) ], "frames": [ ExtResource( 11 ), ExtResource( 7 ), ExtResource( 8 ), ExtResource( 4 ), ExtResource( 14 ), ExtResource( 5 ), ExtResource( 1 ) ],
"loop": true, "loop": true,
"name": "Idle", "name": "Idle",
"speed": 4.0 "speed": 4.0
}, { }, {
"frames": [ ExtResource( 36 ), ExtResource( 35 ), ExtResource( 47 ), ExtResource( 54 ) ], "frames": [ ExtResource( 58 ), ExtResource( 67 ), ExtResource( 59 ), ExtResource( 60 ) ],
"loop": true, "loop": false,
"name": "degat", "name": "block",
"speed": 5.0
}, {
"frames": [ ExtResource( 33 ), ExtResource( 30 ), ExtResource( 44 ), ExtResource( 56 ), ExtResource( 57 ), ExtResource( 37 ), ExtResource( 31 ), ExtResource( 32 ), ExtResource( 45 ) ],
"loop": true,
"name": "mort",
"speed": 5.0
}, {
"frames": [ ExtResource( 18 ), ExtResource( 22 ), ExtResource( 23 ) ],
"loop": true,
"name": "Jump Up",
"speed": 5.0
}, {
"frames": [ ExtResource( 53 ), ExtResource( 40 ), ExtResource( 49 ), ExtResource( 42 ), ExtResource( 51 ), ExtResource( 52 ), ExtResource( 39 ), ExtResource( 43 ) ],
"loop": true,
"name": "attack2",
"speed": 5.0
}, {
"frames": [ ExtResource( 26 ), ExtResource( 28 ), ExtResource( 27 ), ExtResource( 29 ), ExtResource( 25 ), ExtResource( 34 ), ExtResource( 72 ), ExtResource( 71 ) ],
"loop": true,
"name": "shield",
"speed": 5.0 "speed": 5.0
}, { }, {
"frames": [ ExtResource( 9 ), ExtResource( 2 ), ExtResource( 12 ), ExtResource( 15 ), ExtResource( 13 ), ExtResource( 10 ), ExtResource( 6 ), ExtResource( 3 ), ExtResource( 16 ), ExtResource( 17 ) ], "frames": [ ExtResource( 9 ), ExtResource( 2 ), ExtResource( 12 ), ExtResource( 15 ), ExtResource( 13 ), ExtResource( 10 ), ExtResource( 6 ), ExtResource( 3 ), ExtResource( 16 ), ExtResource( 17 ) ],
@ -110,23 +105,28 @@ animations = [ {
"name": "Walk", "name": "Walk",
"speed": 5.0 "speed": 5.0
}, { }, {
"frames": [ ExtResource( 50 ), ExtResource( 50 ), ExtResource( 48 ), ExtResource( 55 ), ExtResource( 46 ), ExtResource( 41 ), ExtResource( 38 ) ],
"loop": false,
"name": "attack",
"speed": 10.0
}, {
"frames": [ ExtResource( 18 ), ExtResource( 22 ), ExtResource( 23 ) ],
"loop": true,
"name": "Jump Up",
"speed": 5.0
}, {
"frames": [ ExtResource( 53 ), ExtResource( 40 ), ExtResource( 49 ), ExtResource( 42 ), ExtResource( 51 ), ExtResource( 52 ), ExtResource( 39 ), ExtResource( 43 ) ],
"loop": false,
"name": "attack2",
"speed": 6.0
}, {
"frames": [ ExtResource( 68 ), ExtResource( 64 ), ExtResource( 66 ), ExtResource( 69 ), ExtResource( 62 ), ExtResource( 61 ), ExtResource( 65 ), ExtResource( 70 ), ExtResource( 63 ) ],
"loop": false,
"name": "dash",
"speed": 5.0
}, {
"frames": [ ExtResource( 20 ), ExtResource( 21 ), ExtResource( 19 ), ExtResource( 24 ) ], "frames": [ ExtResource( 20 ), ExtResource( 21 ), ExtResource( 19 ), ExtResource( 24 ) ],
"loop": true, "loop": true,
"name": "jump Down", "name": "jump Down",
"speed": 5.0 "speed": 5.0
}, {
"frames": [ ExtResource( 50 ), ExtResource( 50 ), ExtResource( 48 ), ExtResource( 55 ), ExtResource( 46 ), ExtResource( 41 ), ExtResource( 38 ) ],
"loop": true,
"name": "attack",
"speed": 5.0
}, {
"frames": [ ExtResource( 68 ), ExtResource( 64 ), ExtResource( 66 ), ExtResource( 69 ), ExtResource( 62 ), ExtResource( 61 ), ExtResource( 65 ), ExtResource( 70 ), ExtResource( 63 ) ],
"loop": true,
"name": "dash",
"speed": 5.0
}, {
"frames": [ ExtResource( 58 ), ExtResource( 67 ), ExtResource( 59 ), ExtResource( 60 ) ],
"loop": true,
"name": "block",
"speed": 5.0
} ] } ]

View File

@ -72,14 +72,14 @@ void GestionJeu::create_scene()
auto mob = (MobsCorpACorpIA*) m; auto mob = (MobsCorpACorpIA*) m;
Godot::print("Add child mob"); Godot::print("Add child mob");
add_child(m); add_child(m);
m->setPosition(15, 150); m->setPosition(15.0f, 150.0f);
} }
} }
void GestionJeu::setup_scene() void GestionJeu::setup_scene()
{ {
gPlayer->setPosition(15, 150); gPlayer->setPosition(15.0f, 150.0f);
gTerrain->GenerationCarte(); gTerrain->GenerationCarte();

View File

@ -16,22 +16,26 @@ GestionPlayer::GestionPlayer()
void GestionPlayer::_register_methods() void GestionPlayer::_register_methods()
{ {
Godot::print("register Player..."); Godot::print("register Player...");
register_method("_physics_process", &GestionPlayer::_physics_process);
register_method("_process", &GestionPlayer::_process); register_method("_process", &GestionPlayer::_process);
register_method("_init", &GestionPlayer::_init); register_method("_init", &GestionPlayer::_init);
register_method("_ready", &GestionPlayer::_ready); register_method("_ready", &GestionPlayer::_ready);
Godot::print("register Player OK!"); 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 void GestionPlayer::_process(float dt) // dt = deltaTime
{ {
playerState.right = false; PlayerLogic_AutoReset();
playerState.left = false;
traitementInput(); traitementInput();
PlayerLogic(dt); PlayerLogic(dt);
p.velocity = move_and_slide(p.velocity);
} }
void GestionPlayer::_init() void GestionPlayer::_init()
@ -42,6 +46,7 @@ void GestionPlayer::_init()
void GestionPlayer::_ready() void GestionPlayer::_ready()
{ {
setupPlayer(); setupPlayer();
playerState.Reset();
} }
void GestionPlayer::createPlayer() void GestionPlayer::createPlayer()
@ -49,6 +54,8 @@ void GestionPlayer::createPlayer()
add_child(sprite_player_ptr); 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() void GestionPlayer::setupPlayer()
{ {
//Chargement de la texture //Chargement de la texture
@ -70,6 +77,9 @@ void GestionPlayer::setupPlayer()
} }
//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() void GestionPlayer::traitementInput()
{ {
// manage Inputs // manage Inputs
@ -78,31 +88,70 @@ void GestionPlayer::traitementInput()
// move in X directions // move in X directions
p.velocity.x = 0.0f; // rest x, keyboard action will change this p.velocity.x = 0.0f; // rest x, keyboard action will change this
if (i->is_action_pressed("ui_left")) if (i->is_action_pressed("ui_left"))
playerState.left = true; playerState.Flags.left = true;
if (i->is_action_pressed("ui_right")) if (i->is_action_pressed("ui_right"))
playerState.right = true; playerState.Flags.right = true;
if (i->is_action_pressed("dash")) if (i->is_action_pressed("dash"))
playerState.dash = true; playerState.Flags.dash = true;
if (i->is_action_pressed("attack")) if (i->is_action_pressed("attack"))
playerState.attack = true; playerState.Flags.attack = true;
if (i->is_action_pressed("attack2")) if (i->is_action_pressed("attack2"))
playerState.bigattack = true; playerState.Flags.bigattack = true;
if (i->is_action_pressed("block")) if (i->is_action_pressed("block"))
playerState.block = true; playerState.Flags.block = true;
// move in Y directions // move in Y directions
if (i->is_action_pressed("ui_select")) if (i->is_action_pressed("ui_select"))
playerState.jump = true; 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) void GestionPlayer::PlayerLogic(float dt)
{ {
if (playerState.jump) 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 // attack en l'air
PlayerLogic_Jump(dt); PlayerLogic_Jump(dt);
@ -115,15 +164,26 @@ void GestionPlayer::PlayerLogic(float dt)
PlayerLogic_OnGround(dt); PlayerLogic_OnGround(dt);
} }
else else
{ // freefall { // we fall from the ground
// attack en l'air playerState.Flags.freefall = true;
PlayerLogic_FreeFall(dt);
} }
} }
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) void GestionPlayer::PlayerLogic_Jump(float dt)
{ {
Godot::print("\t Jump");
if (on_ground) if (on_ground)
{ {
p.velocity.y = power_jump; p.velocity.y = power_jump;
@ -134,19 +194,21 @@ void GestionPlayer::PlayerLogic_Jump(float dt)
} }
if (p.velocity.y > 0.0f) if (p.velocity.y > 0.0f)
{ {
playerState.jump = false; playerState.Flags.jump = false;
playerState.freefall = true; playerState.Flags.freefall = true;
} }
else else
{ {
if (playerState.left) if (playerState.Flags.left)
{ {
Godot::print("\t\t Jump left");
p.velocity.x = -speed; p.velocity.x = -speed;
sprite_player_ptr->play("Jump Up"); sprite_player_ptr->play("Jump Up");
sprite_player_ptr->set_flip_h(true); sprite_player_ptr->set_flip_h(true);
} }
else if (playerState.right) else if (playerState.Flags.right)
{ {
Godot::print("\t\t Jump right");
p.velocity.x = +speed; p.velocity.x = +speed;
sprite_player_ptr->play("Jump Up"); sprite_player_ptr->play("Jump Up");
sprite_player_ptr->set_flip_h(false); sprite_player_ptr->set_flip_h(false);
@ -154,40 +216,47 @@ void GestionPlayer::PlayerLogic_Jump(float dt)
} }
} }
//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) void GestionPlayer::PlayerLogic_OnGround(float dt)
{ {
Godot::print("\t OnGround");
p.velocity.y = 0.0f; p.velocity.y = 0.0f;
if (playerState.attack) if (playerState.Flags.attack)
{ {
sprite_player_ptr->play("attack"); sprite_player_ptr->play("attack");
playerState.Flags.isInBlockingAnimation = true;
playerState.Flags.attack = false;
} }
else if (playerState.bigattack) else if (playerState.Flags.bigattack)
{ {
sprite_player_ptr->play("attack2"); sprite_player_ptr->play("attack2");
p.velocity.y = -5.0f;
playerState.Flags.isInBlockingAnimation = true;
playerState.Flags.bigattack = false;
} }
else if (playerState.dash) else if (playerState.Flags.dash)
{ {
sprite_player_ptr->play("dash"); sprite_player_ptr->play("dash");
p.velocity.x =+ 50; p.velocity.x =+ 1000.0f;
playerState.Flags.isInBlockingAnimation = true;
playerState.Flags.dash = false;
} }
else if (playerState.block) else if (playerState.Flags.block)
{ {
sprite_player_ptr->play("block");
sprite_player_ptr->play("shield"); playerState.Flags.isInBlockingAnimation = true;
playerState.Flags.block = false;
} }
else if (playerState.left) else if (playerState.Flags.left)
{ {
p.velocity.x = -speed; p.velocity.x = -speed;
sprite_player_ptr->play("Walk"); sprite_player_ptr->play("Walk");
sprite_player_ptr->set_flip_h(true); sprite_player_ptr->set_flip_h(true);
} }
else if (playerState.right) else if (playerState.Flags.right)
{ {
p.velocity.x = +speed; p.velocity.x = +speed;
sprite_player_ptr->play("Walk"); sprite_player_ptr->play("Walk");
@ -203,17 +272,21 @@ void GestionPlayer::PlayerLogic_OnGround(float dt)
} }
} }
//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) void GestionPlayer::PlayerLogic_FreeFall(float dt)
{ {
p.velocity.x = +speed; Godot::print("\t FreeFall");
if (playerState.left) if (playerState.Flags.left)
{ {
Godot::print("\t\t tFreeFall left");
p.velocity.x = -speed; p.velocity.x = -speed;
sprite_player_ptr->play("jump Down"); sprite_player_ptr->play("jump Down");
sprite_player_ptr->set_flip_h(true); sprite_player_ptr->set_flip_h(true);
} }
else if (playerState.right) else if (playerState.Flags.right)
{ {
Godot::print("\t\t tFreeFall right");
p.velocity.x = +speed; p.velocity.x = +speed;
sprite_player_ptr->play("jump Down"); sprite_player_ptr->play("jump Down");
sprite_player_ptr->set_flip_h(false); sprite_player_ptr->set_flip_h(false);
@ -221,7 +294,9 @@ void GestionPlayer::PlayerLogic_FreeFall(float dt)
p.velocity.y += gravity * dt; p.velocity.y += gravity * dt;
} }
void GestionPlayer::setPosition(int x, int y)
//Fonction qui inisalise la position du joueur
void GestionPlayer::setPosition(float x, float y)
{ {
Transform2D t; Transform2D t;
Vector2 pos; Vector2 pos;
@ -240,51 +315,3 @@ void GestionPlayer::setPosition(int x, int y)
//init Velocity //init Velocity
p.velocity = Vector2(0.0f, 0.0f); p.velocity = Vector2(0.0f, 0.0f);
} }
/*
void GestionPlayer::droit()
{
Godot::print("Deplacement a droite");
p.velocity.x = speed;
}
void GestionPlayer::gauche()
{
Godot::print("Deplacement a gauche");
p.velocity.x = -speed;
}
void GestionPlayer::bas()
{
}
void GestionPlayer::saut()
{
}
void GestionPlayer::idle()
{
p.velocity.x = 0.0;
}
void GestionPlayer::dash()
{
p.velocity.x =+1000;
sprite_player_ptr->play("dash");
}
void GestionPlayer::attack()
{
sprite_player_ptr->play("attack");
}
void GestionPlayer::block()
{
sprite_player_ptr->play("block");
}
void GestionPlayer::bigattack()
{
sprite_player_ptr->play("attack2");
}
*/

View File

@ -24,6 +24,7 @@ public:
GestionPlayer(); GestionPlayer();
void static _register_methods(); void static _register_methods();
void _physics_process(float delta);
void _process(float delta); void _process(float delta);
void _init(); void _init();
void _ready(); void _ready();
@ -35,22 +36,13 @@ public:
Player p; Player p;
public: public:
void traitementInput();
void setPosition(int x, int y); void setPosition(float x, float y);
private: private:
//void droit(); void traitementInput();
//void gauche();
//void bas();
//void saut();
//void dash();
//void idle();
//void attack();
//void bigattack();
//void block();
void PlayerLogic_AutoReset();
void PlayerLogic(float dt); void PlayerLogic(float dt);
void PlayerLogic_OnGround(float dt); void PlayerLogic_OnGround(float dt);
void PlayerLogic_Jump(float dt); void PlayerLogic_Jump(float dt);
@ -68,19 +60,34 @@ public:
bool on_right_wall = false; bool on_right_wall = false;
struct S_PlayerState class S_PlayerState
{ {
bool right; public:
bool left; union
bool jump; {
bool dash; struct
bool idle; {
bool attack; unsigned int right : 1;
bool bigattack; unsigned int left : 1;
bool block; unsigned int jump : 1;
unsigned int dash : 1;
unsigned int idle : 1;
unsigned int attack : 1;
unsigned int bigattack : 1;
unsigned int block : 1;
bool freefall; unsigned int freefall : 1;
unsigned int isInBlockingAnimation : 1;
};
unsigned int AllFlags; // to reset all bits at once
} Flags;
void Reset()
{
Flags.AllFlags = 0;
}
S_PlayerState() { Reset(); }
} playerState; } playerState;
private: private:

View File

@ -6,7 +6,7 @@
#include <Texture.hpp> #include <Texture.hpp>
#include "MobsCorpACorp.h" #include "MobsCorpACorp.h"
#include "GestionPlayer.h" #include "GestionPlayer.h"
//constructeur
MobsCorpACorpIA::MobsCorpACorpIA() MobsCorpACorpIA::MobsCorpACorpIA()
{ {
sprite_MobsCorpACorp_ptr = AnimatedSprite::_new(); sprite_MobsCorpACorp_ptr = AnimatedSprite::_new();
@ -29,7 +29,7 @@ void MobsCorpACorpIA::_register_methods()
Godot::print("register Mobs OK!"); Godot::print("register Mobs OK!");
} }
//fonction _pgysics_process meilleur rafraichissement de 60 fps comparé à 30 pour la fonction _process meilleur pour les mouvement plus fluide du mob
void MobsCorpACorpIA::_physics_process(float dt) void MobsCorpACorpIA::_physics_process(float dt)
{ {
mouvement(dt); mouvement(dt);
@ -47,6 +47,8 @@ void MobsCorpACorpIA::_init()
createMobsCorpACorp(); createMobsCorpACorp();
} }
//fonction qui met en place et creer le mob
void MobsCorpACorpIA::createMobsCorpACorp() void MobsCorpACorpIA::createMobsCorpACorp()
{ {
add_child(sprite_MobsCorpACorp_ptr); add_child(sprite_MobsCorpACorp_ptr);
@ -60,6 +62,8 @@ void MobsCorpACorpIA::_ready()
} }
//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 MobsCorpACorpIA::setupMobsCorpACorp() void MobsCorpACorpIA::setupMobsCorpACorp()
{ {
@ -86,8 +90,8 @@ void MobsCorpACorpIA::setupMobsCorpACorp()
} }
//fonction qui set la position dans l'écrans du mob
void MobsCorpACorpIA::setPosition(int x, int y) void MobsCorpACorpIA::setPosition(float x, float y)
{ {
Transform2D t; Transform2D t;
Vector2 pos; Vector2 pos;
@ -104,6 +108,8 @@ void MobsCorpACorpIA::setPosition(int x, int y)
set_transform(t); set_transform(t);
} }
//fonction office de mini IA qui va déplacer les mobs en fonction de la positon du joueur TargetPosition
void MobsCorpACorpIA::mouvement(float dt) void MobsCorpACorpIA::mouvement(float dt)
{ {
@ -143,6 +149,9 @@ void MobsCorpACorpIA::mouvement(float dt)
} }
//Fonction qui gere les animations en fonction des mouvements et de la direction du joueur
void MobsCorpACorpIA::animation() void MobsCorpACorpIA::animation()
{ {
@ -168,23 +177,31 @@ void MobsCorpACorpIA::animation()
} }
//Deplacement mob a droite
void MobsCorpACorpIA::droit() void MobsCorpACorpIA::droit()
{ {
Godot::print("Deplacement mob a droite"); //Godot::print("Deplacement mob a droite");
m.velocity.x = speed; m.velocity.x = speed;
} }
//Deplacement mob a gauche
void MobsCorpACorpIA::gauche() void MobsCorpACorpIA::gauche()
{ {
Godot::print("Deplacement mob a gauche"); //Godot::print("Deplacement mob a gauche");
m.velocity.x = -speed; m.velocity.x = -speed;
} }
//Deplacement mob a bas
void MobsCorpACorpIA::bas() void MobsCorpACorpIA::bas()
{ {
m.velocity.y = -power_jump; m.velocity.y = -power_jump;
} }
//Deplacement mob a saut
void MobsCorpACorpIA::saut() void MobsCorpACorpIA::saut()
{ {

View File

@ -71,5 +71,5 @@ public:
Vector2 TargetPosition; Vector2 TargetPosition;
public: public:
void UpdateTargetPosition(Vector2 _TargetPosition) { TargetPosition = _TargetPosition; } void UpdateTargetPosition(Vector2 _TargetPosition) { TargetPosition = _TargetPosition; }
void setPosition(int x, int y); void setPosition(float x, float y);
}; };