Animation de menus de jeu et de transitions d'écran en HTML5 guide pour les développeurs Flash

Les développements HTML5 et Flash ont peut-être beaucoup en commun, mais en tant que développeur Flash, je trouve toujours que la réapprentissage de mes anciennes compétences en HTML5 est une tâche monumentale. Dans ce tutoriel, je vais vous montrer comment j'ai créé un menu animé et une transition d'écran pour un jeu de tir HTML5..


Aperçu du résultat final

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


Cliquez pour essayer la démo

Notez l'arrière-plan qui défile, les navires qui apparaissent et pivotent de chaque côté de chaque élément de menu, ainsi que la façon dont l'écran passe au noir lorsque vous sélectionnez une option..


introduction

HTML5 et JavaScript ressemblent à ActionScript à bien des égards; il y a beaucoup de chevauchement dans la syntaxe, les écouteurs d'événements et les méthodes. Cependant, il y a des différences très distinctes que je vais couvrir dans ce tutoriel:

  • Dessiner des formes
  • Dessiner des images
  • Utilisation des intervalles
  • Animer
  • Événements de souris
  • Ajout de la prise en charge de plusieurs navigateurs

Il convient de noter que ce didacticiel utilise principalement des images pouvant être téléchargées avec la source ou vous pouvez utiliser vos propres images si vous le souhaitez (vous aurez besoin de connaître les largeurs et les hauteurs)..


Étape 1: Mise en place

La première chose à faire est d’ajouter le élément à l'intérieur du corps d'un fichier HTML, créez-en un appelé ShootEmUp.html et insérez le texte suivant:

    Tue les    

Votre navigateur ne supporte pas HTML5!

Les lignes en surbrillance insèrent l'élément canvas, ce qui rendra notre menu actuel. Voir ce tutoriel pour un guide de la toile à partir de zéro.

Il est déjà presque temps de commencer à coder JavaScript! Nous avons deux options pour savoir où le code peut aller; Il peut être écrit à l'intérieur du HTML dans

Notre prochaine étape sera de créer quatre variables pour référencer facilement l’élément canvas..

 var canvas = document.getElementById ("myCanvas"); var context = canvas.getContext ("2d"); var width = canvas.getAttribute ('width'); var height = canvas.getAttribute ('height');

Nous avons d’abord référé le myCanvas variable et définissez-le pour qu'il pointe vers l'élément de la toile HTML. Une autre variable nommée le contexte a été créé pour obtenir la dimensionnalité de la toile (2D). Similaire à Flash, nous créons les deux dernières variables, largeur et la taille, simplifier le processus d'accès aux propriétés de largeur et de hauteur du canevas.


Étape 2: Chargement et dessin des images

Comme dans ActionScript, nous allons créer des instances de nos images..

 var bgImage = new Image (); var logoImage = new Image (); var playImage = new Image (); var instructImage = new Image (); var settingsImage = new Image (); var creditsImage = new Image (); var shipImage = new Image ();

Il nous manque un morceau de code crucial pour chaque instance - le chemin source! J'ai enregistré toutes les images du dossier "Images" dans le même répertoire que le fichier HTML.

 shipImage.src = "Images / ship.png"; bgImage.src = "Images / Background.png"; logoImage.src = "Images / logo.png"; playImage.src = "Images / play.png"; instructImage.src = "Images / instructions.png"; settingsImage.src = "Images / settings.png"; creditsImage.src = "Images / credits.png";

Avant de dessiner les images sur la toile, créons quatre tableaux contenant les positions et les tailles des boutons (playImage, instruireImage, paramètresImage, créditsImage). Ces tableaux seront utilisés plus tard pour créer une fonction de survol de la souris.

 var buttonX = [192,110,149,160]; var buttonY = [100,140,180,220]; var buttonWidth = [96,260,182,160]; var buttonHeight = [40,40,40,40];

Maintenant, nous pouvons dessiner les images sur la toile; cela peut être fait dans un en charge fonction pour chaque image, mais une fonction onload n'a pas besoin d'être incluse - nous pouvons simplement utiliser drawImage ().

 bgImage.onload = function () context.drawImage (bgImage, 0, 0); ; logoImage.onload = function () context.drawImage (logoImage, 50, -10);  playImage.onload = function () context.drawImage (playImage, buttonX [0], buttonY [0]);  instructImage.onload = function () context.drawImage (instructImage, buttonX [1], buttonY [1]);  settingsImage.onload = function () context.drawImage (settingsImage, buttonX [2], buttonY [2]);  creditsImage.onload = function () context.drawImage (creditsImage, buttonX [3], buttonY [3]); 

Si testé maintenant, vous devriez voir une image statique d'un menu dans lequel nous allons insuffler la vie. Le vaisseau n’a pas été dessiné avec le reste des images car nous allons le dessiner plus tard lors d’un événement de souris. À propos, si vous ne l'avez pas encore fait, gardez vos variables groupées en haut et faites la même chose avec les fonctions.


Étape 3: Animation par intervalles

JavaScript manque un onEnterFrame () équivalent, mais nous pouvons facilement créer le nôtre en utilisant un intervalle (minuterie).

 var frames = 30; var timerId = 0; timerId = setInterval (mise à jour, 1000 / images);

Vous pouvez être confus quant à la façon dont l'intervalle fonctionne, je vais donc expliquer brièvement. L'intervalle appelle la fonction mettre à jour() chaque (1000 /cadres) millisecondes pour créer un taux de rafraîchissement régulier. La valeur de cadres contrôle les fps; si cadres est 25 alors le navigateur va essayer d'appeler mettre à jour() toutes les (1000/25 =) 40 millisecondes.

Notre prochaine étape évidente est de créer la fonction mettre à jour()

 function update () clear (); bouge toi(); dessiner(); 

Trois autres fonctions viennent d'être appelées. clair() est utilisé pour effacer la toile car contrairement au flash, la toile fonctionne comme si vous mettiez des autocollants sur un tableau; les images ne peuvent plus être déplacées après avoir été placées. La fonction suivante, bouge toi(), est utilisé pour changer les valeurs de variable utilisées avec les images. finalement dessiner() est appelé à placer ces "autocollants".

 funcion clear () context.clearRect (0, 0, largeur, hauteur); 

En termes simples, ce code efface tout ce qui se trouve dans le rectangle, c'est-à-dire la taille du canevas et tiré de (0,0), le coin supérieur gauche. Cela signifie que cela efface toute la toile visible.

Avant de passer à la fonction suivante, deux variables doivent être introduites. contexte sera la variable pour la position y de l'image d'arrière-plan et la vitesse sera utilisé pour soustraire de contexte chaque cycle de mise à jour.

 var backgroundY = 0; vitesse var = 1;

L'effet que nous allons produire est un fond qui défile continuellement. L'image est composée de deux images starfield identiques, l'une au-dessus de l'autre, dans une image plus grande (l'image étant deux fois la hauteur de la toile). Nous allons lentement déplacer l'image vers le haut jusqu'à ce que la seconde moitié soit complètement visible, puis nous réinitialiserons la position de l'image sur la première moitié..

 fonction move () backgroundY - = speed; if (backgroundY == -1 * hauteur) backgroundY = 0; 

Enfin nous avons le dessiner() une fonction. Toutes les images seront redessinées, mais un changement à noter est que le bgImageLa valeur de y a été remplacée par la variable contexte.

 context.drawImage (bgImage, 0, backgroundY); context.drawImage (logoImage, 50, -10); context.drawImage (playImage, buttonX [0], buttonY [0]); context.drawImage (instructImage, buttonX [1], buttonY [1]); context.drawImage (settingsImage, buttonX [2], buttonY [2]); context.drawImage (creditsImage, buttonX [3], buttonY [3]);

Testez maintenant et admirez le fond de défilement lisse.


Étape 4: Vérification de la position de la souris

Une chose le HTML5 manque le support pour les écouteurs d’événements d’image, ce qui signifie que nous ne pouvons pas simplement écrire playImage.mouseover = function () . Au lieu de cela, nous devons obtenir la position de la souris par rapport au canevas et déterminer si elle se trouve sur un objet..

 var mouseX; var mouseY; canvas.addEventListener ("mousemove", checkPos);

Les deux variables introduites vont être utilisées pour obtenir la position actuelle de la souris. Nous avons ajouté un écouteur d'événement, comme dans ActionScript, qui appelle la fonction checkPos () chaque fois que la souris bouge.

 fonction checkPos (mouseEvent) mouseX = mouseEvent.pageX - this.offsetLeft; mouseY = mouseEvent.pageY - this.offsetTop; 

Si vous avez alerté les valeurs de mouseX et souris chaque fois que vous déplacez la souris, vous obtenez la bonne position. Mais il y a un problème: tous les navigateurs de bureau modernes ne prennent pas en charge cette méthode. Pour surmonter ce problème, nous pouvons utiliser le petit hack à la place:

 if (mouseEvent.pageX || mouseEvent.pageY == 0) mouseX = mouseEvent.pageX - this.offsetLeft; mouseY = mouseEvent.pageY - this.offsetTop;  else if (mouseEvent.offsetX || mouseEvent.offsetY == 0) mouseX = mouseEvent.offsetX; mouseY = mouseEvent.offsetY; 

Ceci vérifie si le navigateur utilise les propriétés "page" ou "offset" pour renvoyer la position de la souris et ajuste les valeurs (si nécessaire) pour obtenir la position de la souris par rapport au canevas..

Maintenant, rappelez-vous ce navire que nous avons instancié, mais n'a pas dessiné? Nous allons prendre cette image statique, la faire tourner et la faire apparaître chaque fois que nous passons la souris sur les boutons!

 var shipX = [0,0]; var shipY = [0,0]; var shipWidth = 35; var shipHeight = 40; var shipVisible = false; var shipSize = shipWidth; var shipRotate = 0;

Les quatre premières variables sont les mêmes que précédemment (nous avons deux positions car il y aura deux navires). le shipVisible variable sera définie sur true lorsque la souris survolera un bouton. Pour ce qui est de shipSize et shipRotate, ils seront utilisés pour redimensionner le bateau verticalement et le repositionner pour donner l’illusion qu’il tourne. Gardez à l'esprit que les images vont de droite à gauche.

 pour (i = 0; i < buttonX.length; i++) if(mouseX > buttonX [i] && mouseX < buttonX[i] + buttonWidth[i]) if(mouseY > buttonY [i] && mouseY < buttonY[i] + buttonHeight[i])  else  

Ajoutez le code dans le checkPos () une fonction. Tout d’abord, nous parcourons les boutons (j’ai calculé la valeur à l’aide de boutonX.longueur). Ensuite, nous comparons le mouseX pour voir s'il est supérieur à celui du bouton actuel boutonX et moins que son buttonX + buttonWidth - c'est-à-dire dans les limites horizontales du bouton. Nous répétons ensuite le processus dans une autre instruction if pour les valeurs Y. Si cela est tout à fait vrai, alors la souris doit être sur un bouton, alors shipVisible à vrai:

 shipVisible = true;

Et dans le vide autre déclaration définie sur faux; il sera ensuite appelé à chaque fois que vous passez la souris sur un bouton:

 shipVisible = false;

Sous shipVisible = true nous allons définir les valeurs initiales pour la shipX et navire, et effectuer toute la mise à l'échelle dans le mouvement et dessiner des fonctions.

 shipX [0] = boutonX [i] - (shipWidth / 2) - 2; shipY [0] = boutonY [i] + 2; shipX [1] = buttonX [i] + buttonWidth [i] + (shipWidth / 2); shipY [1] = boutonY [i] + 2;

Pour le premier shipX, que nous voulons juste à gauche du bouton, nous avons défini la valeur (X du bouton actuel - la moitié de la largeur du navire), et je l’ai déplacée de 2 pixels vers la gauche pour l’améliorer. Un processus similaire est répété pour le premier navire. Pour la seconde shipX on se positionne sur (le X du bouton actuel + la largeur de ce bouton + la moitié de la largeur du navire), puis on règle le Y comme avant.

La partie délicate vient maintenant. Nous devons redimensionner le navire et le déplacer pour compenser la mise à l'échelle. Dans le bouge toi() fonction écrire ceci si déclaration.

 if (shipSize == shipWidth) shipRotate = -1;  if (shipSize == 0) shipRotate = 1;  shipSize + = shipRotate;

Le code commence par soustraire la valeur de shipSize, qui sera utilisé pour redimensionner l'image lorsque nous la dessinons; une fois qu'il atteint zéro, le processus s'inverse jusqu'à ce qu'il soit à nouveau à pleine échelle.

Maintenant nous pouvons passer à la dessiner() une fonction. En dessous de toutes les autres méthodes de dessin, ajoutez ce qui suit:.

 if (shipVisible == true) context.drawImage (shipImage, shipX [0] - (shipSize / 2), shipY [0], shipSize, shipHeight); context.drawImage (shipImage, shipX [1] - (shipSize / 2), shipY [1], shipSize, shipHeight); 

Les navires sont dessinés normalement, à l’exception des positions X qui sont compensées en soustrayant la moitié de l’échelle actuelle..


Étape 5: Vérification des clics de souris

Ajouter un autre écouteur d'événement pour mouseup et créer une nouvelle variable pour un deuxième intervalle que nous allons créer.

 var fadeId = 0; canvas.addEventListener ("mouseup", checkClick);

Créer la fonction checkClick ().

 fonction checkClick (mouseEvent) pour (i = 0; i < buttonX.length; i++) if(mouseX > buttonX [i] && mouseX < buttonX[i] + buttonWidth[i]) if(mouseY > buttonY [i] && mouseY < buttonY[i] + buttonHeight[i])    

Comme précédemment, nous vérifions si la position de la souris est correcte. Maintenant, nous devons créer le nouvel intervalle et arrêter les écouteurs des autres intervalles et événements..

 fadeId = setInterval ("fadeOut ()", 1000 / frames); clearInterval (timerId); canvas.removeEventListener ("mousemove", checkPos); canvas.removeEventListener ("mouseup", checkClick);

Rien de nouveau ici sauf que nous devons créer une fonction appelée disparaître(). Nous devons également créer une autre variable appelée temps.

 var time = 0.0;
 fonction fadeOut () context.fillStyle = "rgba (0,0,0, 0.2)"; context.fillRect (0, 0, largeur, hauteur); temps + = 0,1; if (time> = 2) clearInterval (fadeId); temps = 0; timerId = setInterval ("update ()", 1000 / frames); canvas.addEventListener ("mousemove", checkPos); canvas.addEventListener ("mouseup", checkClick); 

Il a quelques nouvelles méthodes, mais c'est assez simple. Depuis que nous avons arrêté tous les écouteurs d'événements et l'autre intervalle, notre menu est complètement statique. Nous dessinons donc à maintes reprises un rectangle noir transparent en haut du menu - sans le dégager - pour donner l’illusion d’un fondu.

La variable temps est augmentée chaque fois que la fonction est appelée et une fois qu’elle atteint une certaine valeur (une fois que 20 "cadres" sont passés, dans ce cas), nous effaçons l’intervalle en cours. Ici, je réinitialise le menu, mais c’est là que vous dessinez une nouvelle section du menu..

Une dernière chose à noter est que lorsque vous dessinez des formes sur la toile, la fillStyle est défini avec une valeur rgb (rouge, vert, bleu). Lorsque vous voulez dessiner des formes transparentes, vous utilisez rgba (rouge, vert, bleu, alpha).

J'espère que cela a démystifié un peu le processus d'apprentissage pour passer d'une simple programmation AS3 à une programmation simple. Postez un commentaire si vous avez des questions!