Phaser 2.0 Tutoriel : Flappy Bird (Partie 1)

Publié le .

Phaser 2 Tutoriel
Phaser 2.0 Tutoriel : Flappy Bird (Partie 1)

Et hop ! Un clone de plus de Flappy Bird !!! En fait, c’est surtout le prétexte pour apprendre et comprendre certains concept de base pour faire un jeu avec Phaser 2.0.

Rendons à César, ce qui est à César !!!

En fait, ce tutoriel est une adaptation de celui rédigé en anglais par Jeremy Dowell. Tutoriel que vous trouverez sur cette page. La plupart des images de cette adaptation viennent elles aussi de ce tutoriel...

Les images du jeu viennent d’un tutoriel pour Titanium sur comment faire... Oh ! Grande surprise !!! Un clône de Flappy Bird ! Vous trouverez ce tutoriel à cette page.

Le but de ce tutoriel Phaser 2.0

Le but n’est pas de faire un jeu complet pour le moment. Il s’agit juste de mettre en place la mécanique pour obtenir une réplique ( presque ) parfaite de l’écran d’accueil de Flappy Bird.

Et si je veux le jeu complet ? Hein !? Et bien, il faudra suivre les tutoriels suivants pour avoir le jeu complet. Jeu que vous pouvez tester sur cette page...

Si vous suivez l’ensemble des tutoriels pour faire ce jeu en vous impliquant plus qu’en copiant-collant bêtement, et que vous ne connaissez pas Phaser, vous apprendrez et comprendrez les concepts de base important et absolument nécessaire avant de vous envoler de vos propres ailes ;-) Like a bird...

Pourquoi Flappy Bird ?

Ca a été fait mille fois, surement plus... Mais c’est un jeu simple basé sur la physique. Et il n’est pas difficile d’en faire un clone parfait.

Et bien, allons-y !!!

Attention, nous allons utiliser le generator-phaser-official ! Et ce pour générer l’échaffaudage ou la structure de notre jeu. Pour des infos en français sur ce générateur, c’est par ici...

1 : Créé un répertoire et aller dedans

$ mkdir flappy-bird-reborn && cd $_

2 : Utiliser le générateur

$ yo phaser-official

Répondez aux questions avec les valeurs suivantes :

[?] What is the name of your project ? flappy bird reborn

[?] Which Phaser version would you like to use ? 2.0.1

[?] Game Display Width : 288

[?] Game Display Height : 505

3 : Lancer le générateur

Une fois que le générateur à fait son boulot, la struture pour notre jeu doit ressembler à ça :

── Gruntfile.js

├── assets

│ ├── preloader.gif

│ └── yeoman-logo.png

├── bower.json

├── config.json

├── css

│ └── styles.css

├── game

│ ├── main.js

│ └── states

│ ├── boot.js

│ ├── gameover.js

│ ├── menu.js

│ ├── play.js

│ └── preload.js

├── package.json

└── templates

├── _index.html.tpl

└── _main.js.tpl

Attention, je n’ai pas mis les répertoires bower_components et node_modules pour que ce soit plus facile à lire.

Allons-y gaiement, lançons la commande $ grunt !

Et patatra, nous obtenons cela dans notre navigateur :

Notre dossier ressemble à cela maintenant :

── Gruntfile.js

├── assets

│ ├── preloader.gif

│ └── yeoman-logo.png

├── bower.json

├── config.json

├── css

│ └── styles.css

├──dist

│ ├── assets

│ │ ├── preloader.gif

│ │ └── yeoman-logo.png

│ ├── css

│ │ └── styles.css

│ ├── js

│ │ └── game.js

│ └── index.html

├── game

│ ├── main.js

│ └── states

│ ├── boot.js

│ ├── gameover.js

│ ├── menu.js

│ ├── play.js

│ └── preload.js

├── package.json

└── templates

├── _index.html.tpl

└── _main.js.tpl

Comme vous l’avez peut être remarqué, il manque le fichier phaser.js quelque part. Ayant indiqué que nous voulions un projet avec Phaser 2.0.1, il faut aller télécharger celui-ci depuis le github de Phaser dans la partie "relesases" et le mettre dans dist>js.

En rafraîchissant notre page, nous obtenons maintenant :

Ca a l’air fonctionnel maintenant !

En fait Grunt compile, lance un serveur, ouvre un navigateur et rafraîchit la page lorsque l’on sauve son code.

Attention, il ne faut pas fermer le terminal... Sinon, grunt s’arrête et ne peut plus faire son boulot... Je le sais, je me suis fait avoir ! LOL !

Assets

Pour ceux qui ne la savent pas, les assets sont en fait les médias qui servent au jeu. En gros, des fichiers son, image, texte, vidéo, etc...

Vous pouvez télécharger les assets pour jeu ici. Attention, comme déjà mentionné, ils proviennent d’un tutoriel sur comment faire un Flappy Bird avec Titanium. Une fois le zip des assets téléchargés, ouvrez le et mettez son contenu dans le répertoire "assets".

Le menu

Tout les jeux ont besoin d’un menu ! Le notre n’échappa pas à la règle... Nous allons donc maintenant précharger les assets dont nous allons avoir besoin pour notre menu. Ouvrez le fichier game/states/preload.js Vous devriez y voir quelque chose comme :

  1. 'use strict';
  2. function Preload() {
  3.   this.asset = null;
  4.   this.ready = false;
  5. }
  6.  
  7. Preload.prototype = {
  8.   preload: function() {
  9.     this.asset = this.add.sprite(this.width/2,this.height/2, 'preloader');
  10.     this.asset.anchor.setTo(0.5, 0.5);
  11.  
  12.     this.load.onLoadComplete.addOnce(this.onLoadComplete, this);
  13.     this.load.setPreloadSprite(this.asset);
  14.     this.load.image('yeoman', 'assets/yeoman-logo.png');
  15.  
  16.   },
  17.   create: function() {
  18.     this.asset.cropEnabled = false;
  19.   },
  20.   update: function() {
  21.     if(!!this.ready) {
  22.       this.game.state.start('menu');
  23.     }
  24.   },
  25.   onLoadComplete: function() {
  26.     this.ready = true;
  27.   }
  28. };
  29.  
  30. module.exports = Preload;

Télécharger

Si vous regardez le menu du Flappy Bird original, vous vous rendez compte qu’il consiste en un fond d’écran, un titre, un oiseau, un bouton de démarrage et un bouton de partage. Nous n’allons pas implémenter le bouton de partage, mais tous les autres éléments seront là ! Nous devons donc en charger les images dans notre menu. Voici le code pour faire cela :

  1. preload: function() {  
  2.     this.load.onLoadComplete.addOnce(this.onLoadComplete, this);
  3.     this.asset = this.add.sprite(this.width/2, this.height/2, 'preloader');
  4.     this.asset.anchor.setTo(0.5, 0.5);
  5.     this.load.setPreloadSprite(this.asset);
  6.  
  7.     this.load.image('background', 'assets/background.png');
  8.     this.load.image('ground', 'assets/ground.png');
  9.     this.load.image('title', 'assets/title.png');
  10.     this.load.image('startButton', 'assets/start-button.png');
  11.  
  12.     this.load.spritesheet('bird', 'assets/bird.png', 34, 24, 3);
  13. }

Télécharger

A coller ver la ligne 9 du fichier game/states/preload.js...

Les quatre premières lignes de cette fonction sont un code "générique". Il affiche une barre de progression pendant que les autres images sont chargées.

Les 4 lignes suivantes chargent des images individuelles. La syntaxe pour charger une image est simple :

this.load.image(key,url);

Cela dit au système de cache de Phaser de charger l’image depuis l’url donnée et de la stocker. L’argument key est un nom unique servant à l’identifier facilement pour pouvoir l’appeler dans notre jeu.

3 : Regardons de plus près la dernière ligne

Cette ligne diffère légèrement des autres. Ceci parce que nous allons charger un sprite. C’est à dire un ensemble d’images réunies en une seule que l’on va afficher sucessivement. Ci-dessous le sprite de notre oiseau :

Comme vous pouvez le voir, ce sprite ce décompose en 3 images ou frames.

Vous pouvez me croire sur parole lorsque je vous affirme que chaque frame est de 34 pixels de large et 24 pixels de haut !

La syntaxe pour charger un sprite est la suivante :

this.load.spritesheet(key, url, frameWidth, frameHeight, numberOfFrames);  

Sachant que notre sprite a 3 frames, chacunes d’entre elles faisant 34 pixels de large et 24 pixels de haut, nous chargeons notre sprite avec la ligne de code suivante :

this.load.spritesheet('bird', 'assets/bird.png', 34, 24, 3);

Allons-y ! Sauvons notre code ! Les choses n’aurons plus l’air parfaites maintenant...

Rassurez-vous, c’est normal... Notre code ne charge plus l’image qu’il y avait précédemment. Ce n’est pas grave, nous allons faire quelque chose d’impressionnant avec une seule ligne de code !

Codons le Menu :

Ouvrez le fichier game/states/menu.js. Vous devriez y trouver le code suivant :

  1. 'use strict';
  2. function Menu() {}
  3.  
  4. Menu.prototype = {
  5.   preload: function() {
  6.  
  7.   },
  8.   create: function() {
  9.     var style = { font: '65px Arial', fill: '#ffffff', align: 'center'};
  10.     this.sprite = this.game.add.sprite(this.game.world.centerX, 138, 'yeoman');
  11.     this.sprite.anchor.setTo(0.5, 0.5);
  12.  
  13.     this.titleText = this.game.add.text(this.game.world.centerX, 300, '\'Allo, \'Allo!', style);
  14.     this.titleText.anchor.setTo(0.5, 0.5);
  15.  
  16.     this.instructionsText = this.game.add.text(this.game.world.centerX, 400, 'Click anywhere to play "Click The Yeoman Logo"', { font: '16px Arial', fill: '#ffffff', align: 'center'});
  17.     this.instructionsText.anchor.setTo(0.5, 0.5);
  18.  
  19.     this.sprite.angle = -20;
  20.     this.game.add.tween(this.sprite).to({angle: 20}, 1000, Phaser.Easing.Linear.NONE, true, 0, 1000, true);
  21.   },
  22.   update: function() {
  23.     if(this.game.input.activePointer.justPressed()) {
  24.       this.game.state.start('play');
  25.     }
  26.   }
  27. };
  28.  
  29. module.exports = Menu;

Télécharger

Soyons fous ! Effaçons tout et remplaçons ce code par :

  1.   'use strict';
  2.   function Menu() {}
  3.  
  4.   Menu.prototype = {
  5.     preload: function() {
  6.     },
  7.     create: function() {
  8.     },
  9.     update: function() {
  10.     }
  11.   };
  12.   module.exports = Menu;

Télécharger

Ajoutons l’image de fond :

Nous allons donc charger l’image de fond. Pour cela, nous allons utiliser la méthode create du fichier game/states/menu.js

  1. create: function() {  
  2.      // add the background sprite
  3.     this.background = this.game.add.sprite(0, 0, 'background');
  4. },

Télécharger

Allons-y ! Sauvegardons notre fichier ! Allons voir le fenêtre du navigateur contenant notre jeu... Et voilà le résultat :

L’image du fond est bien là !

Une petite remarque sur l’affichage d’un sprite. C’est ridiculement facile :

var sprite = this.game.add.sprite(x, y, key);  
Le x et le y sont clairement les valeurs de l’abscisse et de l’ordonnée. L’argument key est la "clé" ou l’identifiant que nous avons donné à l’image dans le preloader. Rappelez-vous, dans le fichier : game/states/preload.js.

Ajoutons le sol :

Dans l’original de Flappy Bird, le sol bouge, même sur le menu. Pour faire cela, nous allons utiliser ce qui s’appelle un TileSprite. Du coup, nous pourrons faire bouger le sol sans avoir à instancier des sprites avec une texture pour les faire bouger et détecter leur sortie de l’écran...

Une fois de plus, nous allons utiliser la méthode create du fichier game/states/menu.js. A la suite du code pour le fond, nous allons ajouter les ligne de code suivante :

  1. // add the ground sprite as a tile
  2. // and start scrolling in the negative x direction
  3. this.ground = this.game.add.tileSprite(0, 400, 335, 112, 'ground');
  4. this.ground.autoScroll(-200, 0);

Télécharger

Vite ! Sauvons notre code ! Maintenant nous voyons quelque chose comme ça dans notre navigateur :

Moi, je dis : « C’est la grande classe ! »

Regardons la syntaxe de TileSprite :

Nous avons deux ligne à considérer. Voyons d’abord la première... Elle permet d’ajouter un TileSprite :

var tileSprite = this.game.add.tileSprite(x, y, width, height, key);

C’est relativement simple à comprendre si on a bien assimilé la logique de la syntaxe suivie jusque maintenant... Evidemment, width est la largeur et height, la hauteur...

La magie se passe à la seconde ligne :

tileSprite.autoScroll(xSpeed, ySpeed);

Cette ligne dit à notre tileSprite de bouger automatiquement à la vitesse donnée en pixel par seconde. xSpeed est la vitesse de déplacement selon l’abcisse et vous l’avez devinez, ySpeed est la vitesse de déplacement selon l’ordonnée. Un xSpeed négatif va faire bouger vers la gauche tandis qu’un xSpeed va faire bouger vers la droite. Un ySpeed négatif va faire bouger vers le haut et un ySpeed positif vers la bas. Simple, non ?

Ajoutons le titre et l’oiseau

Ok... C’est un gros morceau ! Palons un peu de ce qui va se passer. Dans le Flappy Bird original, le titre et l’oiseau oscille lentement de bas en haut pendant que l’oiseau bat des ailes. Pour reproduire cela, nous allons suivre les étapes suivantes :

  1. Créer un groupe pour pour y mettre notre titre et notre oiseau, ce sera le groupe "title"
  2. Créer le sprite du titre et l’ajouter au groupe "title"
  3. Créer le sprite de l’oiseau et l’ajouter au groupe "title"
  4. Ajouter une animation à l’oiseau en utilisant un spritesheet ( Plusieurs images regroupées dans un seul fichier ) et commencer à jouer avec l’animation
  5. Placer le groupe
  6. Ajouter une interpolation de mouvement ou tween au groupe pour que tout son contenu oscille en même temps
  7. En parler ( Parce que ce n’est pas sale... )

Je vais vous balancer un gros pavé de code, et ensuite, je vais le découper pour en parler morceau par morceau.

Encore une fois de plus, nous allons utiliser la méthode create du fichier game/states/menu.js. Sous le code saisie précédement, nous allons ajouter ce pavé :

  1. create: = function {  
  2.     /* Ici se trouve le code que nous avons déjà écrit */
  3.  
  4.     /** ETAPE 1 **/
  5.     // create a group to put the title assets in
  6.     // so they can be manipulated as a whole
  7.     this.titleGroup = this.game.add.group();
  8.  
  9.     /** ETAPE 2 **/
  10.     // create the title sprite
  11.     // and add it to the group
  12.     this.title = this.game.add.sprite(0,0,'title');
  13.     this.titleGroup.add(this.title);
  14.  
  15.     /** ETAPE 3 **/
  16.     // create the bird sprite
  17.     // and add it to the title group
  18.     this.bird = this.game.add.sprite(200,5,'bird');
  19.     this.titleGroup.add(this.bird);
  20.  
  21.     /** ETAPE 4 **/
  22.     // add an animation to the bird
  23.     // and begin the animation
  24.     this.bird.animations.add('flap');
  25.     this.bird.animations.play('flap', 12, true);
  26.  
  27.     /** ETAPE 5 **/
  28.     // Set the originating location of the group
  29.     this.titleGroup.x = 30;
  30.     this.titleGroup.y = 0;
  31.  
  32.     /** ETAPE 6 **/
  33.     // create an oscillating animation tween for the group
  34.     this.game.add.tween(this.titleGroup).to({y:115}, 350, Phaser.Easing.Linear.NONE, true, 0, 1000, true);

Télécharger

Les explications sur ce qui se passe dans ce pavé

Bon, nous allons procéder étapes par étapes. Nous allons parler du code que nous avons écrit... enfin, copié-collé... Bref, nbous allons parlé de ce pavé de code à la fois en ce qui concerne notre jeu et aussi d’une façon générale...

Etape 1 : Créer un groupe pour pour y mettre notre titre et notre oiseau, ce sera le groupe "title"

Notre code :

  1. this.titleGroup = this.game.add.group();

Cette ligne créait un nouveau groupe dans le jeu auquel nous allons nous référer plus tard.

Qu’est ce qu’un groupe ?

Les groupes, dans Phaser, sont généralement utilisés pour placer un ensemble de sprites comme des tirs ou des ennemis. Les groupes sont puissants, chacun des sprites attachés à un groupe peut être facilement manipulé. Tous ont une méthode pour les manipuler en même temps. On peut ainsi changer leurs propriétés ou bien les faire bouger ensemble.

Créer le sprite du titre et l’ajouter au groupe "title"

  1. this.title = this.game.add.sprite(0,0,'title');  
  2. this.titleGroup.add(this.title);

Télécharger

Nous créons le sprite "title" en utilisant la syntaxe vue auparavant et, à la ligne suivante, nous ajoutons ce sprite au groupe ’title". Facile, non ?

Etape 3 : Créer le sprite de l’oiseau et l’ajouter au groupe "title"

  1. this.bird = this.game.add.sprite(200,5,'bird');  
  2. this.titleGroup.add(this.bird);

Télécharger

Comme l’étape précédente, sauf que nous créons le sprite ’bird’.

Etape 4 : Ajouter une animation à l’oiseau en utilisant un spritesheet et commencer à jouer avec l’animation

  1. this.bird.animations.add('flap');  
  2. this.bird.animations.play('flap', 12, true);  

Télécharger

Tiens, quelque chose de nouveau ! Cool...

Simple SpriteSheet Animations

Quand on a un sprite dont la texture est un sprite sheet ( plusieurs images dans un seul fichier ), on peut facilement ajouter une animation à ce sprite en utilisant le "AnimationManager" de sprite de Phaser.. Celui-ci peut être accéder via l’objet animation du sprite. Nous créons une animation simple pour le moment. Si notre spritesheet comportait beaucoup plus d’images ( ou de frames ) et d’animations ( disont pour marcher, courir, sauter ect ), nous pourrions faire des animations beaucoup plus complexe. Mais il s’agit là d’un autre tutoriel.En fait, notre code est plutôt simple. Voyons le ligne par ligne :

  1. sprite.animations.add(animationKey);

Ce code dit à l’objet AnimationManager du sprite d’utiliser toutes les frames du sprite sheet pour créer une animation identifier par animationKey

  1. sprite.animations.play(animationKey, frameRate, loop);

Ce code dit à l’objet AnimationManager du sprite de de commencer à jouer l’animation identifier par animationKey au frameRate voulue ( Nombre de frame par seconde ). Si loop est à true, l’animation boucle sur elle même indéfiniement ou jusque sprite.animations.stop() soit appelé.

Revoyons maintenant notre code :

  1. this.bird.animations.add('flap');  
  2. this.bird.animations.play('flap', 12, true);

Télécharger

  1. Nous disons au AnimationManager du sprite bird d’utiliser toutes les frames disponible dans le sprite sheet de ce sprite pour pour créer une nouvelle animation appelée « flap »
  2. Nous disons au AnimationManager du sprite bird de commencer à jouer l’animation « flap » avec une cadence de 12 frames par seconde et boucler indéfiniment.

Placer le groupe

  1. this.titleGroup.x = 30;  
  2. this.titleGroup.y = 100;

Télécharger

Nous avons créé nos sprites à (0,0) (200,5) respectivement puis ajouté au groupe « title ». Si nous n’avions pas réglé la position du groupe nous aurions quelque chose comme ça à l’écran :

Cependant, lorsque nous changeons l’emplacement d’un groupe, tous les sprites contenus à l’intérieur sont aussi déplacés. Du coup, lorsque nous réglons l’emplacement du groupe « title » à (30,100), nous pouvons tous les sprites qu’il contient 30 pixel vers la gauche et 100 pixels vers le bas. Faites le à l’étape 6 et sauvegarder votre fichier. Maintenant, vous devriez voir quelque chose comme :

Magnifique non ?

Ajouter une interpolation de mouvement ou tween au groupe pour que tout son contenu oscille en même temps

Qu’est qu’un tween ?

Un tween est une interpolation de mouvement. C’est une animation créée en spécifiant plusieurs valeurs pour les propriétés de mouvement d’un objet dans le temps. Le terme interpolation (« tween » en anglais) est la contraction de l’anglais « in between » qui signifie « au milieu » ou « dans l’intervalle ».

  1. this.game.add.tween(this.titleGroup).to({y:115}, 350, Phaser.Easing.Linear.NONE, true, 0, 1000, true);  

Cette seule ligne fait beaucoup. Regardons la d’une manière plus générique pour mieux la comprendre :

  1. this.game.add.tween(object).to(properties, duration, ease, autoStart, delay, repeat, yoyo);  
  • object : L’objet à tweener. Cela peut être un sprite, un groupe ou n’importe quel objet du jeu
  • properties : un objet représentant le tween.
  • duration : Combien de temps prend chaque itération du tween en millisecondes
  • ease : Le type de mouvement à utiliser ( Voir les fonctions Phaser.Easing disponibles )
  • autoStart : Pour démarrer automatiquement ou pas le tween
  • delay : Le temps d’attente en millisecondes avant de comencer le tween
  • repeat : Combien de fois répéter le tween.
  • yoyo : Jouer le tween à l’envers ou pas lorsqu’une itération est finie

Il y a pas mal de documentation sur les tweens. Je vous suggère d’y jeter un oeil sur cette page à un moment ou à un autre...

Bon, retournons à nos moutons ! A notre zoziô avec son titre devrais-je dire !

  1. this.game.add.tween(this.titleGroup).to({y:115}, 350, Phaser.Easing.Linear.NONE, true, 0, 1000, true);  

La liste des propriétés ressemble à ça :

  • object : this.titleGroup
  • properties : y : 115
  • duration : 350
  • ease : Phaser.Easing.Linear.NONE
  • autoStart : true
  • delay : 0
  • repeat : 1000
  • yoyo : true
Ce que l’on pourrait traduire en français par :

Bouge le groupe « title » vers une position "y" de 115 pixels du haut de l’écran sur une durée de 350 millisecondes sans flottements. Démarrer le tween dés qu’il est définit et sans délai. Le répèter 1000 fois et le faire en « avant » puis en « arrier ».

Et bhé... Voilà ! Si vous avez fait cela sans sauvegarder et sans prévisualisation, châpeau bas !

Quoiqu’il en soit, sauvegarder et aller voir votre jeu sur le navigateur. Vous devriez être récompensé en voyons cela :

La première interaction !

Ouais, super ! On a un menu avec des trucs qui bougent !!! Mais... Heu, il est où le bouton pour démarrer le jeu ?

Ajouter le bouton

Encore une fois de plus, nous allons utiliser la méthode create du fichier game/states/menu.js. Sous le code saisie précédement, nous allons ajouter les lignes suivantes :

  1. // add our start button with a callback
  2. this.startButton = this.game.add.button(this.game.width/2, 300, 'startButton', this.startClick, this);
  3. this.startButton.anchor.setTo(0.5,0.5);

Télécharger

Le code suivant lui ressemble beaucoup à l’exception des deux derniers arguments.

  1. var button = this.game.add.button(x, y, key, callback, callbackContext);  

Exactement comme nous appelons un game.add.sprite, nous fournisons un x et un y pour les coordonnées et une key ou identifiant qui appelle une image préchargée. Cependant, nous devons aussi spécifier une méthode de callback à lancer lorsque l’on interagis avec le bouton. Et un callbackContext dans lequel le callback opère.

Que sont les Callbacks et les callbacksContexts ?

Un callback est une fonction de retour. Il s’agit d’une fonction comme les autres. Sa particularité est qu’elle est appelée par une autre qui l’a reçu en tant que paramètre.

Chaque fonction de Phaser qui a un callback a aussi un paramètre de contexte de callback. Si vous ne passez pas ce paramètre, il sera considéré comme null. D’une manière générale, vous mettrez comme contexte de callback this, comme nous voulons que nos callbacks opèrent à l’intérieur d’un contexte auquel nous pouvons accéder. Et ce, depuis tous les objets de notre jeu.

Vous noterez également que comme paramètres pour x, nous n’avons pas passé un chiffre, mais une formule magique avec laquelle nous allons devenir familier...

  1. var centerX = this.game.width/2;  
  2. var centerY = this.game.height/2;  

Télécharger

Cela nous donne le centre dans nos axes x et y.

Il y a aussi la ligne suivante :

  1. this.startButton.anchor.setTo(0.5,0.5);  

Nous utilisons cette ligne de code pour mettre l’ancre ( anchor ) de notre bouton en son centre. Parce que nous plaçons le bouton initialement à game.width/2, 300, le bouton devrait apparaître directement centré dans l’axe des x et 300 pixels moins la moitié de sa hauteur dans l’axe des y.

Qu’est qu’une ancre ( anchor )

L’ancre d’un sprite est la position, à l’intérieur du sprite, que Phaser utilise comme point de référence pour ce sprite. Cela signifie que lorsque vous positionnez un sprite, se sera selon son ancre et la texture du sprite sera affichée autour de cette ancre. Lorsque l’on créait un sprite, son ancre et a (0,0) ce qui signifie que le sprite sera positionné selon son coin en haut à gauche. Régler l’ancre à (0.5,0.5) signifie que le sprite sera positionné selon son centre.

Regardez cela :

Le bouton avec l’ancre par défaut à (0,0)

Avec l’ancre à (0.5,0.5)

L’ancre est aussi le point autour duquel pivote le sprite. Ce qui signifie qu’avec l’ancre par défaut, le sprite tournouaillerait ainsi :

Mais, si vous réglez l’ancre à (0.5, 0.5), c’est beaucoup mieux :

Voilà pour les ancres ( anchors ).

Une nouvelle méthode

Sous la méthode create, nous allons ajouter une nouvelle méthode appelée startClick avec le code suivant :

  1. create: function() {  
  2.     /* The code we've already written */
  3. },
  4. startClick: function() {  
  5.     // start button click handler
  6.     // start the 'play' state
  7.     this.game.state.start('play');
  8. },

Télécharger

Cette méthode fait une seule et unique chose ! Elle appelle game.state.start(). La méthode appelée prend seulement un paramètre : une chaîne de caractère qui représente le nom de l’état à démarrer. Dans ce cas, nous allons démarrer l’état play qui va contenir notre jeu en lui-même !

Qu’est ce qu’un état ( State )

Un état est une partie, un écran ou une séquence du jeu. Dans notre cas, lorsque nous aurons fini notre jeu, nous aurons 5 états : l’amorçage ( The Boot State ), le préchargement ( The Loading Screen State ), Le menu ( The Menu Screen State ), le jeu en lui-même ( The Play Screen State ) et l’écran final ( The Game Over Screen State ). Jusque maintenant, nous avons seulement parlé de l’écran du menu. et un peu du préchargement.

Comment ?
Le générateur l’a fait pour nous ! Et de ce fait, nous avons passé la création des états... Si vous ouvrez game/main.js, vous devriez voir :

  1. 'use strict';
  2.  
  3. //global variables
  4. window.onload = function () {
  5.   var game = new Phaser.Game(288, 505, Phaser.AUTO, 'flappy-bird-reborn');
  6.  
  7.   // Game States
  8.   game.state.add('boot', require('./states/boot'));
  9.   game.state.add('gameover', require('./states/gameover'));
  10.   game.state.add('menu', require('./states/menu'));
  11.   game.state.add('play', require('./states/play'));
  12.   game.state.add('preload', require('./states/preload'));
  13.  
  14.  
  15.   game.state.start('boot');
  16. };

Télécharger

Le générateur créait pour nous ce fichier. Et, encore plus magique, le recréé à chaque fois que l’on ajoute un nouvel état... La chose importante à comprendre ici est ce que fait ce code :

  1. game.state.add(key, Phaser.State);

Comme le chargeur, le StateManager du jeu vous permet d’ajouter un état avec une key ou identifiant pour pouvoir y accéder. Et un Phaser.State qui représente l’état lui-même. Chacun des états à des méthodes hérités que Phaser reconnait automatiquement et sais appeler au bon moment durant le cycle du jeu et en fait, vous avez déjà vous quelques uns d’entre eux ( preload,create,update ).

Au bas de game/states/menu.js, il y a une ligne de code :

  1. module.exports = Menu;

Parce que nous utilisons Browersifyt pour définir les modules et require() les dépendances, module.exports dit à Browserify quoi retourner quand ce fichier est appelé. dans ce cas, nous disons à notre module d’exporter l’objet Menu contient tout le code que nous venons d’écrire pour cet état ( state ).

Parce que le générateur a créé les lignes suivantes dans game/main.js pour nous :

  1. var MenuState = require('./states/menu');  
  2. ...
  3. game.state.add('menu', MenuState);

Télécharger

le StateManager du jeu saura quoi faire avec le code que nous avons écrit dans game/states/menu.js quand l’état « menu » est joué.

Tout ensemble

Et nous voici proche de la fin de cette première partie... Sauvegarder votre code et regardez la fenêtre de votre navigateur. Vous devriez y voir ceci :

Cliquez sur le bouton ’Start’ devrez vous amener directement à l’état play. Pour le moment, vous ne verrez d’un carré au contour vert aller et venir... Nous amélioreront cela bientôt !

Votre code devrez ressembler à celui que vous trouverez sur cette page.

Vous avez aimé ? Partager !

Twitter Facebook Google Plus Tumblr Linkedin
Cet article à 5 articles connexes :