Frapper la cible avec un missile mortel Homing

Ce tutoriel va guider en ajoutant des missiles à tête chercheuse mortels à l'arsenal de votre prochain match.


Aperçu du résultat final

Jetons un coup d'œil au résultat final sur lequel nous allons travailler:


Étape 1: Configuration du document FLA

Créez un nouvel ensemble de documents Flash pour ActionScript 3.0. Je vais utiliser les dimensions de 600x400 et une cadence de 30 FPS. Enregistrez le fichier avec un nom de votre choix.


Étape 2: créer une classe de document

Outre la FLA, nous devons également créer une classe de document. Créez un nouveau fichier Actionscript et ajoutez ce code:

 package import flash.display.Sprite; Classe publique Main Etend Sprite Fonction publique Main () 

Enregistrez ce fichier dans le même répertoire que notre fichier FLA. Nommez-leMain.as.


Étape 3: Liez le Principale Classe avec la FLA

Afin de compiler le code à partir du Principale classe, nous devons le relier à la FLA. Sur lePropriétés panneau de la FLA, à côté deClasse, entrez le nom de la classe de document, dans ce cas, Principale.

Enregistrez ensuite les modifications sur la FLA..


Étape 4: Dessinez un missile

Nous avons besoin d'un graphique de missile à afficher lors de la prise de vue. Vous pouvez importer une image bitmap ou dessiner une forme directement sur Flash. Je vais utiliser une forme minuscule sur cet exemple.

Ce qui est important ici, c’est que vous devez placer le point de missile tout à fait à droite, car c’est le point d’origine de la rotation. Donc 0ш signifie tout droit pointant vers la droite, -90ш signifie haut, 90ш signifie bas, et 180ш pointent vers la gauche. Plus tard, nous devrons faire pivoter le missile en fonction de sa direction..


Étape 5: Créer un MovieClip pour le missile

Une fois que vous avez le graphique de missile, sélectionnez-le et appuyez sur F8 pour créer un clip. Nommez-le "Missile", assurez-vous que le Point d'inscription est au centre et cochez la case "Exporter pour ActionScript".

Vous vous retrouverez avec un missile MovieClip dans la bibliothèque.

Si vous avez une instance de missile sur la scène, supprimez-la. Nous allons ajouter le missile MovieClip par code.


Étape 6: objectif

La première chose qu'un missile à tête chercheuse a besoin de savoir, c'est l'emplacement de la cible. Nous allons définir la rotation du missile en fonction de la position du curseur de la souris. Travaillons avec le enterFrame Evénement pour une mise à jour constante de la rotation.

Ajouter un Missile par exemple à la scène, je le place au centre (300, 200). Puis calculez la distance entre le missile et le curseur de la souris (je le stocke dans des variables targetX et cibleY). Enfin, l'angle du missile sera l'arc tangent des deux points (targetX, cibleY). Le résultat obtenu sera en radians, mais la rotation fonctionne en degrés. Vous devrez donc convertir en multipliant par 180 / Pi. (Pour voir pourquoi, consultez cet article.)

 import flash.events.Event; public class Main étend Sprite missile var privé: Missile = new Missile (); fonction publique Main () addChild (missile); missile.x = 300; missile.y = 200; addEventListener (Event.ENTER_FRAME, playGame);  fonction privée playGame (event: Event): void var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 / Math.PI; 

(Je ne sais pas quoi Math.atan2 () est pour? Consultez cet article sur la trigonométrie.

Si vous Publier (Ctrl + Entrée) le document à ce stade, vous devriez obtenir quelque chose comme ceci:

Déplacez votre souris près du missile pour le voir pivoter.


Étape 7: chercher

Nous avons eu la rotation, maintenant nous avons besoin du mouvement. Le missile doit rechercher la cible, qu’il s’agisse d’une cible stable ou en mouvement. Nous allons calculer le mouvement en fonction de la rotation actuelle du missile. Définissons une valeur pour la vitesse et faisons en sorte que le missile poursuive après le curseur de la souris.

Nous allons inclure quelques nouvelles variables pour calculer la vitesse (vx, vy). Lorsque le missile est dirigé vers la droite, son angle est inférieur à 90 ° et supérieur à -90 °, il est donc toujours inférieur à la valeur absolue de 90 °. Lorsqu'il pointe vers la gauche, son angle a une valeur absolue supérieure à 90 °. Cela déterminera vx conformément à la vitesse, puis vy sera la différence de la vitesse et vx.

 vitesse de la variable privée: int = 10; fonction publique Main () addChild (missile); missile.x = 300; missile.y = 200; addEventListener (Event.ENTER_FRAME, playGame);  fonction privée playGame (event: Event): void var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 / Math.PI; // La vitesse dans x est relative à l'angle; quand il est 90 ° ou -90 °, vx doit être 0. var vx: Nombre = vitesse * (90 - Math.abs (missile.rotation)) / 90; var vy: Number; // Velocity in y est la différence entre speed et vx. si (missile.rotation < 0) vy = -speed + Math.abs(vx);//Going upwards. else vy = speed - Math.abs(vx);//Going downwards. missile.x += vx; missile.y += vy; 

Vous obtiendrez un missile qui poursuivra votre curseur.

Vous pouvez utiliser une vitesse différente si vous voulez.


Étape 8: Créer un lanceur de missiles

Les missiles ne sortent pas de nulle part, ils sont tirés par des lanceurs de missiles. Faisons un MovieClip représentant un canon (je vais utiliser un simple rectangle), et nommez-le Canon. Je vais ajouter un Canon exemple par code, donc je vais garder la scène vide.


Étape 9: tirer

Maintenant, au lieu d’ajouter un missile, je vais simplement ajouter un canon, et un missile sera ajouté à la position du canon lorsque je clique sur la scène. Nous allons ajouter un booléen pour vérifier si le missile a été tiré, ainsi qu'une nouvelle fonction permettant de tirer après le clic..

 import flash.events.MouseEvent; public class Main étend Sprite missile var privé: Missile = new Missile (); vitesse de la variable privée: int = 10; private var cannon: Cannon = new Cannon (); private var missileOut: Boolean = false; // Le missile a-t-il été tiré? fonction publique Main () addChild (canon); canon.x = 50; canon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, shoot);  fonction privée playGame (event: Event): void if (missileOut) var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 / Math.PI; var vx: Number = speed * (90 - Math.abs (missile.rotation)) / 90; var vy: nombre; si (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy;   private function shoot(event:MouseEvent):void  if (!missileOut)  addChild(missile); swapChildren(missile, cannon);//missile will come out from behind cannon missileOut = true; missile.x = cannon.x; missile.y = cannon.y;  

Voici ce que vous obtiendrez:

Cela n'a pas l'air bien. Nous devons aussi faire tourner le canon ou forcer le missile à monter juste après avoir été touché. L'option n ° 1 étant la plus simple, nous allons choisir l'option n ° 2..


Étape 10: Moins de précision pour une meilleure apparence

Si le canon est vertical, on peut s’attendre à ce que le missile tire vers le haut, puis se dirige vers sa cible. L’approche que j’utiliserai pour y parvenir consiste à donner au missile un angle de départ de -90 ° (pointant vers le haut) et de le faire pivoter sans à-coups pour que le curseur de la souris se trouve bien sur sa trajectoire. Nous allons ajouter un facilité variable pour déterminer la finesse ou la netteté de la rotation. Ensuite, nous allons créer une autre variable pour suivre la rotation réelle qui pointe directement vers la cible, tandis que la rotation du missile changera en fonction de la facilité nous fixons (facilité = 1 se comportera comme avant, tout ce qui est plus haut fera un virage plus doux).

Comme la moitié des valeurs de rotation sont négatives, dans certains cas, nous devons les calculer par rapport à 360 pour obtenir la différence réelle entre l'angle de la cible et la rotation du missile..

 var var privé: int = 10; fonction publique Main () addChild (canon); canon.x = 50; canon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, shoot);  fonction privée playGame (event: Event): void if (missileOut) var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; rotation de var: int = Math.atan2 (targetY, targetX) * 180 / Math.PI; if (Math.abs (rotation - missile.rotation)> 180) if (rotation> 0 && missile.rotation < 0) missile.rotation -= (360 - rotation + missile.rotation) / ease; else if (missile.rotation > 0 && rotation < 0) missile.rotation += (360 - rotation + missile.rotation) / ease;  else if (rotation < missile.rotation) missile.rotation -= Math.abs(missile.rotation - rotation) / ease; else missile.rotation += Math.abs(rotation - missile.rotation) / ease; var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90; var vy:Number; if (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy;   private function shoot(event:MouseEvent):void  if (!missileOut)  addChild(missile); swapChildren(missile, cannon);//missile will come out from behind cannon missileOut = true; missile.x = cannon.x; missile.y = cannon.y; missile.rotation = -90;//missile will start pointing upwards  

Vérifiez-le:

Remarquez ce qui se passe lorsque vous déplacez votre souris hors du fichier SWF et en quoi cela diffère de l'exemple précédent..


Étape 11: Frappes de missiles, explosions de missiles

Outre le Missile Clip, il nous faut une animation d'explosion. Dans mon cas, je vais créer un MovieClip séparé avec une simple interpolation de cercle qui s’agrandit. Je l'exporte en tant que Explosion. presse O pour sélectionner le Outil ovale, et maintenir Décalage en dessinant l'ovale pour former un cercle.

Pour un effet visuel plus agréable, je vais insérer le cercle dans un autre clip vidéo et lui donner un aperçu. Biseau filtrez pour obtenir une couleur plus sombre en bas et une couleur plus claire en haut. Ensuite, je vais passer à la frame 10 et appuyer sur F6 créer un Image clé, puis faites un clic droit entre les images 1 et 10 et créez un Tween classique. De retour à l'image 10, appuyez sur Q pour sélectionner le Outil de transformation gratuit et agrandir le cercle.

Ensuite, créez un autre Tween classique pour encadrer 20, je vais ajouter un Brouiller effet de filtre.

Enfin, faites-le disparaître dans un dernier Classic Tween pour encadrer 30 avec un Alpha effet de couleur allant à 0.


Étape 12: Nettoyez la scène

L'animation de l'explosion doit être supprimée à la fin, sinon la boucle sera bouclée indéfiniment. Ajouter un nouveau calque et appuyer sur F6 sur la dernière image, puis appuyez sur F9 ouvrir le actes panneau, et ajoutez ce code:

 Arrêtez();
parent.removeChild (this);

Cela fera la Explosion par exemple se retirer après l'animation est terminée.


Étape 13: éclater

Maintenant quand le missile rencontre le curseur, nous le remplacerons par un Explosion exemple. Nous avons juste besoin d'ajouter un nouveau conditionnel dans le playGame () une fonction.

 fonction privée playGame (event: Event): void if (missileOut) if (missile.hitTestPoint (mouseX, mouseY)) explosion de var: Explosion = nouvelle Explosion (); addChild (explosion); explosion.x = missile.x; explosion.y = missile.y; enleverChild (missile); missileOut = false;  else var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; rotation de var: int = Math.atan2 (targetY, targetX) * 180 / Math.PI; if (Math.abs (rotation - missile.rotation)> 180) if (rotation> 0 && missile.rotation < 0) missile.rotation -= (360 - rotation + missile.rotation) / ease; else if (missile.rotation > 0 && rotation < 0) missile.rotation += (360 - rotation + missile.rotation) / ease;  else if (rotation < missile.rotation) missile.rotation -= Math.abs(missile.rotation - rotation) / ease; else missile.rotation += Math.abs(rotation - missile.rotation) / ease; var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90; var vy:Number; if (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy;   

Regarde:


Étape 14: Quelque chose d'autre à exploser

Courir après le curseur de la souris était amusant, mais cela ne sert à rien dans un jeu; nous devons faire une cible. Je vais dessiner un groupe de cercles pour former un Cible Clip du film.


Étape 15: Tirez sur la cible

Maintenant, nous allons ajouter un Cible par exemple pour que le missile ait un objectif plus concret. Nous allons donc remplacer toute référence du curseur de la souris pour la position de la cible. En outre, nous ne testerons pas un point de vie, mais un objet.

 private var target: Target = new Target (); fonction publique Main () addChild (canon); canon.x = 50; canon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, shoot); addChild (cible); target.x = 550; cible.y = 50;  fonction privée playGame (event: Event): void if (missileOut) if (missile.hitTestObject (cible)) var explosion: Explosion = new Explosion (); addChild (explosion); explosion.x = missile.x; explosion.y = missile.y; enleverChild (missile); missileOut = false;  else var targetX: int = target.x - missile.x; var targetY: int = target.y - missile.y; rotation de var: int = Math.atan2 (targetY, targetX) * 180 / Math.PI; if (Math.abs (rotation - missile.rotation)> 180) if (rotation> 0 && missile.rotation < 0) missile.rotation -= (360 - rotation + missile.rotation) / ease; else if (missile.rotation > 0 && rotation < 0) missile.rotation += (360 - rotation + missile.rotation) / ease;  else if (rotation < missile.rotation) missile.rotation -= Math.abs(missile.rotation - rotation) / ease; else missile.rotation += Math.abs(rotation - missile.rotation) / ease; var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90; var vy:Number; if (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy;    private function shoot(event:MouseEvent):void  if (!missileOut)  addChild(missile); swapChildren(missile, cannon); //missile will come out from behind cannon missileOut = true; missile.x = cannon.x; missile.y = cannon.y; missile.rotation = -90;//missile will start pointing upwards  

le hitTestObject () méthode ne vérifie en fait que le chevauchement entre les boîtes englobantes des deux objets (c’est-à-dire les boîtes bleues qui apparaissent lorsque vous cliquez sur une occurrence de l’objet dans la scène), alors faites attention à cela; ce n'est pas une détection de collision parfaite. Cependant, il fait très bien le travail ici.

Vous pouvez essayer de placer la cible à différents endroits, ainsi que le canon.


Étape 16: Cible mobile

Nous avons déjà vu que le missile poursuivra une cible en mouvement, telle que le curseur de la souris, alors faisons maintenant la Cible par exemple bouger un peu.

Ce n'est pas une physique réaliste, je vais simplement faire rebondir la cible verticalement. Je choisirai un point de référence comme niveau du sol et ajouterai une valeur de gravité pour affecter la cible. Et pour le rendre plus dynamique, je vais augmenter la vitesse du missile à 15.

 étage de var privé: int = 385; gravité privée var: nombre = 0,5; private var targetVY: Number = 0; // Vélocité verticale actuelle de la fonction publique cible Main () addChild (cannon); canon.x = 50; canon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, shoot); addChild (cible); target.x = 550; cible.y = 50;  fonction privée playGame (event: Event): void if (missileOut) if (missile.hitTestObject (cible)) var explosion: Explosion = new Explosion (); addChild (explosion); explosion.x = missile.x; explosion.y = missile.y; enleverChild (missile); missileOut = false;  else var targetX: int = target.x - missile.x; var targetY: int = target.y - missile.y; rotation de var: int = Math.atan2 (targetY, targetX) * 180 / Math.PI; if (Math.abs (rotation - missile.rotation)> 180) if (rotation> 0 && missile.rotation < 0) missile.rotation -= (360 - rotation + missile.rotation) / ease; else if (missile.rotation > 0 && rotation < 0) missile.rotation += (360 - rotation + missile.rotation) / ease;  else if (rotation < missile.rotation) missile.rotation -= Math.abs(missile.rotation - rotation) / ease; else missile.rotation += Math.abs(rotation - missile.rotation) / ease; var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90; var vy:Number; if (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy;   targetVY += gravity; target.y += targetVY; if (target.y > sol) cible.y = sol; targetVY = -18; 

Si vous Publier cela maintenant, vous devriez obtenir une cible en mouvement.


Conclusion

Que vous souhaitiez un missile à tête chercheuse précis ou une animation fluide, vous pouvez obtenir les deux résultats en fonction de cet exemple. Maintenant que vous avez une nouvelle arme à ajouter à votre arsenal, vous pourriez peut-être essayer de créer un jeu ressemblant à Worms, ou même utiliser l'algorithme sur autre chose qu'un missile, comme un moustique étrange qui suit votre personnage..

J'espère que vous avez trouvé ce tutoriel utile. Merci d'avoir lu!