Cause du problème

Avec l'AS3, l'ActionScript a changé au niveau de la gestion des éléments visuels d'une animation. En effet maintenant les clips, les champs de textes, les éléments vidéos, etc. appartiennent tous au groupe des objets de type "flash.display.DisplayObject".

Tous ces objets peuvent être attachés sur la scène principale d'une animation ou dans d'autres éléments graphiques comme avant mais ils ne dépendent plus uniquement du clip "parent" dans lequel ils vont être attachés.

En effet, il faut regarder dans la documentation de l'ActionScript 3 au niveau de la classe flash.display.DisplayObjectContainer pour comprendre qu'il est maintenant possible de créer un clip (ou autre élément visuel) dans l'animation sans avoir obligatoirement à l'attacher dans un autre.

En AS3 les classes Loader, Sprite et MovieClip du package flash.display.* héritent de la classe DisplayObjectContainer et peuvent donc attacher toute sorte d'éléments graphique si ils héritent de la classe DisplayObject.

Voyons un petit exemple d'utilisation de cette fonctionnalité :

import flash.display.* ;
 
var container:Sprite = new Sprite() ;
var shape:Shape = new Shape() ;
 
shape.x = 25 ;
shape.y = 25 ;
 
shape.graphics.beginFill( 0xFF0000 ) ;
shape.graphics.drawRect( 0, 0, 50, 50 ) ;
 
addChild( container ) ;
 
container.addChild( shape ) ;

Dans l'exemple ci-dessus nous pouvons donc créer les instances de types Sprite et Shape avant de les attacher dans la scène principale plus loin dans le code.

Pour ce qui est maintenant d'un MovieClip attaché dans un DisplayObjectContainer, il suffit de faire un petit test rapide pour s'apercevoir d'un mode de fonctionnement un peu particulier par rapport à la version AS1 ou AS2 de la classe.

Je modifie le code défini plus haut pour illustrer le problème et j'ajoute un petit test avec une écoute des touches du clavier pour lancer l'animation :

import flash.events.KeyboardEvent ;
 
mc.play() ; // ne fonctionne pas
 
var keyDown:Function = function( e:KeyboardEvent ):void
{
    mc.play() ; // fonctionne si nous appuyons sur une touche
}
 
stage.addEventListener( KeyboardEvent.KEY_DOWN , keyDown ) ;

En appuyant sur une touche après l'ouverture de l'animation et une fois que le clip est totalement attaché sur la scène, nous pouvons alors utiliser la méthode play() sans soucis.

Il faut donc un certain temps au player pour initialiser le MovieClip et que nous puissions utiliser la méthode, nous pouvons aussi utiliser la méthode setTimeout pour illustrer ce temps d'attente nécessaire avant d'utiliser la méthode play() :

mc.play() ; // ne fonctionne pas
 
var run:Function = function():void
{
    mc.play() ; // fonctionne après un délais de 150ms par exemple
}
 
setTimeout( run , 150 ) ;

Nous pouvons aussi utiliser un petit hack en utilisant la propagation évènementielle de la classe Stage et en écoutant l'évènement de type Event.ACTIVATE :

import flash.events.Event ;
 
    mc.play() ; // ne fonctionne pas
 
    var activate:Function = function( e:Event ):void
    {
        trace("activate") ;
        mc.play() ; // fonctionne
    }
 
    stage.addEventListener( Event.ACTIVATE , activate ) ;

Finalement nous pouvons dire que lorsque nous attachons un MovieClip ou tout DisplayObject dans un objet de type DisplayObjectContainer il faut absolument faire attention au temps d'initialisation de l'élément graphique dans son container avant de vouloir interagir dessus rapidement. Certaines propriétés et méthodes seront initialisées immédiatement alors que d'autres seront un peu plus capricieuses.

Solution

Finalement, il est impossible de lancer la méthode play() d'un MovieClip avant que celui-ci soit totalement attaché dans un container de l'application.

Personnellement pour remédier à ce petit problème j'utilise la fonction non documentée addFrameScript pour hacker le MovieClip et lui demander de forcer l'exécution de sa méthode play() au moment que je le désire, pour cela il suffit de taper le code suivant :

mc.addFrameScript( 0 , mc.play ) ;

De façon général il faut donc bien réfléchir avant de lancer un clip dans une animation et prendre en compte ce comportement un peu spécial de l'AS3.

Pour toutes vos questions sur cet article vous pouvez utiliser les commentaires de ce blog mais je vous propose d'aller discuter sur le Google Groups de mon blog.