addFrame – Code-moi une Timeline en AS3

Ce tutorial à pour but d’expliquer comment créer une Timeline en AS3, soit plusieurs images en root de l’application sans utiliser Flash. Mais uniquement par code avec le compilateur mxmlc.exe fournit avec le Flex SDK.

Approche de conception d’une application

Il existe deux types de créateurs de sites Web, il y a ceux qui divisent leur application en une série de SWF autonomes, qui les chargent ensuite dans un SWF principal et le tout étant propulsé par un script unique, de nos jours, une classe document.

Et d’autres préfèrent  utiliser la timeline de flash et considérent les Frames comme des écrans :
frame1 = préloader, frame 2 = écran accueil, frame3 = Biographie, etc. Et naviguer d’un écran à l’autre à l’aide gotoAndStop() en fonction des clicks utilisateur.

Une méthode est elle meilleure que l’autre ? Bof, je ne pense pas, c’est surtout dépendant de l’application à réaliser et des affinités du réalisateur avec le code AS3 ou l’IDE Flash. La deuxième est du code spaghettis ? Pas forcément, cela peut être très propre, même si plusieurs images clefs avec code, comme il y a moyen de faire du code spaghettis au sein d’un script unique.

D’ailleurs, la deuxième méthode s’apparente aux « States » de Flex , dans Flex, c’est la seule possibilité de modifier certaines propriétés de contrôles qui sont impossibles à changer au RunTime.

Attention toutefois que la deuxième méthode va recharger et réinstancier les éléments instanciés par code, il faut vérifier l’état de mémoire et regarder à ne pas la surcharger par des redondances au fil de la navigation.

Même en utilisant la première méthode, une Timeline de 2 images est intéressante afin de faire un preloader intégré à la Main application.

Dès lors, est-il possible de créer plusieurs images clefs par code?

Sous Flash .. « Dessine moi une Timeline.. »

Sous Flash, rien de plus simple, on crée les frames nécessaires, on place les éléments, le code et on compile.

Mais justement, comment Flash fait il ? Car c’est en wysiwyg et le code ou les directives de création de frames nous échappent.

Créons un FLA « test.fla », créons 2 images Clefs vides et compilons. Nous obtenons un SWF contenant 2 frames vides, rien d’autre.
A présent, ajoutons une instruction stop() ; sur chaque frame. Nous obtenons un SWF avec 2 Frames vides et une Classe MainTimeline que voici :

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package test_fla
{
    import flash.display.*;
 
    dynamic public class MainTimeline extends MovieClip
    {
 
        public function MainTimeline()
        {
            addFrameScript(0, this.frame1, 1, this.frame2);
            return;
        }// end function
 
        function frame1()
        {
            stop();
            return;
        }// end function
 
        function frame2()
        {
            stop();
            return;
        }// end function
 
    }
}

En AS2, on aurait trouvé 2 frames avec du code dans chaque frame. En AS3, les choses sont différentes ! Flash crée une classe document et le code associé à chaque frame est une fonction dont la référence est ajoutée par code à chaque frame vide. Ce qui nous permet de découvrir l’instruction addFrameScript.

Si on consulte la classe MovieClip du globalPlayer.swc, on trouve cette méthode. Elle est donc bien accessible que via la classe MovieClip, voilà, pourquoi, une classe possèdant une Timeline doit forcément étendre MovieClip et non Sprite qui est au départ la valeur par défaut que le player instancie afin de créer la scène d’affichage.

En AS3 ..  « Code moi une Timeline.. »

Pas de problème, vous créer une MainClass qui étend MovieClip. Vous tracez la propriété totalFrames et vous constatez qu’il  y a 1 frame par défaut. Qu’à cela ne tienne, vous aller dans la doc chercher cette fameuse méthode addFrame ou équivalent.. C’est là que ça se complique.. vous n’en trouvez pas !
Vous essayer d’utiliser addFrameScript, peut être que le compilateur va créer les frames en fonction de ça.. Vous compilez et..  Kedal, nada, zero !! toujours 1 frame :S

La classe MovieClip possède bien en Array scenes, mais il est en lecture seule! Donc, même on créeant un objet à l’aide la classe Scene, impossible de l’ajouter à l’objet MovieClip.

Flash crée plusieurs images Clefs!!, donc, soit, il utilise des instructions cachées, soit une directive de compilation cachée, soit un argument à l’invocation du compilateur.. !? A moins que le compilateur de Flash soit différent du mxmlc??

On pourrait envisager d’écrire une classe Timeline qui imiterait toutes les propriétés et méthodes de la classe MovieClip en y ajoutant addFrame etc.
Mais cela ne sera pas une vraie timeline exécutée automatiquement par le player..

On ouvre une console DOS, on lance la commande:  mxmlc.exe -help -advanced -details

Et là, une longue liste d’arguments apparaît.. on scrute.. mais pas le moindre signe addFrame ou addScene à l’horizon.. Sauf quand même qu’une commande attire notre attention.. La commande

-frame.frame ayant l’alias -frame.

Sous FlashDevelop, on crée un nouveau projet AS3,  on ouvre les propriétés du projet, onglet Compiler Options, et dans Additional Compiler Options, on ajoute :

-frame frame2 Main

Comme il est obligatoire de passer un Label et une classe à associer en paramètre, on l’appelle frame2 et on lui passe la classe Main en se disant qu’il ne la dupliquera pas et que cela aura le même effet qu’ajouter une image en Flash par la touche F5.

On étend la classe MovieClip et on ajoute un test du nombre de frames :

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package
{
    import flash.display.*;
 
	public class Main extends MovieClip
    {
 
		public function Main()
        {
 
			trace(this.totalFrames);
 
        }
 
    }
}

On compile, les yeux rivés sur la fenêtre Output.. et là, un chiffre apparaît ! on peut lire « 2 » !! :D

Génial !! Ca y est !!! Ca fonctionne!! On a bien 2 frames !!

Ensuite, on va ajouter du code lié aux frames  comme ceci :

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package
{
    import flash.display.*;
 
	public class Main extends MovieClip
    {	
 
		public function Main()
        {
			trace(this.totalFrames);
			addFrameScript(0, frame1);
			addFrameScript(1, frame2);
        }// end function
 
		private function frame1():void
        {
 
			stop();
			trace(this.currentFrameLabel);
			nextFrame();
        }// end function
 
		private function frame2():void
        {
                        stop();
			trace(this.currentFrameLabel);
        }// end function
 
    }
}

On teste et tout va bien ! On a créé en code une vraie Timeline, on peut addChilder des objets dans chaque frame et y associer du code.. Voilà, c’est parfait pour un preloader en frame1 et le reste en frame2.

Conclusion

Il est tout à fait possible de créer une Timeline de la manière vue ci avant, pour ajouter des frames, il faut répéter l’option de compilation -frame Label Class autant de fois que de frame désirés.

-frame frame2 Main
-frame frame3 Main
-frame frame4 Main
..

Etant donné que pour chaque frame, on doit associer une classe, il peut être plus simple de créer une classe pour chaque frame et de ne plus utiliser les addFrameScript dans la classe de frame1

Exemple, on peut créer les classes  Frame1.as, Frame2.as, frame3.as, etc Et les associer aux frames correspondants.  Frame1 étant la classe document.

La classe devant contrôler la tête de lecture ou devant utiliser des méthodes ou propriétés de MovieClip devra étendre MovieClip, Dans les autres cas, les frames peuvent étendre Sprite, il n’y aura pas d’erreur de compilation, cela suffit si elle ne sont destinées qu’a addChilder des objets.

Il est tout à fait possible de créer un SWF dont la classe document est un Sprite et contenant une Timeline de plusieurs frames, le SWF fonctionnera, il lira la timeline en boucle, mais aucune méthode ni propriété de Movieclip ne sera accessible, nous n’aurons aucun contrôle dessus, même pas un stop() et surtout, impossible d’y insérer du code. Si on essaye quand même, cela générera une erreur de compilation.

Les gens aimant le principe des frames représentant les états de leurs applications peuvent le faire en AS3 pur ! ;)

Ceux qui aiment avoir un Preloader en frame1 et le reste en frame2 seront également ravis.. dans ce cas, la classe Preload devra être la documentClass et étendre MovieClip.

De cette manière on peut créer l’équivalent des symboles MovieClip sous forme de SWF.
Ceux qui possèdent Flash peuvent faire leurs MC dans Flash et exporter en SWC.

Bookmark and Share

3 réponses Souscrire aux commentaires


  1. ariel sommeria

    Sympa! J’essaie en général de me passer de timeline, mais il faut bien avouer que des fois c’est bien pratique. J’essayerai ta méthode la prochaine fois ou j’y serai obligé
    ariel

    24 mar 2009 @ 13:33


  2. artkabis

    Vraiment pratique cette méthode, perso je l’utilise assez souvent pour stopper par exemple les états (over,out ) de clips étant utilisés comme bouton.

    04 juin 2009 @ 20:47


  3. benbrik rachid

    Effectivement! trés sympa !
    Merci pour ce bout de code qui me sera fort utile. Je reviendrais donner mes retours de son utilisation.

    02 oct 2009 @ 9:28

Répondre