Dans Déployer un tank dans une zone de guerre isométrique, vous avez appris à faire pivoter un objet pour faire face au pointeur et à vous déplacer au clic. Dans ce petit conseil, nous allons jeter un regard général sur ses calculs: la trigonométrie.
Ceci est le résultat final de mon précédent tutoriel. Il utilise les principes de trigonométrie que nous couvrirons dans cette astuce:
Déplacez la souris pour faire viser la tourelle et cliquez n'importe où pour que le char se rende à cet endroit..
Tous les programmeurs, en particulier les programmeurs de jeux, sont confrontés à la nécessité de déplacer les objets à l’écran tôt ou tard. C'est une tâche simple si vous devez déplacer un objet dans une direction, par exemple le long de l'axe des x ou des y. Mais supposons que vous vouliez faire suivre un pointeur de la souris avec un objet, où que vous vous déplaciez, ou créer un jeu de course dans lequel vous contrôliez l’accélération d’une voiture en appuyant sur la touche fléchée vers le haut et en utilisant les flèches gauche et droite pour vous diriger..
Supposons que vous appuyez une fois sur la touche fléchée droite et que cela ajoute 10 degrés à la propriété de rotation de votre voiture, mais vous souhaitez tout de même que la voiture avance (accélère) lorsque vous appuyez sur une touche fléchée haut, même si la voiture est tournée vers le bas de l’écran ou un côté gauche ou droit, etc. et vous ne voulez pas qu’il glisse sur le côté. Alors, comment feriez-vous cela? Voilà où un peu de trigonométrie aide!
Pour ceux qui sont bons en maths, ce ne sera pas un problème, mais beaucoup de gens ne le comprennent pas du tout, voire en ont peur. Je vais essayer de le décomposer aussi clairement que possible dans cette astuce.
Au début, souvenons-nous du système de coordonnées cartésien. Cela vous semble compliqué? Si oui, regardez juste l'image ci-dessous et je suis sûr qu'elle vous sera familière:
Il a les axes X et Y; vous pouvez clairement voir où X et Y sont positifs et négatifs. En ce qui concerne les coordonnées en Flash, la situation est légèrement différente. Flash a aussi son système de coordonnées mais il ressemble au système cartésien à l’envers:
Il a également les axes X et Y et le point d'origine, la seule différence étant que l'axe des Y est positif au dessous de l'axe des x.
Chaque symbole créé dans Flash possède son propre système de coordonnées intégré. Si vous créez un nouveau symbole, qu'il s'agisse d'un clip ou d'un bouton, il est possible qu'une propriété "point d'enregistrement" apparaisse dans la boîte de dialogue de création de symboles. Qu'Est-ce que c'est? Le point d'enregistrement est le point d'origine d'un symbole. Le point autour duquel l'objet tournera si vous modifiez sa propriété rotation.
Remarque: le point d'origine de l'instance d'étape se trouve dans son coin supérieur gauche. Cela signifie que tous les points de la scène ont des coordonnées X et Y positives.
Dans ce petit conseil, nous allons examiner les trois fonctions trigonométriques les plus couramment utilisées dans Flash; Sine, Cosinus et Atan2. Certaines personnes pourraient se demander comment utiliser ces fonctions dans Flash. Eh bien, regardons quelques exemples pratiques et comprenons pourquoi nous en avons besoin et comment ils peuvent nous rendre la vie plus facile..
Calculons l'angle entre deux points. Créez un nouveau fichier Flash (ActionScript 3.0). Sélectionnez la première image du scénario et appuyez sur F9 pour ouvrir un panneau Actions..
À ce stade, faisons quelque chose de simple. Il suffit de taper ceci dans le panneau Actions:
stage.addEventListener (MouseEvent.CLICK, CalculateAngle) fonction CalculateAngle (e: MouseEvent): void trace ("stage X" + e.stageX); trace ("étape Y" + e.stageY)
Cela nous donnera la position du pointeur de la souris chaque fois que nous cliquons sur la scène. Pas vraiment fascinant, est-ce?
Ok, supposons maintenant que vous vouliez "dire" à un objet les coordonnées du pointeur de votre souris par rapport à cet objet, puis lui montrer la direction à suivre pour atteindre la position du pointeur.
Fermez le panneau Actions et accédez à Insertion> Nouveau symbole ou appuyez simplement sur Ctrl + F8.
Donnez-lui un nom (ou laissez un nom par défaut) et appuyez sur OK. Le petit réticule au centre de l'écran est le point d'alignement du symbole ou son point d'origine. Ce seront les positions X et Y de l'objet. Maintenant, prenez l'outil Ovale (touche O) et tracez un cercle (avec la touche Maj enfoncée) n'importe où sur l'écran.
Cliquez sur le cercle pour le sélectionner et accédez à son panneau Propriétés> Position et taille. Pour W (largeur), entrez 20, idem pour H (hauteur) et pour X et Y, entrez (-10). Cela fera le cercle 20x20 px et le centrera exactement sur le point d’enregistrement. Quittez maintenant le mode d’édition des symboles (cliquez sur la scène 1 ci-dessus), saisissez ce symbole dans votre bibliothèque et faites-le simplement glisser sur la scène (n’importe où, sa position sera déterminée dynamiquement ultérieurement). Une fois que votre objet est sur la scène, donnez-lui un nom d'occurrence mCircle
.
Maintenant, nous voulons calculer la direction entre la position Y et X de notre cercle et la position Y et X du pointeur de la souris. La ligne rouge dans l'image ci-dessous est la direction que nous devons connaître. On peut le trouver en utilisant un standard Math.atan2 ()
une fonction.
Faisons-le maintenant. Supprimez les instructions "trace" du code et créez une nouvelle variable à la place. Puis tracez cette variable pour voir ce que vous obtenez:
stage.addEventListener (MouseEvent.CLICK, CalculateAngle); var myAtan2: Number; function CalculateAngle (e: MouseEvent): void myAtan2 = Math.atan2 (e.stageY - mCircle.y, e.stageX - mCircle.x); trace (myAtan2);
Notez que e.stageY - mCircle.y
est le verticale distance de la souris au cercle, et e.stageX - mCircle.x
est le distance horizontale.
Vous obtiendrez ces types de nombres dans le panneau de sortie:
-2.419017353128333 3.0118660246925346 2.5704959452340326 1.6726588917423932 1.0238847495551058 0.21368467849101092
Ce sont les angles relatifs (entre la ligne d'axe X et la ligne rouge) en radians. Pourquoi pas des diplômes? Eh bien, Flash utilise les radians pour calculer le sinus et le cosinus, mais si vous voulez savoir quels sont ces angles en degrés, vous pouvez toujours multiplier "myAtan2" par 180 et le diviser par Math.PI
. Comme ça:
trace (myAtan2 * 180 / Math.PI) // vous donne l'angle en degrés;
Éditeur: En tant que ressource supplémentaire, voici un excellent ensemble de fonctions pour la conversion de degré / radian. Il est stocké sous forme d'extrait sur snipplr.com, le dernier membre du réseau d'Envato.!
Comme nous connaissons l'angle entre deux points, nous pouvons maintenant calculer le nombre de pixels que nous devons ajouter aux propriétés X et Y du cercle à chaque image jusqu'à ce qu'il atteigne le point de clic. Examinons ce que nous devons savoir ici:
La ligne bleue est le cosinus de l'angle et l'orange est le sinus de l'angle. En d'autres termes,
Plutôt que d'expliquer Comment sinus et cosinus, je vais vous montrer comment les utiliser à l'aide d'exemples pratiques. Pour parler franchement, le sinus et le cosinus sont les relations entre Y et X dans notre angle.
Imaginez que l'angle entre deux objets soit de 45 degrés. Dans ce cas, la relation entre sinus et cosinus est de 1: 1 (voir l'image ci-dessous), ce qui signifie que nous devons augmenter les propriétés X et Y de notre cercle de la même quantité chaque image pour atteindre la destination. Par exemple, vous devez ajouter 5 pixels à X et 5 pixels à Y à chaque image..
Dans ce diagramme, l'angle a changé et la relation entre sinus et cosinus a également changé. Il est environ 1: 2 maintenant.
Dans ce cas, nous devons ajouter deux fois plus de pixels à la propriété X de notre cercle qu'à Y. E.g. X + = 10, Y + = 5;
Vous demanderez probablement pourquoi nous avons besoin du sinus et du cosinus si nous connaissons déjà les coordonnées du point de clic - nous pouvons simplement déplacer notre mCircle
à eux tout de suite? Eh bien, vous auriez pu le faire de cette manière si vous vouliez que votre cercle (ou tout autre objet) se "téléporte" aux coordonnées d'un point de clic dès que le clic se produit. Mais que se passe-t-il si vous souhaitez qu’il se déplace progressivement dans la direction du clic? Pour ce faire, vous devez ajouter une quantité particulière de pixels à ses propriétés X et Y, par exemple, chaque image ou chaque seconde..
Calculons maintenant le nombre de pixels à ajouter à ses propriétés X et Y en fonction du sinus et du cosinus de l'angle entre notre objet et un point de clic. N'oubliez pas que Flash connaît l'angle entre eux à partir de cette opération:
myAtan2 = Math.atan2 (e.stageY - mCircle.y, e.stageX - mCircle.x);
Pour cela, nous devrions mettre à jour notre code un peu.
stage.addEventListener (MouseEvent.CLICK, CalculateAngle); // 2 est le nombre maximal de pixels à ajouter aux propriétés X et Y des objets à chaque image // vous pouvez utiliser n'importe quel nombre que vous aimez var moveAmount: Number = 2; var myAtan2: Number; var mouseClickX: Number; var mouseClickY: Number; function CalculateAngle (e: MouseEvent): void mouseClickX = e.stageX; mouseClickY = e.stageY; myAtan2 = Math.atan2 (mouseClickY - mCircle.y, mouseClickX - mCircle.x); addEventListener (Event.ENTER_FRAME, moveTheCircle); function moveTheCircle (e: Event): void mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount;
Notez ce que j'ai fait ici: j'ai promu toutes mes variables en dehors de toute fonction, car j'ai maintenant plus d'une fonction et je veux que ces variables soient accessibles à partir de chaque fonction..
var moveAmount: Number = 2; var myAtan2: Number; var mouseClickX: Number; var mouseClickY: Number;
La scène dispose d’un écouteur d’événements pour les clics de souris. Ainsi, lorsque le clic se produit, la méthode calcule l'angle ()
est appelé et les variables suivantes sont instanciées:
mouseClickX = e.stageX; mouseClickY = e.stageY; myAtan2 = Math.atan2 (mouseClickY - mCircle.y, mouseClickX - mCircle.x);
Cette fonction ajoute également un écouteur d'événement pour entrer une image sur la scène, qui appelle le moveTheCircle ()
méthode chaque image.
addEventListener (Event.ENTER_FRAME, moveTheCircle);
Maintenant, décomposons notre moveTheCircle ()
méthode elle-même. Pour l'instant, il ne fait que deux choses:
mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount;
Comme vous pouvez le constater, la première ligne calcule le nombre de pixels à ajouter à la propriété X et la seconde traite de Y. Laissez-moi vous expliquer. Math.cos trouve le cosinus (propriété x) de l'angle "myAtan2", Math.sin fait de même avec son sinus (propriété y). Si notre angle myAtan2 équivaut à environ 0,785 radian (45 degrés), le cosinus et le sinus équivaudront à environ 0,707… Vous pouvez utiliser une calculatrice pour le vérifier..
Un simple calcul montrera combien de pixels le code ci-dessus va ajouter aux propriétés X et Y de notre objet si l'angle est de 45 degrés.
Cosinus (45 degrés) = 0,707 * 2 = 1,414; Sinusoïdal (45 degrés) = 0,707 * 2 = 1,414; donc le code va travailler ces résultats: mCircle.x + = 1.414 pixels; mCircle.y + = 1,414 pixels;
Si l'angle, par exemple, est. 60 degrés alors les résultats seraient comme ceci:
Cosinus (60 degrés) = 0,5 * 2 = 1; Sinusoïdal (60 degrés) = 0,866 * 2 = 1,732; Et le code fonctionnerait de cette façon: mCircle.x + = 1 pixel; mCircle.y + = 1,732 pixels;
Eh bien, nous avons presque terminé. Mais il y a toujours un petit problème avec notre code. Vous avez peut-être remarqué que notre objet ne s'arrête jamais, même s'il atteint le point de clic, il continue à se déplacer. Nous pouvons résoudre ce problème très facilement. Lorsque notre objet se déplace vers le point de clic, la distance qui les sépare se raccourcit, de sorte que le absolu La valeur de la distance diminue aussi. Nous pouvons garder cela comme ceci:
trace (Math.abs (mCircle.x - mouseClickX)); trace (Math.abs (mCircle.y - mouseClickY));
(Math.abs ()
transforme les nombres négatifs en nombres positifs en les multipliant simplement par -1. Cela ne fait rien aux nombres qui sont déjà positifs.)
Vous n'avez pas besoin d'ajouter cette instruction de trace à votre code, je l'ai mise ici juste pour vous montrer comment vous pouvez voir la valeur absolue. Dans ce cas, les deux valeurs absolues sont inférieures à 3 lorsque l'objet atteint le point de clic. Nous avons donc besoin d’ajouter un si
déclaration à l'intérieur de notre moveTheCircle ()
une fonction.
function moveTheCircle (e: Event): void mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount; // Vérifie si les distances horizontale et verticale entre le cercle et le point de la souris sont très proches si (Math.abs (mCircle.x - mouseClickX) < 3 && Math.abs(mCircle.y - mouseClickY) < 3) removeEventListener(Event.ENTER_FRAME, moveTheCircle);
Lorsque la valeur absolue est inférieure à 3, le programme d'écoute de saisie de cadre est supprimé. Nous devons vérifier les valeurs absolues du X et du Y car l’un d’eux peut atteindre 3 même si le second ne l’a pas été. Cela signifie que les objets pourraient s'arrêter comme ceci:
L'image ci-dessus montre la version dans laquelle seule la valeur absolue de X est vérifiée. La valeur absolue de la distance X est déjà inférieure à 3, elle a donc cessé de prêter attention à la valeur Y.
Eh bien c'est ça. J'espère que ce petit conseil vous aidera à comprendre certaines trigonométries utilisées dans le développement Flash :)