FAQ AS3
Cette FAQ AS3 répond à des questions essentielles que tout programmeur débutant en AS3 risque de se poser.
Termes utilisés:
MainTimeline: la timeline principale du FLA constituée de Frames. (scenario)
MainTimeline: La classe document générée dans le SWF sur base du code de MainTemeline.
Main: La classe document.
membre: Elément d’une classe ou d’un objet. Soit, une propriété, une méthode ou un évenement.
AVM2: FlashPlayer AS3.
AVM1: FlashPlayer AS1 & 2.
Table des matières
- Dans quel Ordre l’AVM2 instancie t’elle les différents éléments au démarrage du SWF?
- Qu’est exactement l’objet root?
- Comment accéder à un membre de l’objet root?
- Je code à la fois dans la MainTimeline du FLA et dans une classe document, que deviennent ces codes au runTime?
- Flash fait-il les imports de classes automatiquement?
- Le compilateur compile t’il d’office toutes les classes importées?
- La librairie du FLA est-elle entièrement compilée dans le SWF?
- Que devient un symbole clip créé en Flash après compilation?
- Que devient un symbole graphique créé dans flash après compilation?
- Peut-on ajouter des Frames par code?
- Comment accéder aux variables et méthodes publiques de Main depuis d’autres classes?
- J’utilise un SWF partagé en guise de librairie et j’ai une erreur #1065!
- Comment importer des SVG dans mes classes AS3?
- Peut-on mettre plusieurs classes dans un package?
- Qu’est exactement le mot clef this?
- Qu’est exactement l’objet stage?
- Comment ajouter des propriétés à une classe non dynamique?
- Comment passer des paramètres à une fonction de Listener?
Dans quel Ordre l’AVM2 instancie t’elle les différents éléments au démarrage du SWF?
l’AVM2 (Adobe Virtual Machine 2) instancie les classes des objets déposés directement sur la scène en frame1, puis la classe document, puis éxécute le code de la frame1 écrit dans la MainTimeline.
Pour changer cet ordre, il faut retarder ce qu’on veut par un enterFrame ou déplacer d’une image en MainTimeline.
Table des matières
Qu’est exactement l’objet root?
root est une propriété de type DisplayObject de tout objet DisplayObject.
root fait référence à l’instance de la classe document du SWF. *
root a une portée globale à toute l’animation.
La propriété root d’un objet n’est définie que si l’objet est dans la liste d’affichage (addChild).Tant que l’objet n’est pas addChildé , sa propriété root = null.
Dans le cas d’un swf chargé par un Loader ou [Embed], root appelé n’importe où dans le code de ce swf pointe vers l’instance de la classe document initiale de ce swf.
Dans le cas d’une image chargée par un Loader, la propriété root de l’objet loader.content pointe vers l’image elle même.
* Exception : la propriété root de la propriété stage de tout DisplayObject pointe sur l’instance de Stage. Le stage étant le DisplayObjectContainer le plus haut et root ne pouvant pointer vers un DisplayObject enfant, il ne peut pas pointer l’instance de la classe document. Dans ce cas, root pointe vers son instance propriétaire.
Table des matières
Comment accéder à un membre de l’objet root?
A l’éxécution, sauf via stage, accéder à un membre de root, c’est accéder à un membre de l’instance de Main (ou MainTimeline).
Etant donné qu’au moment de la compilation, l’instance de la classe document n’existe pas encore, vouloir accéder à un de ses membres engendre une erreur du compilateur en mode Strict.
Pour contourner ce problème tout en restant en mode Strict, il suffit d’utiliser la syntaxe objet afin que le compilateur n’analyse pas le contenu.
Exemple avec une variable d’instance mainVar de la classe document :
root["mainVar"]
Une autre méthode consiste à caster le membre en transtypant l’instance dans le type intial de la classe comme ceci:
MovieClip(root).mainVar
Cette méthode peut sembler inutile, car on transtype l’instance dans un type qui sera déjà le sien au runTime! Mais justement, le compilateur fera l’impasse sur le contrôle de root, car cette syntaxe de code ne peut être évaluée qu’au runTime.
Table des matières
Je code à la fois dans la MainTimeline du FLA et dans une classe document, que deviennent ces codes au runTime?
La classe document et le code de Maintimeline sont combinés par le compilateur et restructurés afin de faire une seule classe document qui portera le nom de la classe document.
Le code de MainTimeline étant associé à au moins une frame du scénario, il est obligatoire d’étendre la classe document en MovieClip.
Le code venant de la MainTimeline est placé dans des fonctions frame et les instanciations en MainTimeline sont placées en tant que propriétés publiques de classe.
Les fonctions de MainTimeline s’ajoutent aux fonctions de la classe document et deviennent publiques.
Les instanciations dans les fonctions restent dans leur fonction, mais sont renommées en _loc_x:*, car elles n’ont qu’une portée locale à la fonction elle-même et ne nécessitent pas de nom propre.
Table des matières
Flash fait-il les imports de classes automatiquement?
Si on code dans la MainTimeline sans utiliser de classe document, Flash importe automatiquement les classes nécessaires. Par contre, s’il existe une classe document liée au FLA, Flash n’importe plus! Il faut faire les import explicitement soit dans la classe document, soit dans le code de MainTimeline ou utiliser le chemin de packages complet dans l’instruction adressant la classe à utiliser.
Lorsqu’on code une classe, il faut faire tous les imports manuellement.
Table des matières
Le compilateur compile t’il d’office toutes les classes importées?
Non! Seules les classes instanciées (var instance:Class = new Class;) ou au minimum déclarées (Class;) ou dont au moins un membre static est utilisé, sont compilées. Les autres sont ignorées et ne seront pas dans le SWF.
Table des matières
La librairie du FLA est-elle entièrement compilée dans le SWF?
Non! Seuls les objets utilisés (instanciés) sur la scène ou dans le code sont compilés ainsi que les objets activés pour Action Script.
Table des matières
Que devient un symbole clip créé en Flash après compilation?
Un Clip devient toujours un Sprite dans le swf et au moins une image clef vide lui est associée. L’image Clef ne sert qu’à référencer le bloc de code qui lui serait éventuellement associé.
Si le clip est activé pour être accessible pour Action Script ou si du code à été placé dans sa Timeline, une classe associée sera générée et étendra MovieClip.
Table des matières
Que devient un symbole graphique créé dans flash après compilation?
Un symbole graphique devient un Shape dans le SWF. S’il contient une image bitMap, le Shape pointe vers l’image.
Table des matières
Peut-on ajouter des Frames par code ?
Oui, il faut utiliser l’argument de compilation -frame et addFrameScript pour y ajouter du code.
Voir l’article addFrame - Code moi une Timeline
Table des matières
Comment accéder aux variables et méthodes publiques de Main depuis d’autres classes ?
Soit, via la propriété root d’un DisplayObject, voir: Qu’est exactement le root?
Soit, définir les membres comme public static dans la classe et y accéder directement via la classe : Main.membre.
Il est à noté qu’accéder depuis une classe directement à un object extérieur est à éviter si on veut respecter le principe POO, en effet, la classe risque de ne plus fonctionner dans une autre application qui n’implémente pas l’objet en question. Cela la rendrait rigide et dépendante de votre application. Il faut absolument essayer, avant d’envisager cette tactique, de fournir l’objet à la classe d’une manière ou d’une autre, cela garantira la souplesse et l’autonomie de la classe.
Table des matières
J’utilise un SWF partagé en guise de librairie et j’ai une erreur #1065!
Lors du premier accès au swf partagé, tout va bien, mais les tentatives suivantes engendrent une Erreur #1065 de référence.
La cause se situe au niveau de la sécurité du Player, pour ne plus avoir cette erreur, il est nécessaire d’utiliser un objet loaderContext.
Voici un exemple de code à utiliser:
var request:URLRequest = new URLRequest(shared_swf_path); var context:LoaderContext = new LoaderContext(); context.applicationDomain = ApplicationDomain.currentDomain; var loader:Loader = new Loader(); loader.load(request,context);
Comment importer des SVG dans mes classes AS3 ?
A l’aide d’une balise Embed, de la manière suivante :
[Embed(source="images/dessin.svg")] public var DessinSVG:Class;
public function Main(){
var dessin:Sprite = new DessinSVG();
addChild(dessin);
}
Attention, la Balise [Embed]est une fonctionalité du Flex SDK, elle est utilisable dans Flash, mais il faudra ajouter le chemin du flex.swc dans la liste des bibliothèques à utiliser par le compilateur Flash.
Table des matières
Peut-on mettre plusieurs classes dans un package ?
Non! Une seule classe peut exister au sein d’un package. Elle peut être public ou internal.
Par contre, d’autres classes peuvent exister en dehors du package dans le même fichier as, mais elles ne pourront être définies qu’en internal et ne seront accessibles qu’a l’intérieur du fichier as. Les attributs final et dynamic sont autorisés.
Note : Les classes en dehors d’un package peuvent être étendues à condition que la définition de la super classe précède celle de la classe qui l’étend dans le fichier as. Dès lors, étendre une classe se trouvant hors package par la classe du package est impossible, car le mot clef package doit se trouver en premier dans le fichier as.
Les classes écrites en dehors du package sont compilées et placées dans un package portant le nom de la classe principale dans le SWF.
Conclusion, écrire des classes en dehors du package n’est utile que pour les utiliser dans la classe du package par composition.
Table des matières
Qu’est exactement le mot clef this ?
Contrairement à une idée reçue, this référence l’instance de classe et non la classe. this n’est donc défini qu’a l’exécution. Cela explique pourquoi le mot clef this n’est pas utilisable dans une méthode static.
Table des matières
Qu’est exactement l’objet stage?
stage est une propriété de tout objet DisplayObject.
stage fait référence à l’instance de Stage.
stage a une portée globale à toute l’animation.
La classe Stage étend DisplayObjectContainer.
L’objet stage est le DisplayObject le plus haut de la liste d’affichage et englobe toute la display list.
La propriété stage d’un objet n’est définie que si l’objet est dans la liste d’affichage (addChild).Tant que l’objet n’est pas addChildé , sa propriété stage = null. Ce comportement est similaire à root.
Truc inutile mais comique, c’est qu’étant donné que la classe Stage hérite de la classe DisplayObject, une récursivité du type instanceDisplayObject.stage.stage.stage.stage.stage etc. renverra toujours l’instance de Stage.
Table des matières
Comment ajouter des propriétés à une classe non dynamique?
A l’aide de la propriété static prototype de la classe Object.
En AS3, chaque classe est dupliquée en un objet prototype pour une question de compatibilité d’héritage ECMAScript. Cet objet est associé à la classe via une propriété static prototype ajoutée à la classe en interne. La classe Object étant dynamic, on peut lui ajouter des propriétés.
Le compilateur ne pouvant évaluer la nouvelle propriété, car crée au runTime, en mode strict, il faut utiliser la syntaxe objet.
OneClass.prototype.newProperty = "bonjour"; var instance:Sprite = new OneClass; trace (instance["newProperty"]);
Vu de l’extérieur, cela va créer une propriété à la classe elle même! Et également à toutes les classes descendantes! A partir de là, toute nouvelle instance de classe ou sous classe possédera cette nouvelle propriété.
Avant de créer une nouvelle propriété, il faut s’assurer que le nom ne soit déjà pas un nom d’un membre existant dans la classe nativement, sans quoi, cela pointera vers le membre natif et non vers le nouveau membre. La raison est que l’AVM2 cherche d’abord dans l’espace de nom AS3 (héritage direct fixe) avant de chercher la propriété dans la copie prototype (héritage ECMAScript).
Table des matières
Comment passer des paramètres à une fonction de Listener?
Probablement inutile, car utiliser une variable d’instance est nettement préférable, passer des paramètres à la fonction d’un écouteur d’évenement met en évidence la souplesse AS3 et ouvre des perspectives qu’on aurait pu penser impossible au départ. Cela remplace également avantageusement l’utilisation d’une classe Delegate.
L’astuce est super simple, mais elle montre qu’on peut passer d’autres choses que ce que la documentation Adobe laisse entendre. L’idée consiste à appeler la fonction d’écouteur au travers d’une fonction anonyme transitoire tout en répercutant le paramètre Event original additionné des divers paramètres persos.
var button:Sprite = new Sprite;
button.graphics.beginFill(0x0000FF);
button.graphics.drawRect(100, 100, 200, 50);
this.addChild(button);
button.addEventListener(MouseEvent.CLICK,
function (event:*):void { buttonClic(event, 1) });
private function buttonClic(event:MouseEvent, num:uint):void
{
trace("Button "+num+" cliqué!");
}
Bonjour, et merci pour ce blog.
J’utilise le flex_sdk (et pas flex builder car je n’ai pas d’argent), et je voudrais comment configurer la connexion entre l’amfphp et le flex_sdk.
J’ai regardé plusieurs tutos sur le net, et ils explique seulement la configuration de la connexion entre le flex “builder” et l’amfphp.
Or moi, je n’utilise pas le flex “builder”, mais flex “sdk”.
Avec flex “builder”, pour configurer la connexion entre flex builder et amfphp, il suffit de faire click droit sur le dossier du projet, puis configurer le compilateur. Dans la configuration du compilateur, il y a un champs ou il fait mettre en_US -services”service-config.xml”.
Mais avec le flex sdk, comment faire ? il faut toucher le fichier config-flex.xml ?
Merci d’avance, coradialement.
Perso, je n’utilise pas le système xml de Flex ni les classes mx, mais bien l’implémentation en AS3 pure. Dans une application Flex, c’est le même code qu’en Flash à placer dans une balise
mx:Script> < ![CDATA[Pour un exemple de code AS3, voir ce blog: http://www.flash-db.com/Tutorials/helloAS3/helloAS3.php?page=2