enchant.js - 2e partie
Rédigé par Fred - - Aucun commentaire
Voyons maintenant les Scene
d’un peu plus près. Encore une fois,
récupérez les exemples ici pour ne pas avoir à recopier.
Comme dit dans l’introduction, les scènes ne sont pas obligatoires.
les instances de Game
ont une rootScene
créée par défaut. Par
contre, elles sont bien utiles si on veut : faire des menus, mettre
une animation, passer d’une séquence de jeu à une autre.
Dans le premier exemple, on va simuler l’apparition du menu (déclenchée normalement par l’appui d’une touche ou d’une icône). Toutes les 5 frames, on va :
- faire apparaître la première scène ;
- faire apparaître le menu ;
- faire apparaître la scène 2 avec l’option 1 ;
- faire disparaître la scène 2 ;
- faire disparaître la scène 1 ;
- arrêter le jeu.
Comment on fait ça n’est pas très important. Ce qu’il faut voir c’est que :
- À la frame 5, on ajoute la première scène avec
game.pushScene(scene1);
. En faisant cela, bien que cette scène soit vide, on voit que le compteur de frames s’arrête : on ne peut pas avoir plusieurs scènes d’affichées en même temps. On a une pile, et seule la scène du haut de la pile est « active ». - Pour enlever une scène du haut de la pile, on l’enlève avec
game.popScene()
. - Pour enlever une scène où qu’elle soit dans la pile, on utilise
game.removeScene(scene2)
. - Une fois qu’on a enlevé nos deux scènes, on voit que le nombre de frames a continué de défilé, en arrière plan. On s’est arrêté à « 5 6 6 » et on repart à « 25 6 26 ». Le numéro de frame étant le premier nombre :
label.text = game.frame+" "+game.rootScene.age+" "+someInt;
On va voir dans un instant le pourquoi des autres nombres.
Il faut également noter qu’une scène ne peut être présente qu’une
seule fois dans la pile : si on a [rootScene, scene1, scene2]
et que
l’on fait un pushScene(scene1)
, on se retrouvera avec [rootScene,
scene2, scene1]
.
Dans le second exemple, on est dans la configuration suivante :
[rootScene, scene1, scene2]
, puis on fait un removeScene(scene1)
suivi d’un popScene()
. On a donc la pile qui passe à [rootScene,
scene2]
, puis à [rootScene]
.
On peut également remplacer la scène du dessus de la pile par une
autre : avec [rootScene, scene2]
, si on fait un
replaceScene(scene1)
, on se retrouve avec [rootScene, scene1]
.
On termine également en faisant un popScene
sur la rootScene
pour
constater que non, elle ne disparaît pas.
Pour terminer, on va parler un peu de ces
addEventListener('enterframe',function() {
. Mais avant de commencer,
on va parler des attributs age
. Pour la plupart des objets qu’on
manipulera, les instances ont une variable age
qui est plus ou moins
le nombre de frames pendant lesquelles l’objet a été affiché.
Le déroulement du premier exemple est donc le suivant.
game.frame | rootScene.age | scene1.age | chose1.age | scene2.age | |
0 | 1 | ||||
↓ | ↓ | ||||
game.pushScene(scene1) | 5 | 6 | 1 | ||
↓ | [en pause à cause de scene1] | ↓ | |||
scene1.addChild(chose1) | 9 | 6 | 5 | 1 | |
↓ | ↓ | ↓ | |||
game.pushScene(scene2) | 15 | 6 | 11 | 6 | 1 |
↓ | [en pause à cause de scene2] | [idem] | ↓ | ||
game.removeScene(scene2) | 20 | 6 | 11 | 6 | 5 |
↓ | ↓ | ↓ | [plus dans la pile] | ||
game.popScene() | 24 | 6 | 15 | 10 | 5 |
↓ | ↓ | [plus dans la pile] | [idem] | ||
game.stop() | 30 | 11 | 15 | 10 | 5 |
On peut donc gérer l’apparition des éléments suivant le numéro de
frame — c’est le cas de scene2
— ou suivant l’âge d’un élément
— c’est le cas de scene1
.
J’espère que ce tableau permet de mieux comprendre les deux premières
valeurs affichées dans le label : game.frame
et
game.rootScene.age
.
Ça n’est pas plus compliqué pour la dernière valeur, someInt
. Vous
pouvez constater que dans le second exemple, la variable someInt
croît en même temps que l’âge de la rootScene
contrairement au
premier exemple.
C’est parce que dans le premier cas, j’ai mis l’incrémentation dans
game.addEventListener('enterframe',function() {
et dans le second,
dans game.rootScene.addEventListener('enterframe',function() {
.
Dans l’introduction, j’ai brièvement parlé des changements d’états et
des événements. Pour chaque frame affichée, un événement ENTER_FRAME
est émis. Du coup, tous les objets qui ont un écouteur (listener)
d’événements pour l’entrée dans une frame auront du code exécuté au
début de chaque frame.
Dans le premier exemple, c’est game
qui écoute ; comme il est
présent dans chaque frame, someInt
croît à chaque frame. Dans le
second exemple, c’est la rootScene
qui écoute ; comme elle n’est pas
affichée quand il y a d’autres scènes dans la pile, someInt
ne
grandit plus.
Vous aurez également noté que les label
sont personnalisables
(polices, couleurs, taille, alignement). Plutôt que d’utiliser la
console, j’utiliserai souvent ces labels pour faire afficher des
informations. Je ne les présenterai pas, mais ce deuxième exemple
permet de savoir tout ce qu’il faut sur eux.
C’est tout pour le moment. La prochaine fois, ce sera un peu plus ludique ; on va jouer avec des images.