Puce et Média

Recherche et développement en multimédia

  • Augmenter la taille
  • Taille par défaut
  • Diminuer la taille
Puce et Média

Flash et XML - Créez une barre de menu sous Flash et XML

Envoyer Imprimer PDF

.net - Mai 2005

Simplement avec quelques lignes de code ActionScript et l’aide d’une structuration XML, il est très facile de générer une barre de menu à la volée pour vos animations Flash, Lancez l’animation menu_03.fla, un jeu de menus et sous menus permet de choisir une image. Ouvrez le panneau Action, cliquez sur la première image du calque ‘Valeur’ et donnez à la variable ‘RefFichier’ la valeur ‘menus2’ et à la variable ‘RefBouton’ la valeur ‘Bt_Base3’. Lancez à nouveau l’animation pour visualiser la différence. Grâce à quelques lignes d’ActionScript et à l’utilisation de fichiers XML il est facile de mettre en place une telle souplesse de modification. Nous allons le voir au travers de cet article.

Apercu et télchargement des fichiers nécessaires

 

Le fichier XML

Un des grands avantages d’XML est de pouvoir facilement structurer le contenu d’un fichier. Prenons l’exemple d’une barre de navigation. A la base, les éléments qui la composent sont des menus, des sous menus, des liens... on pourrait comme cela aller encore plus loin dans le détails en incluant toute sortes d’informations telle que la forme des boutons, les textes des info-bulles, etc. XML va nous permettre de renseigner toutes ces informations dans le degré de complexité voulu.

Avant d’aller plus loin, quelques règles de bases sont nécessaires. Le XML est un langage à balises imbriquées les unes aux autres. Il a beaucoup de similitude avec le HTML, mais la syntaxe y est bien plus rigoureuse. En voici quelques exemples:

  1. Une seule balise doit composer l’ensemble du document, comme la balise <html> des documents html.
  2. Les imbrications de balises ne peuvent pas être croisées, <b><i>contenu</b></i> n’est pas valide en XML.
  3. Chaque balise ouvrante doit posséder une balise fermante, dans le cas de balise simple, comme <img> en html, il faut terminer la balise par un slache, <img src=«lelien.jpg» /> ou <br />.
  4. Chacune des balises peut avoir un ou plusieurs attributs qui doivent être définis entre guillemet, lien=«lelien.jpg», même pour des valeurs numéraires largeur=«10».
  5. Les balises ouvrantes et fermantes sont sensibles à la casse, <Balise>contenu</balise> n’est pas valide en XML.

Voilà, on peut débuter la rédaction du document XML. Lancez Note Pad ou (TextEdit sous Mac) et enregistrez le fichier sous « menus.xml ». Pour renseigner des valeurs, il y a deux possibilités, soit comme contenu de balises, soit au travers d’attributs. Afin d’en explorer les deux manières, les menus et les liens seront passés en attribut et les sous menus en élément (ou balise).

Aucun entête de fichier n’est nécessaire car pour l’heure Flash ne les gère pas, l’essentiel est, si possible, d’enregistrer le fichier sous un codage UTF-8. Le fichier XML en est réduit à sa plus simple expression, une balise <menus> incluant des sous balises <menu> et <sousmenu> ainsi que des attributs ‘titre’ et ‘lien’.

<menus>
	<menu  titre="Légumes">
		<sousmenu  lien="oign.jpg">Oignons</sousmenu>
		<sousmenu  lien="poiv.jpg">Poivrons</sousmenu>
	</menu>
	<menu titre="Fruits">
		<sousmenu  lien="melo.jpg">Melons</sousmenu>
		<sousmenu  lien="pech.jpg">Pêches</sousmenu>
		<sousmenu  lien="citr.jpg">Citrons</sousmenu>
		<sousmenu  lien="oran.jpg">Oranges</sousmenu>
	</menu>
</menus>
      

Le fichier Flash

Le fichier de description terminé, il faut passer à Flash et à l’ActionScript. Durant cette phase, il va falloir, importer le fichier XML, le transformer en tableau Flash (Array())*,et générer l’affichage des menus correspondants.

Les trois fichier fournis vont tour à tour explorer diverses facettes de cette barre de menu. D'abord le chargement du fichier XML (menu_01.fla), puis viendra la sérialisation du fichier XML en tableau Flash (menu_02.fla) et enfin le dernier explorera la gestion de la barre de navigation (menu_03.fla). Vous allez trouvez ci-dessous le détail de l'exploration des ces trois fichiers.

(*) Deux écoles sont possibles, soit utiliser et faire référence continuellement au modèle XML, soit sérialiser sous forme d’Array().   Pour notre barre de navigation nous allons utiliser un seul symbole ‘Clip’, contenant un bouton. Le bouton contient lui, une variable ‘titre’ qui affichera le libellé. Il faut impérativement exporter ce symbole pour l’action script. Deux possibilités pour obtenir la boîte de dialogue, sélectionnez le symbole puis soit pressez le bouton info de la bibliothèque, soit sélectionnez ‘liaison’ dans le menu contextuel de la bibliothèque. Il faut ensuite choisir ‘exporter pour l’action Script’, ‘exporter dès la première image’, et ne pas oublier de donner comme identifiant le nom ‘Bt_Base’.

--- menu_01.fla --- Chargement et exploration du fichier XML depuis Flash

Le fichier XML est chargé par Flash, puis exploré au niveau de ses balises et attributs. Tout est affiché au fur et à mesure dans une variable ‘Apercu’ présente sur la scène.

calque(Init)
	/*

		Si le fichier XML n’est pas Unicode, cette instruction permet à 
		Flash de s’adapterau mode d’encodage du système et
		de préserver entre autre les caractères accentués 
		(si UTF est utilisé pour le fichier XML, 
		commentez cette ligne par deux slaches ‘//’). 
	*/
	
System.useCodepage = true;

	/*
		Instanciation d'un objet XML
	*/ 
	
LeMenuXML = new XML();

	/*
		Lors de la mise en forme du fichier XML, il est souvent utilisé 
		des tabulations, des retours chariots, etc… 
		Le player de Flash traitent ces caractères spéciaux comme des balises 
		qu’il nous faut filtrer. 
		En plaçant la propriété ignoreWhite=true, 
		on indique au player Flash de ne pas tenir compte des caractères TAB, CR, LF... 
	*/
	
LeMenuXML.ignoreWhite = true;

	/* 
		Déclenchement du chargement du fichier XML.
	*/
	
LeMenuXML.load("menus.xml");

	/* 
		En applicant la fonction onLoad() à l'objet XML 
		on spécifie les jeux d'instruction à executer 
		une fois le dernier octet chargé 
	*/
	
LeMenuXML.onLoad = function() {

	/* 
		recupération et extraction de la première balise 
		dans notre cas <menus> 
	*/
	
	LeMenuXML = LeMenuXML.firstChild;
	
	/* 
		mise en boucle sur le nombre de balise contenu...
		dans notre cas <menu> pour chacune de ces balises 
		recupération et affichage de l'attribut titre 
		dans la variable Apercu présente sur la scène 
		la concaténation de l'instruction \n permet 
		d'occasionner un retour chariot 
	*/
	
	for (var i = 0; i<LeMenuXML.childNodes.length; i++) {
		var menu = LeMenuXML.childNodes[i].attributes["titre"];
		Apercu +=  menu + "\n";
/* mise en boucle sur le nombre de balise contenu dans la balise <menu> dans notre cas <sousmenu> */ for (var j = 0; j<LeMenuXML.childNodes[i].childNodes.length; j++) { /* pour chacune de ces balises recupération du contenu de la balise et de l'attribut titre. Ensuite on les affiche dans la variable Apercu présente sur la scène. La concaténation de l'instruction \n permet d'occasionner un retour chariot */ var sousmenu = LeMenuXML.childNodes[i].childNodes[j].firstChild.nodeValue; var lien = LeMenuXML.childNodes[i].childNodes[j].attributes["lien"]; Apercu += " " + sousmenu + ": " + lien + "\n"; } } };

--- menu_02.fla --- Mise en tableau des datas, et génération du menu.

Cette fois lors de l’extraction des datas, ceux ci sont placés dans un tableau Flash, et les menus se positionnent sur la scène.Pour un soucis de clarté, certaines lignes de code ne sont pas commentées. Si vous le souhaitez, vous pouvez vérifier dans le fichier précédent, vous aurez alors les commentaires 'manquants'.

calque (init) - complément
System.useCodepage = true;
LeMenuXML = new XML();

/*
	Instanciation d'un objet Array(), permettant de stocker des tableaux 
*/

LeMenuArray = new Array();
LeMenuXML.ignoreWhite = true;
LeMenuXML.load("menus.xml");
LeMenuXML.onLoad = function() {
	LeMenuXML = LeMenuXML.firstChild;
	for (var i = 0; i<LeMenuXML.childNodes.length; i++) {
		var menuTemp = LeMenuXML.childNodes[i].attributes["titre"];
	
		/*
			Pour chaque balise <menu> un tableau supplémentaire est imbriqué dans le premier, 
			afin de stocker lesinformations relatives à chacun des menus. Vous pouvez voir sur la scène
			le détail d'imbrication du tableau global 'LeMenuArray' 
		*/
		
		LeMenuArray[i] = new Array();
/* Deux sous rubriques sont crées dans ce sous tableau ‘menu’, dans laquelle est placé le nom du menu et ‘sousmenu’ dans laquelle est placé un nouveau tableau qui lui recevra , dans la boucle suivante, une à une les informations relatives à l'ensemble des sous menu.(voir schéma ci-dessous) */ LeMenuArray[i]["menu"] = menuTemp; LeMenuArray[i]["sousmenus"] = new Array(); for (var j = 0; j<LeMenuXML.childNodes[i].childNodes.length; j++) { /* Création d'un nouveau tableau qui recevra pour chaque éléments de sous menu, le nom du sous menu et son lien. Une fois ce tableau créé et rempli, il est placé dans le tableau précédent. (voir schéma sur la scène) */ var smenuTemp = new Array(); smenuTemp["smenu"] = LeMenuXML.childNodes[i].childNodes[j].firstChild.nodeValue; smenuTemp["lien"] = LeMenuXML.childNodes[i].childNodes[j].attributes["lien"]; LeMenuArray[i]["sousmenus"][j] = smenuTemp } } /* L'instance LeMenuXML peut maintenant être libérée de la mémoire */ delete LeMenuXML; /* Appel de la fonction qui va gérer l'affichage des menus cette fonction est placée sur le calque suivant 'Menu' */ AfficheMenu(); };

calque(Menu)
AfficheMenu = function () {

	/*
		Un clip vide, nommé ‘menuGlobal’, est créé sur la scène en profondeur 500. Ce clip va contenir 
		les menus et permettra de les regrouper au sein d'une même instance. Le niveau 500 est arbitraire 
		et permet de s'assurer qu'aucun clip éventuellement présent sur la scène ne sera écraser
	*/

	_root.createEmptyMovieClip("MenuGlobal", 500);

	/* 
		Pour chacun des menus, un clone du symbole ‘BT_Base’ (présent et identifié (liaison) dans la 
		bibliothèque) est attaché au clip ‘menuGlobal’, positionné en x y, identifié par une variable 
		lequel (qui nous servira plus tard) et sa variable ‘titre’ est rempli avec le libellé du menu.
	*/
	
	/* 
		Attention, le premier élément d'un tableau (Array()) se trouve en index 0 et pas en 1 
		comme il semblerait logiquement
	*/

	for (var i = 0; i<LeMenuArray.length; i++) {
		_root.MenuGlobal.attachMovie("Bt_Base", "menu"+i, 510+i);
	
		/* 
			20 correspond à lamarge X à laquelle sera placé le premier bouton, ensuite le second se placera,
			à cette marge plus autant de fois la largeur du bouton 
		*/
	
		_root.MenuGlobal["menu"+i]._x = 20+(i*_root.MenuGlobal["menu"+i]._width);
		
		/* 
			10 correspond à la marge sur les Y pour placer l'ensemble des boutons attention de bien tenir 
			compte du point de référence 0 du clip pour un positionnement précis 
		*/
		
		_root.MenuGlobal["menu"+i]._y = 10;
		_root.MenuGlobal["menu"+i].lequel = i;
		_root.MenuGlobal["menu"+i].titre = LeMenuArray[i]["menu"];
	
		/* 
			Enfin, une action de rollover est attachée au bouton (bt)contenu dans ce clone.
			Pour l’instant cette fonction trace simplement le nom du menu au survol, mais dans le fichier 
			suivant, elle sera décommentée et interpellera la fonction afficheSousMenu().
		*/
	
		_root.MenuGlobal["menu"+i].bt.onRollOver = function() {
			trace(LeMenuArray[this._parent.lequel]["menu"]);
			//AfficheSousMenu(this._parent.lequel);
		}
	}
}

En sélectionnant le symbole ‘Bt_Base’ puis l’icône infos de la bibliothèque, il suffit de l’exporter pour l’ActionScript dès la première image, afin de le rendre disponible au code.

--- menu_03.fla --- Gestion des sous menus et affichage de l’image.

calque(Valeur)
/* 
	L’utilisation de 4 variables nous permet de judicieusement  centraliser, et assouplir la modification
	de certaines parties du code. ‘RefBouton’ précise le symbole à utiliser pour la barre de menu 
	(ligne 4  du calque ‘Menu’), ‘RefFichier’ définie le  fichier XML à charger (ligne 22 du calque ‘Init’),
	et ‘ImageX’ et ‘ImageY’ spécifient  quant à elles, la position de l’image à afficher 
	(lignes 2 et 3 du calque  ‘Image’).
*/

RefBouton =  "Bt_Base";
RefFichier =  "menus";
ImageX =  400;
ImageY =  300;
Calque (SousMenu)
/*
	Afin de ne pas avoir deux sous menus affichés en même temps, la fonction AfficheSousMenu() commence par retirer 
	le clip « sousMenuGlobal » éventuellement déjà présent, puis elle reprend le schéma de la fonction précédente.
	C’est à dire qu’elle va créer un clip vide global, appelé « SousMenuGlobal », pour contenir les sous menus.
	Ce clip est placé en profondeur 600, mais cette fois il sera positionné en fonction du menu qui est survolé.
	Dans l’intitulé de la fonction un paramètre est reçu et est identifié par ‘a’. Il est donc ainsi facile de
	retrouver toutes les propriétés du menu en invoquant le chemin de cible _root.MenuGlobal[«menu» + a].
*/

AfficheSousMenu = function (a) {
	_root.SousMenuGlobal.removeMovieClip()
	_root.createEmptyMovieClip("SousMenuGlobal",600);
	_root.SousMenuGlobal._x = _root.MenuGlobal["menu" + a]._x;
	_root.SousMenuGlobal._y = _root.MenuGlobal["menu" + a]._y + _root.MenuGlobal["menu" + a]._height;
	
	/*
		Pour chacun des sous menu un clone du symbole lié, ‘Bt_Base’, est attaché au sous menu global, puis 
		positionné et libellé. Le lien adéquat lui est attribué et une fonction est attachée au bouton. 
		Cette fonction va permettre de gérer l’action de notre barre de navigation. Afin de ne pas s’attarder
		sur cette finalité, une simple image s’affichera sur la scène pour en matérialiser l’effet (zone 8).
	*/
	for (var i = 0; i<LeMenuArray[a]["sousmenus"].length; i++) {
		_root.SousMenuGlobal.attachMovie(RefBouton,"smenu" + i, 610 + i);
		_root.SousMenuGlobal["smenu" + i].titre = LeMenuArray[a]["sousmenus"][i]["smenu"];
		_root.SousMenuGlobal["smenu" + i]._x = 0;
_root.SousMenuGlobal["smenu" + i]._y = i * _root.SousMenuGlobal["smenu" + i]._height; _root.SousMenuGlobal["smenu" + i].lien = LeMenuArray[a]["sousmenus"][i]["lien"]; _root.SousMenuGlobal["smenu" + i].bt.onRelease = function(){ AfficheImage(this._parent.lien); _root.SousMenuGlobal.removeMovieClip() } } };
Calque (Image)
/*
	Un clip vide nommé « image » est placé sur la  scène et positionné en fonction des deux variables 
	‘ImageX’ et ‘ImageY’ vues  dans le script de la zone 1. Bien que décrites en fin de commentaires, 
	ces deux  lignes sont exécutées au tout début de l’animation et ne font pas partie 
	de la  fonction de la zone suivante.
*/

  _root.createEmptyMovieClip("image",  100);
  _root.image._x = ImageX;
  _root.image._y = ImageY;
  
/*
  La   fonction AfficheImage() est interpellée par le bouton  du sous menu cliqué. Un LoadMovie charge l’image 
  adéquate dans le clip  « image ». L’image est identifiée par le paramètre ‘a’ passé par la fonction. 
  Les images  étant dans un dossier « Images », le début du chemin est  concaténé  à ce paramètre «images/» + a.
*/  
  
AfficheImage = function (a) {
	_root.image.loadMovie("Images/"+a);
};

 


Puce et Média