Créez votre propre jeu de pseudo 3D Pong

Deux fois par mois, nous revoyons certains des articles préférés de nos lecteurs dans l’histoire d’Activetuts +. Ce tutoriel a été publié pour la première fois il y a longtemps, en mai 2009..

Dans ce tutoriel, je vais décrire comment créer une scène 3D de base à l'aide des options 3D natives de Flash Player 10. Ensuite, nous expliquerons comment ajouter de l'interactivité aux éléments et configurer un jeu de pong de base. Allons-y?


Étape 1: Mise en scène

Préparons la scène et créons la scène 3D. Dans une partie normale de pong, la balle rebondit en haut et en bas de l'écran, mais comme nous ajoutons une certaine perspective au mélange, nous devrons également fournir ces frontières. Cinq clips vidéo sont nécessaires: le sol et les quatre murs (dont deux sont en réalité des pagaies). Les points d’enregistrement des murs doivent tous être situés contre le sol. Vous pouvez créer tout cela simplement avec l'outil Rectangle ou utiliser une image bitmap importée (n'oubliez pas d'activer "Autoriser le lissage" dans les propriétés). Faites un MovieClip sur chacun des murs et donnez-leur un nom d'instance (je les ai nommés "wallTop", "wallBottom", "wallLeft" et "wallRight" et les référencerai plus tard). Nommez le fond "sol".

Sélectionnez tous les murs et le sol, créez-en un grand et nommez-le "bg".

Pour afficher la partition ultérieurement, nous aurons également besoin de deux champs de texte dynamiques. Si vous les placez dans le MovieClip "bg", ils auront également la perspective 3D. Nommez-les "scoreLeft" et "scoreRight" puis intégrez les polices.


Étape 2: Création du ballon

Créez la balle à l'aide de l'outil ovale et dégradé sur la scène. Ne placez pas la balle dans le MovieClip "bg", sinon elle serait déformée par la perspective. Nous ne donnerons pas à la balle les propriétés 3D réelles, mais la ferons comme si c'était de la 3D. Placez la balle au centre de l'écran et nommez-la par exemple "balle".


Étape 3: Classe de document

Nous allons maintenant configurer la scène 3D en utilisant les nouvelles propriétés rotationX, Y et Z ajoutées à Flash Player 10. Toutefois, avant de pouvoir exécuter du code ActionScript, nous devons créer la classe de document. Créez un fichier Main.as vide et remplissez-le avec le code ci-dessous.

 package import flash.display.MovieClip; Classe publique Main étend MovieClip fonction publique Main (): void // Remplace ce commentaire par du code ultérieurement

Maintenant, pour utiliser ceci comme classe principale, nous pouvons renseigner "Principal" dans la zone de saisie "Classe:" des propriétés du document..


Étape 4: rotation

Essayons la rotation. Ajoutez cette ligne à la fonction Main () pour tout donner en perspective:

 bg.rotationX = -30;

Comme vous pouvez le voir, tous les MovieClips sont maintenant tournés de 30 ° autour de l'axe des x.

Chacune des parois nécessite une rotation de 90 ° pour se tenir debout. Comme vous pouvez le constater, le mode de fusion des murs a également été modifié pour que les dégradés soient plus nets. Le code suivant est uniquement destiné à la prévisualisation car nous le remplacerons par des interpolations à l'étape suivante (supprimez-le après le test)..

 bg.wallTop.rotationX = 90; bg.wallBottom.rotationX = -90; bg.wallRight.rotationY = 90; bg.wallLeft.rotationY = -90;

Étape 5: Fonction de démarrage

Pour ajouter un effet aux murs, nous devons d’abord créer un bouton de démarrage. Créez un MovieClip avec le texte "Cliquez ici pour commencer". Encore une fois, vous pouvez placer ceci dans "bg" si vous voulez aussi avoir une perspective. Donnez-lui un nom d'instance comme "startText". Nous pouvons maintenant le référencer dans le code et y ajouter un eventlistener. Définissez également le paramètre buttonMode sur true, ce qui renverra le curseur de la main lorsque la souris survolera le bouton. Lorsque vous cliquez dessus, la fonction de démarrage est appelée et le bouton est masqué. Nous masquons également le pointeur de la souris car l'utilisateur contrôlera le mur droit avec la souris.

 fonction publique Main (): void bg.rotationX = -30; startText.addEventListener (MouseEvent.MOUSE_UP, début); startText.buttonMode = true;  fonction privée start (_e: Event): void startText.buttonMode = false; startText.visible = false; Mouse.hide (); // Cela contiendra les tweens

Étape 6: interpolation

Nous pouvons utiliser TweenLite pour interpoler les murs de 0 à 90 ° en rotation. Bien sûr, tout moteur d'interpolation conviendra, mais je préfère celui-ci. Le code suivant interpelle les murs en 2 secondes et utilise la fonction d'accélération "Bounce.easeOut". Pour interpoler également la valeur alpha des murs, nous devons d’abord le régler sur 0. Vous pouvez le faire dans Flash en définissant l'alpha sur 0 dans les paramètres de couleur. Une fois ces tweens terminés, le jeu devrait commencer. Ajoutez donc une propriété "onComplete" à l'un des tweens et associez-lui un nom de fonction (vous pouvez le laisser pour le test car la fonction n'existe pas encore)..

 fonction privée start (_e: Event): void startText.buttonMode = false; startText.visible = false; Mouse.hide (); nouveau TweenLite (bg.wallRight, 2, rotationY: 90, alpha: 1, facilité: Bounce.easeOut); nouveau TweenLite (bg.wallLeft, 2, rotationY: -90, alpha: 1, facilité: Bounce.easeOut); nouveau TweenLite (bg.wallTop, 2, rotationX: 90, alpha: 1, facilité: Bounce.easeOut); nouveau TweenLite (bg.wallBottom, 2, rotationx: -90, alpha: 1, facilité: Bounce.easeOut, onComplete: goBall); 

Étape 7: Pagaies

Avant de pouvoir commencer le jeu, nous devrons ajouter de l’interactivité aux murs gauche et droit et à la balle. Commençons par la pagaie du joueur. Créez une nouvelle classe "Player.as" et ajoutez le code suivant.

 package import flash.display.MovieClip; import flash.events.MouseEvent; public class Player étend MovieClip fonction publique Player (): void stage.addEventListener (MouseEvent.MOUSE_MOVE, moveAlong);  fonction privée moveAlong (_e: MouseEvent): void var mousePos: Number = stage.mouseY - parent.y; si (MousePos < 0 ) y = 0; else if ( mousePos > 340) y = 340; sinon y = mousePos; 

Dans le constructeur (la fonction Player), nous ajoutons un eventlistener à la scène pour vérifier le déplacement de la souris et appeler la fonction "moveAlong" à chaque fois. Dans la fonction moveAlong, nous calculons la position locale de la souris (uniquement la position y puisque nous ne nous déplaçons que verticalement). Ensuite, nous vérifions si la souris sort des limites et réinitialisons la position le cas échéant. J'ai trouvé la valeur 340 par essais et erreurs, car "parent.height - height" ne renvoie pas la valeur attendue lorsque nous utilisons une perspective 3D..

Ensuite, changez les propriétés du wallRight movieclip; cochez la case "Exporter pour ActionScript" et définissez la classe sur "Lecteur". Laissez la "classe de base" vide.


Étape 8: adversaire (AI)

La création de l'IA est très similaire à la création du joueur. Seulement cette fois, nous le ferons avancer vers la valeur y de la balle mais avec une vitesse légèrement inférieure à celle de la balle. Créez une autre classe "AI.as":

 package import flash.display.MovieClip; import flash.events.Event; classe publique AI étend MovieClip fonction publique AI (): void addEventListener (Event.ENTER_FRAME, followBall);  fonction privée followBall (_e: Event): void var ball: MovieClip = MovieClip (parent.parent) .ball; if (ball.xspeed || ball.yspeed) var newy: Number = ball.y - height; si (nouveau> 345) nouveau = 345; si (y <= newy ) y += 9; else y -= 9;    

Nous devons d’abord pouvoir référencer la balle. Puisque le clip mural WallLeft est à l'intérieur du clip vidéo "bg", l'appel de "parent" ferait référence à "bg". Pour cette raison, nous devons utiliser "parent.parent". La première instruction "if" vérifie si la balle a une vitesse x ou yspeed. Ce sont des variables publiques de la balle que nous définirons plus tard. Le contrôle empêche l'IA de bouger avant le début du jeu. La valeur "newy" contient la valeur y de la balle moins la hauteur de wallLeft. C'est la valeur à laquelle il doit se déplacer pour frapper la balle. Comme auparavant, changez la classe de wallLeft en "AI".


Étape 9: Fonctionnalité du ballon

La balle a besoin de la plupart des fonctionnalités: elle doit bouger, rebondir sur les murs, vérifier si les palettes sont touchées et mettre à jour sa propre profondeur car ce n'est pas un objet 3D..

 package import flash.display.MovieClip; import flash.events.Event; public class Ball s'étend sur MovieClip public var xspeed: Number = 0; public var yspeed: Number = 0; fonction publique Ball (): void  fonction publique start (): void xspeed = -12; yspeed = 12; addEventListener (Event.ENTER_FRAME, moveBall);  fonction privée moveBall (_e: Event): void profondeur (); collision(); x + = xspeed; y + = yspeed;  fonction privée profondeur (): void // redimensionne la balle en fonction de sa position y fonction privée collision (): void // fait rebondir la balle

Tout d'abord, nous donnons à la balle un x et yspeed. Celles-ci sont définies sur public afin que nous puissions vérifier à partir d'autres objets si la balle est en mouvement. Ajoutez ensuite un eventlistener "onenterframe" à la fonction de démarrage. Lorsque la fonction de départ est appelée, la balle commence à bouger de chaque image. J'ai donné à la balle une vitesse de départ de 12 pixels par image. Vous pouvez changer cela pour accélérer le jeu mais vous pouvez aussi augmenter le nombre d'images par seconde. En fait, la fonction moveBall augmente les valeurs x et y de la balle en fonction de x et de yspeed. Il appelle également les fonctions de profondeur et de collision sur chaque image.


Étape 10: perspective du ballon

Comme la balle n’est pas un objet 3D et qu’elle n’a pas de valeur z, elle ne paraîtra pas plus petite une fois que la valeur y aura changé. Plus la balle devient haute à l'écran (valeur y faible), plus elle devrait apparaître petite. Nous pouvons changer cela en le modifiant simplement en fonction de sa position:

 fonction privée profondeur (): void var plus petit: Number = ((y / stage.stageHeight) * 0.6) + 0.6; scaleX = scaleY = plus petit; 

Étape 11: Cours de collision

La fonction "collision" décidera quand et comment la balle rebondira sur d'autres objets. Dans la première déclaration "if", nous vérifions simplement la valeur y pour déterminer si la balle frappe le mur supérieur ou inférieur. Encore une fois, j'ai trouvé ces valeurs par essais et erreurs, car la balle doit rebondir de manière plausible. Si la vérification est vraie, il en résulte une modification de la vitesse y, de sorte que la balle change de direction verticale.

 fonction privée collision (): void if (y> = 463 || y <= 105 )  yspeed *= -1; 

Vérifier les frontières x n'est pas aussi facile à cause de la perspective et des pagaies qui se déplacent. Nous pouvons effectuer un "hitTest" avec les murs et renvoyer la balle si c'est vrai. Les HitTests sont un peu lourds, il est donc préférable de ne pas en abuser. Cependant, comme nous avons affaire à un simple jeu de pong, cela ne ralentira pas le jeu de façon notable. J'ai cependant ajouté un chèque supplémentaire; pour voir si la valeur x de la balle est à gauche ou à droite de la scène et vérifiez le mur en conséquence. Cela garantit qu’un seul hitTest est nécessaire par image au lieu de deux..

 if ((x> stage.stageWidth / 2 && hitTestObject (MovieClip (parent) .bg.wallRight)) || (x < stage.stageWidth / 2 && hitTestObject( MovieClip(parent).bg.wallLeft)) )  xspeed *= -1; 

Enfin, nous devons savoir si la balle est toujours sur la plate-forme. Nous pouvons le savoir en vérifiant si un point au bas de la balle est toujours situé sur le "sol". Le point exact a la valeur x de la balle et la valeur y plus le rayon. Si cela est vrai, nous découvrons si la balle s'est décollée du côté gauche ou du côté droit (en comparant à nouveau la valeur x au centre de l'écran) et mettons à jour le score de manière fidèle. À la fin, définissez les valeurs x et y de la balle au centre pour que le jeu puisse continuer..

 si (! MovieClip (parent) .bg.floor.hitTestPoint (x, y + (hauteur / 2 * scaleY), true)) if (x < stage.stageWidth / 2 ) MovieClip(parent).bg.scoreRight.text = Number(MovieClip(parent).bg.scoreRight.text) + 1; else MovieClip(parent).bg.scoreLeft.text = Number(MovieClip(parent).bg.scoreLeft.text) + 1; y = stage.stageHeight / 2; x = stage.stageWidth / 2;  

Changer la classe de la balle en "balle".


Étape 12: action!

Maintenant que nous avons créé les palettes et la balle, il ne reste plus qu'à mettre le jeu en action. Ajoutez cette fonction à la classe Main et assurez-vous que le onComplete que nous avons utilisé à l'étape 6 fait référence à cette fonction..

 fonction privée goBall (): void ball.start (); 

Étape 13: Ajout de rebond

Une fois le score mis à jour, la balle revient au centre et recommence à rouler. Nous devons animer légèrement la balle en revenant avant que le jeu ne recommence.

Remplacez ce code dans la fonction de collision de la balle:

 y = stage.stageHeight / 2; x = stage.stageWidth / 2;

Par:

 xspeed = yspeed = 0; removeEventListener (Event.ENTER_FRAME, moveBall); y = -hauteur; x = stage.stageWidth / 2; échelle de var: Nombre = (0.5 * 0.6) + 0.6; new TweenLite (this, 1.5, y: stage.stageHeight / 2, scaleX: échelle, scaleY: échelle, facilité: Bounce.easeOut, onComplete: start);

Cela empêchera le ballon de bouger en premier. Ensuite, il définit la position de la balle juste au-dessus de l'écran mais horizontalement centrée. Si nous utilisons ensuite la fonction d’atténuation du rebond, la balle tombera d’en haut juste avant de reprendre le jeu..


Conclusion

J'espère que vous avez pu suivre sans trop de problèmes. Le jeu actuel est très basique et peut apporter quelques améliorations. La balle, par exemple, rebondit toujours à 90 degrés, ce qui rend le mouvement très prévisible..

Si vous souhaitez aller plus loin, vous pouvez essayer de faire varier la vitesse x et la vitesse y en fonction du point où la balle frappe la raquette (comparez les valeurs y). La détection de collision avec les palettes est loin d'être parfaite, mais elle vous montre un moyen simple de rechercher un coup. Enfin, si vous n’utilisez pas de dégradés pour les murs, vous remarquerez que la balle semble rouler sur le mur au lieu de disparaître sous celui-ci. Pour résoudre ce problème, vous pouvez facilement séparer les objets qui devraient apparaître sur la balle et les placer dans un nouveau MovieClip que vous déformez autant que le MovieClip "bg" et que vous disposerez plus haut que la balle en Flash.