Pages: [1]   Bas de page
Imprimer
Auteur Fil de discussion: détecter la direction/angle d'un personnage  (Lu 467 fois)
0 Membres et 1 Invité sur ce fil de discussion.
blendman Hors ligne
Newbie
*
Messages: 14


Voir le profil
« 28 Mai 2012, 10:52:29 »

Coucou

Je me remets un peu au dev de mon jeu version Xbox (Arkeos).

Savez-vous comment on peut détecter la direction d'un personnage (windows/xbox) ?
Sous windows j'utilise le déplacement avec les flèches du clavier et sous xbox avec le Thumbstick.

En gros, j'utilise ce genre de code :

Code: (csharp)
player1._position.Y -= (GamePad.GetState(playerpad1).ThumbSticks.Left.Y) * 4;

Savez si on peut récupérer la "direction" de déplacement  ou l'angle du personnage en focntion de thumbstick ?

ça me serait utile pour 2 choses :
- lorsque je lance un sort de magie, le sort pourrait se déplacer en fonction de cette direction
- lorsque je déplace mon personnage, je pourrais changer le sprite en fonction de cette direction.

Si vous avez des informations là-dessus, n'hésitez pas Wink.

Merci Cheesy
« Dernière édition: 28 Mai 2012, 14:47:11 par blendman » Journalisée

t4ils Hors ligne
Branleur
Elite Member
**
Messages: 961


Voir le profil WWW
« Réponse #1 : 29 Mai 2012, 07:48:56 »

Hello Smiley

Déjà pour la direction du sort, tu peux reprendre les valeurs X et Y du thumbstick. Il partira dans la direction du thumbstick forcément.
Donc sort.vx = thumbstick.left.x et sort.vy = thumbstick.left.y

Ensuite pour l'angle :
Le stick est de base en position (0, 0).
Quand tu le bouges, ça change les coordonnées X et Y. Donc tu peux par exemple l'avoir en (0.8, 0.12).

A partir de la, c'est simple : il suffit de trouver l'angle décrit par le triangle rectangle passant par (0, 0) et (0.8, 0.12)
C'est donc un calcul à base de côté opposée, côté adjacent, hypoténuse, sinus, cosinus ... La trigonométrie grin

Exemple de fonction qui renvoie l'angle entre 2 points (par rapport à l'axe des abscisse d'un repère orthonormal) :

Citation
public double getAngle(float x1, float y1, float x2, float y2)
   {
      double radian = Math.Atan2 (y2 - y1 , x2 - x1);
      double angle = radians * (180/Math.PI);
      return angle;
   }

Pour avoir l'angle de ton thumbstick, tu fais donc :
Citation
double thumbstickAngle = getAngle(0, 0, GamePad.GetState(playerpad1).ThumbSticks.Left.X, GamePad.GetState(playerpad1).ThumbSticks.Left.Y);

Voilou Smiley

Edit : J'ai cherché un peu le net, voir ce que les gens font. Tu as plus "simple" pour le coup, vu qu'on part toujours de 0, 0 ...
Citation
// Angle en radians
float radAngle = (float) Math.Atan2(GamePad.GetState(playerpad1).ThumbSticks.Left.Y, GamePad.GetState(playerpad1).ThumbSticks.Left.X);

//Angle en degrés
float degAngle = radAngle * (180/Math.PI);

Tu peux utiliser la seconde "méthode" pour trouver l'angle du stick rapidos, mais la première méthode te permettra de calculer des angles entre 2 points n'importe ou à l'écran Wink

Revoilou Smiley
« Dernière édition: 29 Mai 2012, 07:56:05 par t4ils » Journalisée

Le codage amateur ? Parce que je le veux bien.
blendman Hors ligne
Newbie
*
Messages: 14


Voir le profil
« Réponse #2 : 29 Mai 2012, 09:13:01 »

salut

Merci beaucoup pour tes explications, je me suis servi de ta 1-re méthode (getangle()) et ça marche très bien pour récupérer l'angle.

Mais j'ai gardé en radian, sinon, je n'avais que les angles multiples de 45°.


Ensuite, pour faire bouger mes sorts, je fais la chose suivante :
Code:
_position.X += Convert.ToInt16(Math.Cos(_angle) * projectileMoveSpeed;
 _position.Y += Convert.ToInt16(Math.Sin(_angle) * projectileMoveSpeed;

Je mets ce code dans une méthode pour updater chaque sort et ça marche Smiley.
J'ai tous les angles.

Donc, un grand merci à toi !


Journalisée

PypeBros Hors ligne
Hero Member
*****
Messages: 707


Voir le profil WWW
Posez-vous les bonnes questions

« Réponse #3 : 29 Mai 2012, 10:49:25 »

Ensuite, pour faire bouger mes sorts, je fais la chose suivante :
Code:
_position.X += Convert.ToInt16(Math.Cos(_angle) * projectileMoveSpeed;
 _position.Y += Convert.ToInt16(Math.Sin(_angle) * projectileMoveSpeed;

Allons, allons ... un peu de pitié pour ces transistors de calcul intensifs qui ne vous ont rien fait comme ça! calculer un sinus un cosinus ou une tangente, ça reste quelque chose de sophistiqué et inutilement complexe pour être effectué à chaque étape.

Tu peux sans problème calculer vitesse.x et vitesse.y une seule fois au niveau du lancement du sort et avoir simplement
Code:
_position.x += vitesse.x
_position.y += vitesse.y

Puisque tu as déjà dans les infos de ton stick une paire de coordonnées (stick.x, stick.y) telles que stick.x = stick.radius * stick.alpha, tout ce qu'il te faut, c'est normaliser stick.x et stick.y de sorte que tu puisse choisir la vitesse de ton sort indépendamment du "radius" (distance par rapport à la position 0,0) de ton stick.

Code:
radius = sqrt(stick.x*stick.x + stick.y*stick.y)
vitesse.x = (vitesse_du_sort * stick.x) / radius
vitesse.y = (vitesse_du_sort * stick.y) / radius


Et si même tu avais voulu avoir un sort qui tourne pour suivre sa cible (donc _angle qui évolue au fil du temps), n'oublie pas les matrices de rotations dérivées de nos bonnes vieille formules de trigono:
Code:
// sin(a+b) = sin a cos b + cos a sin b  ... ou qqch comme ça ;)
vitesse.y = vitesse.y * cos_petite_deviation_a_gauche + vitesse.x * sin_petite_deviation_a_gauche

quelques multiplications, quelques additions, et des sin/cos calculés sur des constantes. C'est tout ce dont il y a vraiment besoin ^_^

EDIT: oh, bien sûr, il faut éviter de diviser par radius=0, mais si radius<RADIUS_MINImUM, il vaut mieux réutiliser les dernières valeurs de direction du stick que d'utiliser à nouveau stick.x et stick.y, parce que proche du centre, l'angle devient juste une lecture (bruitée Smiley de la nervosité du joueur Tongue
« Dernière édition: 29 Mai 2012, 10:51:36 par PypeBros » Journalisée

blendman Hors ligne
Newbie
*
Messages: 14


Voir le profil
« Réponse #4 : 29 Mai 2012, 17:46:12 »

salut

Merci beaucoup pour ta réponse Smiley.

J'ai effectivement calculé 1 seule fois (à l'initialisation du sort) la direction et ensuite je ne fais que l'ajouter à la position et ça marche très bien, donc si ça économise du cpu, tant mieux Smiley.

Je fais donc simplement ceci :
Code:
direction .X += Convert.ToInt16(Math.Cos(_angle);
direction .Y += Convert.ToInt16(Math.Sin(_angle);

Évidemment, je normalise tout ceci comme tu me l'as suggéré (par rapport à la distance du stick, car j'ai constaté que sinon, la vitesse était effectivement proportionnelle à la distance avec le stick.

Mais j'utilise normalize(), car je pense que ça fait la même chose que ton système (me trompe-je ?)
Code:
direction .Normalize();

Puis j'update en faisant simplement ça (dans une autre méthode update()):
Code:
_position.x += direction .x;
_position.y += direction .y;

Voilà.

Encore merci Wink.
Journalisée

Pages: [1]   Haut de page
Imprimer

Aller à: