Forums Développement Multimédia

Aller au contenu

Boutons, swf externes, loader ... Problème de fonction

loader MovieClip swf externe fonction en boucle target CODE Actionscript

7 réponses à ce sujet

#1 MaelCreation

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 21 June 2012 - 09:40 AM

Bonjour,
Je me plonge dans l'AS3 pour un projet, je ne suis pas complètement novice, j'ai quelques notions de langages, mais là, je butte ....

J'ai plusieurs boutons - Chacun d'eux comporte :
- une action au survol : charger un swf externe à un endroit précis
- une action au clic : ouvrir une URL

Chaque bouton charge un swf externe différent dans la page courante, et une url différente.

Voici mon code

bt01.addEventListener(MouseEvent.ROLL_OVER, loadmovie01);
function loadmovie01(event:MouseEvent):void{
var request:URLRequest = new URLRequest("c01.swf");
var loader:Loader = new Loader()
loader.load(request);
loader.y=250;
MovieClip(root).addChild(loader);
}
bt01.addEventListener(MouseEvent.CLICK, lien01);

function lien01(event:MouseEvent):void {
   navigateToURL(new URLRequest("http://monlien.com"));
}
 

Il fonctionne, mais le broblème, c'est que j'ai une soixantaine de boutons à coder, et que je suis sûre qu'il y a une meilleure façon de faire que de répeter ce code en nommant "loadmovie02"etc ...et "lien02" etc ...
Finalement, c'est toujours la même fonction que j'appelle, je devrais donc pouvoir créer 1 seule fois la fonction et l'appeler pour chaque bouton, avec des critères de cibles différentes ... Je sais qu'il faut que j'utilise "target" ou "currentTarget" mais je ne trouve pas la syntaxe ...

J'espère me faire comprendre ... Merci de votre aide.

Maelle

#2 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 21 June 2012 - 10:31 AM

Bonjour mael.

Ce qui te manque, c'est de structurer tes données. Avec des données structurées, tu peux penser de façon abstraite (je code pour "un bouton" et pas pour "le bouton 01") et tu peux alors utiliser currentTarget (ou target).
Mais sans cela, tu seras toujours à coder une fonction par bouton.

Pour structurer les données, il y a une méthode simple si tes boutons sont des MovieClips, car ils sont dynamiques. Cela veut dire que tu peux leur ajouter des variables à la volée, et donc, structurer tes données à l'intérieur même du bouton. Du coup, tu récupères le bouton via la variable currentTarget des événements, et tu peut retrouver toutes tes données dans le bouton…

Si tes boutons sont des SimpleButton, c'est plus difficile puisque pas dynamiques… Dans ce cas on peut contourner en passant par un Dictionnary, mais je trouve cette solution moins propre.

D'ailleurs, la meilleur de toutes les solutions serait quand même de créer une classe, ou tes données seraient bien structurées et typées… ça dépend de tes connaissances dans ce domaine.

Si je reprends la première idée :
il faut que tu stockes dans ton bouton une variable pour l'url de la vidéo associée, une variable pour l'url du lien à atteindre, une variable pour la position du loader… peut-être d'autres ? Une fois qu'on a compris le principe, on peut en ajouter autant que l'on veut.

Pour faire ça, tu peux t'y attaquer bouton par bouton, mais ça va être encore un peu fastidieux.
Tu peux écrire une fonction qui va se charger de stocker les données, poser les écouteurs, il ne te restera plus qu'a appeler la fonction en lui passant tous les paramètres. C'est le minimum syndical, je crois…

ça donnerait quelque chose comme ça :

// J'appelle ma fonction pour chaque bouton, en lui passant tous les paramètres distinctifs
structurer (bt01,"c01.swf","http://monlien.com",250);
structurer (bt02,"c02.swf","http://autrelien.com",150);
structurer (bt03,"c02.swf","http://encoreunlien.com",50);
// etc…

function structurer ($bouton:MovieClip,$url_1:String,$url_2:String,$y:int):void {
  $bouton.movieURL = new URLRequest($url_1);
  $bouton.linkURL = new URLRequest($url_2);
  $bouton.loader_y = 250;
  $bouton.addEventListener(MouseEvent.ROLL_OVER,roll);
  $bouton.addEventListener(MouseEvent.CLICK,click);
}

 

Et là, ça devient facile.
Tu n'as plus que 2 fonctions à écrire.
Dans chaque fonction, le principe est le même : d'abord récupérer le bouton via la propriété currentTarget de l'événement
Ensuite accéder aux variables que la première fonction a créé…

function roll (event:MouseEvent):void {
  var bouton:MovieClip=MovieClip(event.currentTarget);
  var loader:Loader = new Loader();
  loader.load (bouton.movieURL);
  loader.y = bouton.loader_y;
  MovieClip(root).addChild (loader);
}
function click (event:MouseEvent):void {
  var bouton:MovieClip=MovieClip(event.currentTarget);
  navigateToURL (bouton.linkURL);
}
 

Il y a un autre sujet en cours où je développe l'idée (plus celle du dictionnary), ça commence ici.

#3 MaelCreation

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 21 June 2012 - 11:54 AM

Merci beaucoup Dldler,
Tes explications sont très claires ... Je m'attèle à ma tâches dans ce sens, en transformant mes boutons en clip dans un 1er temps, et avec 2 fonctions, ça me parait plus simple que "dictionnary" ...

#4 MaelCreation

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 21 June 2012 - 13:04 PM

ça y est c'est en place et ça fonctionne très bien !
Il y a encore une petite chose ... Je me suis rendue compte que les swf se chargeaient les uns sur les autres ... Je pensais que par défaut, l'action du nouveau bouton et le nouveau swf chargé viendrait remplacer le 1er mais ce n'est pas le cas.
J'ai essayé de faire une nouvelle fonction avec unload ou removeChild ... Et de l'appeler dans la fonction qui structure, avant toute autre action, mais ça ne fonctionne pas ... Je cherche dans les forums, j'ai testé pas mal de choses mais rien ...
Encore un coup de main ? :-) Merci bcp

#5 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 21 June 2012 - 13:12 PM

Effectivement, dans Flash, rien ne se fait tout seul :D Il faut tout faire soi même.
Donc, si tu ne veux plus d'un objet d'affichage, il faut l'ôter avec removeChild.

Pour pouvoir l'ôter, il faut avoir un lien vers… autant dire une variable.

Tu pourrais par exemple le faire comme ça :
// déclarer une variable globale (cad en dehors des fonctions)
var loader_actuel:Loader;

Dans la fonction qui affiche (function roll()), il te reste à :
- vérifier s'il y a un loader actuel.
- - Si oui : le désafficher.
- Puis :
- afficher le nouveau loader
- le stocker dans la variable loader_actuel…

Je te laisse un peu chercher le code mais si tu bloques, je repasse par là cet aprem.

#6 MaelCreation

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 22 June 2012 - 17:47 PM

Re !!
Haaaaa je m'arrache les cheveux ! j'essaie de comprendre et de suivre la méthodo que tu me donnes, mais encore une fois, je beug ...
Voilà ce que j'ai fait :
j'ai tout bêtement copié ce que tu m'as conseillé : déclarer la variable globale var loader_actuel:Loader;
En dehors de la fonction, OK ...
Ensuite, dans la function roll(), voici le code que j'ai testé :

function roll (event:MouseEvent):void {
  var bouton:MovieClip=MovieClip(event.currentTarget);
  var loader:Loader = new Loader();
 
if(loader_actuel.numChildren > 0){
                            loader_actuel.removeChildAt( 0 );
                    }else{
  loader.load (bouton.movieURL);
  loader.y = bouton.loader_y;
  MovieClip(root).addChild (loader);
// maintenant il faut que je stocke le nouveau loader dans loader_actuel ...
                    }
 

Flash me renvoie Error #1009: Il est impossible d'accéder à la propriété ou à la méthode d'une référence d'objet nul.

Je nage un peu ...
Si tu peux m'expliquer mes erreurs et à côté de quoi je passe ... Vraiment merci bcp !

Maelle

#7 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 22 June 2012 - 18:18 PM

C'est sans doute normal… au début, il n'y a pas de loader_actuel.
Donc impossible pour flash d'accéder à la propriété numchildren de rien du tout.

Ce qu'il faut que tu fasses, c'est vérifier l'existance d'un loader_actuel avant d'acceder à la propriété.

Généralement on le fait avec un simple test : if(la_variable)

donc plutôt :
if(loader_actuel) MovieClip(root).removeChild(loader_actuel);
loader_actuel = loader;
MovieClip(root).addChild(loader_actuel);

et c'est tout… car il vaut mieux retirer le loader entier plutôt que juste son contenu. Sinon, tu vas accumuler des loaders (vides) dans la liste d'affichage.

#8 MaelCreation

    Ceinture Blanche

  • Members
  • Pip
  • 5 messages

Posté 23 June 2012 - 07:47 AM

ah oui ... effectivement je m'étais compliquée la vie ... Mille mercis, je pense que je devrais y arriver maintenant !



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)

authorised training centre

Centre de Formation Mediabox - Adobe et Apple Authorised Training Center.

Déclaré auprès de la Direction du Travail et de la Formation Professionnelle

Mediabox : SARL au capital de 62.000€ - Numéro d'activité : 11 75 44555 75 - SIRET : 49371646800035

MEDIABOX, 23, rue de Bruxelles, 75009 PARIS

FFP