2009-10-04 21 views
2

C'est quelque chose qui me dérange depuis que j'ai commencé AS3 il y a un an.Comment référencer un objet dynamiquement instancié dans AS3? (Ajout d'un Moviclip sur la scène)

Exemple. Je fais une classe qui étend un clip vidéo et l'appeler « LoaderBar » tout ce qu'il est est un texte qui dit « Loading » et en dessous un autre clip qui est un rectangle clair que j'appelle « lBar »

Quand j'appelle une fonction pour charger mon image ajouter le chargeur sur la scène en tant que tel ..

function imageLoader(URL:String):void 

{ 

    var loader:Loader = new Loader(new URLRequest(URL)); 
    loader.contentLoaderInfo.addEventListner(ProgressEvent.PROGRESS, progressHandler); 

     var loadBar:Loader Bar = new LoaderBar(); 
     addChild(loadBar); 
} 


function progressHandler(e:Event):void 

{ 

    var pcent:Number = e.getBytesLoaded/e.getBytesTotal; 
    // HERE IS WHERE I'D LIKE TO MAKE DIRECT REFERENCE TO MY LOADBAR; 
    loadBar.lBar.width = pcent*100; 



} 

Essentiellement, je veux juste dire lBar dans le clip loadbar film à la largeur du 100 pour cent *. (de sorte que lorsque le clip est chargé, la barre du chargeur a une largeur de 100 pixels).

Mon problème est le suivant. Quand j'ajoute le loadbar à la scène à l'intérieur d'une fonction, je ne peux pas faire référence à l'intérieur d'une autre fonction sans faire une bidouille faire une variable globale en dehors de ma fonction comme ...

var loadBarClip:MovieClip; 

et à l'intérieur de la charge fonction attribuant la loadBar au loadBarclip en tant que telle

loadBarClip = loadBar. 

Je me sens comme cela est redondant. Est-ce que quelqu'un sait de toute façon d'accéder à mon loadBar sans faire une variable de référence?

Répondre

2

Si c'est juste pour ce gestionnaire, vous pouvez rendre le gestionnaire anonyme et rester dans la portée actuelle.

var loadBar = new LoaderBar(); 
var loader:Loader = new Loader(new URLRequest(URL)); 
loader.contentLoaderInfo.addEventListner(
    ProgressEvent.PROGRESS, function (e:Event):void { 
     var pcent:Number = e.getBytesLoaded/e.getBytesTotal; 
     loadBar.lBar.width = pcent*100; //Here you are making a direct reference. 
    } 
); 

Si vous voulez vraiment vos champs d'application encapsuler vous pouvez utiliser la fermeture:

returnFromEncapulatingClosure = function(){ 
    var loadBar = new LoaderBar(); 
    var loader:Loader = new Loader(new URLRequest(URL)); 
    return { 
     loadBar: loadBar, 
     loader: loader 
    }; 
}(); 

qui vous permet de regrouper ensemble des références afin qu'ils n'écraserait d'autres parties du code, et vous pouvez consulter à lui avec:

returnFromEncapulatingClosure.loader.contentLoaderInfo.addEventListner(ProgressEvent.PROGRESS, progressHandler); 
function progressHandler(e:Event):void { 
    var pcent:Number = e.getBytesLoaded/e.getBytesTotal; 
returnFromEncapulatingClosure.loadBar.lBar.width = pcent*100; 
} 

Comme une note de bas, lorsque vous étendez le clip, ajoutez une méthode qui définit le lBar.width.Quelque chose comme:

loadbar.setLBarWidth = function (w:number) { 
    this.lBar.width = w; 
} 
+0

love it !! RE: La note de pied, Pour une raison quelconque, j'ai adapté un goût de tout contrôler à partir de la base. Je sens que je ne suis pas en train de creuser à travers les classes pour voir ce qui se fait quoi à lui-même, plutôt que de partir de la maison et de mettre mes commandes sur tout à partir de zéro. Je ne fais pas toujours ça, et je suppose que ce n'est pas très OOP de moi, mais je commence juste. Merci encore, des conseils géniaux. –

+0

oh mec, cela règle !! Ça a bien marché. De cette façon, je peux également me débarrasser du chargeur lorsque j'ai terminé le chargement en ajoutant un autre gestionnaire pour le Event.COMPLETE. Vous venez de changer la façon dont j'écris mes gestionnaires d'événements de chargement pour toujours. –

+0

Je suis très heureux que vous l'aimez. Je pense que c'est assez propre, et rend les choses lisibles et organisées lorsque vous utilisez des fonctions anonymes. Pour les événements, j'utilise uniquement les fonctions nommées lorsqu'elles sont réutilisées. Notez également que pour la fermeture que j'ai mentionnée, le 'returnFromEncapsulatingClosure' devrait être nommé quelque chose qui fonctionne pour votre contexte, et vous pouvez supprimer les variables nommées et placer les instructions' new' directement dans l'objet retourné. – dlamblin

2

Je ne vois pas de problème majeur à ce que la variable soit déclarée en dehors de la fonction imageLoader. Si vous écriviez ceci dans une classe au lieu de la timeline, alors ce serait juste une variable membre de classe et il n'y a rien de mal à cela. Ils existent pour cette raison même.

Si votre DEADSET vouloir garder alors variable locale le loadbar vous pouvez toujours le faire:

dans la fonction imageLoader:

var loadBar:Loader Bar = new LoaderBar();  
loadBar.name = "loadBar"; 
addChild(loadBar); 

dans la fonction progressHandler:

getChildByName("loadBar"); 
+0

Merci! La raison pour laquelle j'ajoute ceci à la scène dans une fonction est avant cette fonction que je fais un balayage propre de tous les enfants enterrés dans son clip parent. J'ai essentiellement une "scène" (déteste ce mot) dont la visibilité est juste cliqué, selon où quelqu'un est dans la navigation. A l'intérieur de la scène sont un ensemble de fonctions qui produisent son contenu. L'un d'entre eux étant une fonction "cleanScene()" qui supprime tous ses enfants afin que je n'utilise pas l'excès de mémoire. Le problème est qu'une fois que je nettoie ma scène, j'élimine aussi tout ce que je ne rajoute pas dynamiquement à la scène. –

1

Depuis lBar (ou loadBar d'ailleurs) est un élément que vous devez gérer au niveau de la classe, vous devriez en faire un membre de la classe. Il n'y a rien de mal à cela;)

+0

Je triche en fait quand je dis cours ... J'utilise l'option "Exporter pour Actionscript" dans le panneau des propriétés de la bibliothèque. Bien que j'aimerais faire tout en textedit, je suis aussi un peu paresseux. –

+0

Un MovieClip avec du code dans son scénario est aussi une classe pour flash ... le compilateur génère une classe avec le nom que vous déclarez dans le champ "Nom de classe", et les propriétés et fonctions que vous déclarez dans l'une de ses images. Ensuite, le code "non-déclaratif" lui-même est inséré dans la classe via addFrameScript ... Donc vous pouvez réellement traiter vos MovieClips comme des classes, même si vous ne créez pas un fichier de classe externe pour eux;) – Cay