• Variables, fonctions, syntaxe
• Objets, méthodes, propriétés…
• Clics et événements souris sur les boutons et les clips
• Champs texte et objet String
• Structures de contrôle alternatives : if
• MovieClip : manipuler (ici)
• Structures de contrôle alternatives : switch
• Structures de contrôle répétitives : for - while
• Liste d'affichage, imbrication et profondeur des objets
• Liste d'affichage, gestion dynamique des objets
• Les tableaux
Manipuler un MovieClip
L'objet phare, la vedette de Flash, c'est le clip, c'est donc par là que nous allons attaquer les choses vraiment sérieuses (ou rigolotes c'est selon l'état d'esprit).
Un clip, quand on parle vite, c'est une instance d'un symbole de bibliothèque de type Clip.
Dans un premier temps on va manipuler des instances (occurrences) de symbole déjà présentes sur la scène, on verra plus tard comment les ajouter en cours d'exécution (à la volée) - on dit dynamiquement.
Fabriquons donc un symbole de type Clip, animé - puisque c'est LA caractéristique principale de ces objets.
Tiens on va faire un ballon qui vole (ou une soucoupe volante pour les garçons ) :
Une instance de graphique Gr_Ballon animée sur un guide mouvement (pour CS3 et comme vous voulez après).
On en glisse une occurrences sur la scène et nous voilà prêts à tester les principales méthodes et propriétés1) des objets de type MovieClip.

Manipuler la tête de lecture
Les méthodes caractéristiques de la classe MovieClip vous les connaissez certainement - au moins de réputation - ce sont celles qui permettent de manipuler la tête de lecture, et quand je disais tout à l'heure un peu vite que la caractéristique principale des MovieClip c'est d'être animés, en parler correct c'est : d'avoir plusieurs images3) et une tête de lecture… qu'on peut piloter, donc.
stop, play, gotoAndStop et gotoAndPlay
Ça, on a déjà vu et même pris de l'avance avec l'exercice du skieur.
Je résume tout de même :
stop
arrête la tête de lecture du clip considéré là ou elle se trouve ; play
démarre la lecture depuis l'image courante (actuellement affichée).
Par exemple pour arrêter la course du ballon en cliquant dessus…
Deux possibilités :
• Soit vous nommez l'instance (disons leBallon
pour faire original) et, sur le calque dédié au code du scénario principal4), vous lui associez un écouteur :
leBallon.addEventListener(MouseEvent.MOUSE_DOWN,qdClicBallon); function qdClicBallon(me:MouseEvent):void { me.currentTarget.stop(); }
• Soit vous décidez d'écrire ce bout de code dans le clip lui même image 1 d'un calque dédié.
this.addEventListener(MouseEvent.MOUSE_DOWN,explose); function explose(me:MouseEvent):void { this.stop(); }
Ici, avec un seul clip, c'est la première option la meilleure : on a tout le code sous les yeux en ouvrant le .fla, mais vous verrez que quelquefois l'option 'code dans le clip' se révèle bien utile
gotoAndStop envoie la tête de lecture à une image considérée, sans lire les autres, la tête de lecture “saute” jusqu'à l'image et y reste ; gotoAndPlay lit depuis l'image en question.
On précise le numéro d'image entre parenthèses comme illustré là bas, mais on peut aussi préciser une étiquette d'image en passant une chaîne.
Les étiquettes d'image
Pour poser une étiquette d'image il suffit de sélectionner une image clé5) dans le scénario du clip considéré et de saisir un nom dans le champ Nom
du panneau Propriétés.
Il vous suffira par la suite de “passer” ce nom, entre guillemets, à un gotoAnd… pour y envoyer la tête de lecture :
leClip.gotoAnStop("uneEtiquette"); //ou //leClip.gotoAnPlay("uneEtiquette");
Par exemple, sauriez vous faire un ballon qui explose quand on clique dessus ?
Ce n'est qu'une ruse de construction et du code qu'on connait, n'allez pas chercher midi à quatorze heure…
Jusqu'alors on avait un clip (Mv_BallonVole) qui animait un graphique nommé ballon
(instance de Gr_Ballon) sur une guide mouvement. Il vous suffit de remplacer cette instance (bouton Permuter du panneau Propriétés) par un clip présentant image 1 le visuel du ballon et, plus loin, une animation figurant l'explosion à partir d'une image quelconque que vous aurez pris soin de repérer à l'aide d'une étiquette d'image (“paf”, par exemple).
Un clic sur l'instance de Mv_BallonVole, en arrête la tête de lecture et envoie celle du clip contenu lire depuis l'étiquette “explose” (gotoAndPlay).
Prenez soin, si vous avez procédé par permutation, de régler le type sur “Clip” dans le panneau Propriétés.
Toujours les deux mêmes possibilités :
Sur la première image de Mv_BallonVole :
this.addEventListener(MouseEvent.MOUSE_DOWN,explose); function explose(me:MouseEvent):void { this.stop(); this.removeEventListener(MouseEvent.MOUSE_DOWN,explose);// plus besoin de l'écouteur on le supprime this.ballon.gotoAndPlay("paf"); }
Sur la première image du scénario principal :
leBallon.addEventListener(MouseEvent.MOUSE_DOWN,explose); function explose(me:MouseEvent):void { me.currentTarget.stop(); me.currentTarget.removeEventListener(MouseEvent.MOUSE_DOWN,explose);// plus besoin de l'écouteur on le supprime me.currentTarget.ballon.gotoAndPlay("paf"); }
nextFrame et prevFrame
Comme leur nom l'indique, nextFrame
et prevFrame
, permettent d'envoyer la tête de lecture, respectivement, image suivante ou image précédente. On pourrait par exemple fabriquer cette toute petite chose (aussi, ça nous permettra de tester d'autres propriétés par la suite).
Il s'agit d'un bête clip avec une poignée d'images clés, sur chacune d'elle une illustration différente. Quand on clique, l'image suivante est affichée (la tête de lecture se déplace vers l'avant), si on clique avec la touche majuscule enfoncée c'est l'image précédente qui est affichée (tête de lecture recule d'une image).
C'est une bonne occasion de réviser les propriétés du paramètre de la fonction de rappel ainsi que l'emploi de la structure if
nextFrame
sur la dernière image, ou prevFrame
sur la première… Rien ne se passe, c'est tout.
Et pour ceux qui se demandent comment faire changer le pointeur en main, tant pis si ce n'est pas le chapitre je le dis quand même : c'est la propriété buttonMode
valorisée à true
qui produit ça.
demo.buttonMode=true;
Je vous laisse trouver, et si vous séchez vous trouverez le code à l'occasion du chapitre suivant.
Les propriétés bien utiles de MovieClip
Puisqu'on peut déplacer la tête lecture sur des images de son choix selon leur numéro ou leur nom d'étiquette, voici une poignée de propriétés auxquelles vous aurez souvent recours dès qu'il s'agira de “se” déplacer sur un scénario.
currentFrame et totalFrame
Ces deux propriétés renvoient un int qui vaut pour
currentFrame
le numéro de l'image en cours de lecture, celle sur laquelle se trouve la tête de lecture à l'instant considéré,
totalFrame
le nombre d'images du clip en question.
Vous pouvez tester en ajoutant deux traces au code que vous venez d'écrire à l'occasion de l'exercice du dessus :
demo.stop(); demo.addEventListener(MouseEvent.CLICK,qdClic); demo.buttonMode = true; // pointeur en forme de main au survol function qdClic(me:MouseEvent) { if (me.shiftKey) { // touche majuscule du clavier enfoncée me.currentTarget.prevFrame();// reculer d'une image } else { me.currentTarget.nextFrame();// avancer d'une image } trace("image courante : "+me.currentTarget.currentFrame); trace("nombre d'images du clip : "+me.currentTarget.totalFrames); }
Exercices
Défiler et boucler
Histoire d'illustrer l'utilisation de ces deux propriétés, je vous propose la consigne suivante avec le toujours même clip aux bestioles (ou une autre instance, si ça vous arrange) : quand on clique, on passe à l'image suivante et on revient à la première après la dernière. En gros, ça boucle.
Bien sûr le code doit fonctionner quelque soit le nombre d'images du clip sans qu'on ait à le modifier, et pour corser la chose - sans quoi c'est trop facile - j'ajoute la contrainte de ne pas utiliser de if.
En fait il s'agit d'une seule ligne un peu rusée, mais vous avez déjà rencontré tout ce qu'il faut pour faire
• Il y a peut-être un piège… Ce n'est pas parce qu'on vient de voir
nextFrame
et prevFrame
qu'il faut forcément vous jeter dessus ^^• Parmi les opérateurs mathématiques il y en a un qu'on a tort de négliger.
Tout petit jeu
Ici ce swf illustre la consigne toute entière : vous savez faire en sorte que la partie démarre ou reprenne via majuscule-clic.

C'est une cas de figure où on peut trouver préférable d'écrire le code “dans” le symbole, plutôt qu'associer un écouteur à chaque instance.
this.addEventListener(MouseEvent.MOUSE_DOWN,explose); function explose(me:MouseEvent):void { this.stop(); this.removeEventListener(MouseEvent.MOUSE_DOWN,explose); ballon.gotoAndPlay("paf"); }
currentFrameLabel et currentLabel
En ce qui concerne ces deux propriétés, je ne peux que vous renvoyer à la doc et attirer votre attention sur le fait qu'elles ne sont disponibles que pour lecteurs 10 et supérieurs.
Si l'explication vous reste confuse faites le test suivant :
image 1 : stop()
image 2 : une étiquette : “etiquette image 2”
image 5 : une étiquette : “etiquette image 5”
un bouton sur la scène et ce code associé :
bt.addEventListener(MouseEvent.CLICK,qdClic); function qdClic(me:MouseEvent) { nextFrame(); trace("currentFrame : "+this.currentFrame); trace("currentFrameLabel : "+this.currentFrameLabel); trace("currentFrame : "+this.currentLabel); trace("---"); }
currentFrame : 2 currentFrameLabel : etiquette image 2 currentFrame : etiquette image 2 --- currentFrame : 3 currentFrameLabel : null currentFrame : etiquette image 2 --- currentFrame : 4 currentFrameLabel : null currentFrame : etiquette image 2 --- currentFrame : 5 currentFrameLabel : etiquette image 5 currentFrame : etiquette image 5 --- currentFrame : 6 currentFrameLabel : null currentFrame : etiquette image 5 ---
Retrouver une instance par son nom : getChildByName
Vous le savez, quand on veut (s') adresser (à) un clip posé sur l'animation, on utilise le nom de l'instance tout bonnement (leClip.play();
par exemple).
La question qui se pose maintenant c'est comment faire quand on dispose d'une chaine de caractère, pour, par exemple, piloter ballon1 ou ballon2 en reconstituant le nom depuis une variable qui vaudrait le suffixe (le chiffre).
Il ne vous viendrait pas à l'esprit d'écrire :
var suffixe:int=1 var leBallon:String="ballon"+suffixe leBallon.play(); // Aïe !! depuis quand la classe String expose-t-elle une méthode play ? O.O
C'est la méthode getChildByName
qui renvoie l'objet d'affichage (DisplayObject) correspondant à une chaîne.
var suffixe:int=1 trace(getChildByName("ballon"+suffixe)) trace(getChildByName("ballon"+suffixe).name)
[object Mv_BallonVole] ballon1
Erreurs 1118 et 1061
Je viens d'illustrer la méthode getChildByName dans un trace et en utilisant la propriété name, si de votre côté vous vous y êtes essayé avec un play ou un stop vous voilà confronté à l'erreur 1118 ou 1061, très célèbres sur le forum
C'est le moment de tirer l'embrouille au clair.
Voilà ce qu'on obtient si on a une instance nommée leBallon
et qu'on a le front d'écrire :
getChildByName("leBallon").play();
Si vous essayez de passer par une variable, c'est pas mieux :
var b:MovieClip= getChildByName("leBallon");
Chaque fois il est question de DisplayObject… De fait si vous consultez la doc, vous constatez que getChildByName renvoie du DisplayObject.
“Euhh… oui et alors”, grommèle le Ronchon de service.
Eh bien, c'est là qu'il devient nécessaire de comprendre l'arbre d'héritage des classes d'affichage.
Reprenons :
Quand on code en AS3 on utilise des objets - puisque tout est Objet - et il existe des objets de genre différent : clips, boutons, images bitmap, sons…
On sait que tous les objets d'un même genre s'utilisent pareil. Je veux dire, on leur applique les mêmes méthodes ou propriétés et - partageant les mêmes caractéristiques et compétences6) - on les classe dans la même catégorie.
Eh bien voilà, le mot est lâché, les objets qui ont le même “mode d'emploi”, sont classés dans la même catégorie qu'on appelle classe.
Attention, une classe c'est plus qu'une catégorie, qu'une étiquette pour identifier un objet, c'est aussi ce qui permet de fabriquer les objets en question. Une classe c'est à la fois un “genre” (on dit type vous vous souvenez) et une usine, une fabrique, un moule…
Les objets de même type sont issus de la même classe (au sens où ils sont fabriqués par la même classe).
La classe d'un objet c'est à la fois la catégorie dans laquelle le “ranger” et le moule qui permet de le fabriquer.
Ce qui est pratique, c'est que les classes héritent les unes des autres et voilà comment ça peut se comprendre vite fait pour ce qui nous intéresse (la POO c'est l'objet d'un autre tuto) :
Ça fonctionne un peu comme dans la vraie vie : il y a des parents et des enfants ; en fait des mères et des filles - puisqu'on parle de classes - et les filles héritent de leur mère, génétiquement pour les humains, “codesquement” pour les classes.
Comme dans la vie biologique les filles héritent de leur mère certaines caractéristiques et compétences et y ajoutent des facultés propres. Ma fille, par exemple, a hérité de mon caractère et de la couleur de mes yeux, mais en plus elle est sportive (caractéristique qui me fait parfaitement défaut ). En AS3 c'est pareil si ce n'est qu'il est question de propriétés et de méthodes.
L'arbre d'héritage des classes d'affichage
Les classes qui nous intéressent ici, ce sont les classes des objets affichables7).
D'un point de vue AS3 voilà comment se présente l'arbre généalogique d'héritage des classes d'affichage :
Souvent pour aller vite on opère un glissement sémantique qui nous fait parler de l'objet issu d'une classe en utilisant le nom de la classe elle même. Comme lorsqu'on dit boire un verre ou manger un cornet de frites. Ce n'est pas le verre qu'on boit (mâche ?

• L'aïeule c'est DisplayObject, qui est la classe dont héritent tous les objets affichables, qu'il s'agisse d'une image (Bitmap), d'un objet de dessin (Shape), d'instances de symboles (Sprite, SimpleButton, MovieClip), ou même de chargeurs d'images externes (Loader), de vidéos (Video) ou encore de champs texte (TextField).
Si vous consultez la doc vous trouverez toutes les méthodes et propriétés qui s'appliquent aux objets d'affichage quels qu'ils soient. name
, par exemple, ou encore x et y8)
• Ensuite il y a les enfants de DisplayObject, au nombre des quels les objets interactifs (InteractiveObject), qui non contents d'être affichables, d'avoir des coordonnées et tout ce qu'on sait, permettent l'interaction. Dit autrement, ils diffusent les célèbres “événements souris” : MouseEvent
• Les enfants des objets interactifs sont les boutons, les champ texte, et les objets d'affichage pouvant en contenir d'autres (DisplayObjectContainer).
• Héritant de DisplayObjectContainer, vous trouvez la classe Loader (pour charger des fichiers image), la classe Sprite (une seule image donc pas de scénario) et la classe Stage (la scène, qui pour le coup est un conteneur).
• Enfin, tout en bas de l'arbre d'héritage, l'objet le plus aboutis de l'évolution : le (fameux) MovieClip qui est donc : un objet d'affichage avec toutes ses méthodes et propriétés, interactif, pouvant en contenir d'autres, et équipé d'un scénario.
Pour reprendre ma métaphore familiale, ça dit de qui l'enfant en question “tient” ses caractéristiques (il a le don de la musique de sa grand mère, la main verte de sa bisaïeule mais ses talents de cuisiniers il ne les doit qu'à lui).
cliquer pour grossir
Certaines classes (type d'objets) ne sont pas instanciables, comprendre elles ne peuvent pas générer un objet (via le mot clé new, on y arrive très bientôt), je ne vais pas pouvoir fabriquer un objet de type DisplayObjet “tout court”. Ces classes n'existent que pour transmettre à leur descendance les méthodes et propriétés qui leurs seront communes.
Ici j'ai développé MovieClip, depuis flash/DisplayObject :

Oui, bon, ronchonne le toujours même, et quel rapport avec l'erreur ?
J'y viens :
Une dernière chose à savoir en ce qui concerne l'héritage, c'est que puisque les enfants savent faire tout comme leurs parent et mieux, partout où on attend la mère on peut envoyer la fille9) (puisqu'elle sait assurément faire la même chose que sa mère).
Quand on dit de la méthode getChildByName qu'elle renvoie un objet de type DisplayObject, il faut comprendre “au minimum”.
Dans notre exemple, on reçoit un clip, c'est bien un DisplayObject (par ascendance), mais on tente d'utiliser la méthode play, qui n'est pas une méthode de la classe en question, le compilateur lui, n'en sait rien si c'est un clip ou un loader ou un TextField ou n'importe quel autre objet d'affichage, et il râle que la méthode play n'existe pas (peut-être non définie), via la la classe DisplayObject, normal.
Oui mais voilà, nous, dans ce contexte, parce que c'est nous humains qui programmons, on le sait que “leBallon” c'est un clip. On en est sûr, là, voilà !
On va donc “rassurer Flash”, lui dire “écoute gars, je suis sûre de mon coup, cet objet que je reçois est un MovieClip”.
En langage Objet on dit qu'on transtype (par delà le type) et on s'y prend comme suit :
MovieClip(getChildByName("leBallon")).play(); // Ou : var ballon:MovieClip=MovieClip(getChildByName("leBallon")); ballon.play();
Et du coup vous comprenez pourquoi l'exemple que j'avais pris avec la propriété name fonctionnait, lui. Eh oui, name
est une propriété de la classe DisplayObject10).
Exercice
Maintenant que vous savez piloter la tête de lecture d'une instance dont vous connaissez le nom, vous pouvez sans doute, armés de vos récentes connaissances sur les champs texte, lâcher le ballon de votre choix…
Conclusion (provisoire)
Vous l'avez constaté : il existe encore nombre de méthodes et propriétés, dont certaines absolument primordiales. On va les voir, mais pas tout de suite.
Ce n'est pas que je tienne à ménager un suspens insoutenable c'est que pour en comprendre au mieux l'intérêt et la mise en œuvre on va avoir besoin de quelques billes supplémentaires, à commencer par les structures de contrôle répétitives (les boucles).
Et c'est par là [lien à venir] que ça se passe…
A tout de suite, donc !


