Séparer le code des média

Quel intérêt?

Lors d’un projet on est rarement seul à travailler dessus. Et donc il peut arriver que le ou les graphistes aient à modifier les médias pendant que le ou les développeurs avancent sur le projet.

Il arrive aussi souvent d’avoir un projet multilingue. La séparation des média et des codes peut faciliter la tâche. Sur certain projet il suffira d’externaliser les textes dans un XML et ça ira ! Mais qu’en est-il des logos ? des FX qui possède du textes ? ou même l’intégration de texte dans le décors ? Très souvent un XML ne suffit pas pour toutes ces problématiques.

Il y a d’autres projets qui nécessite de changer de style à l’occasion de Noel, Halloween, l’été ou pour n’importe quelle raison ! Il faut pouvoir changer de média sans avoir à changer de code.

Une classe pour contrôler ses médias

Pour pouvoir gérer complètement et facilement la séparation du code et des médias j’ai créé la classe SharedLibrary.

Télécharger l’exemple

package  multifred.utils
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.display.Loader;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.display.LoaderInfo;
	import flash.system.ApplicationDomain;

	/**
	 * ...
	 * @author MultiFred
	 */
	public class SharedLibrary extends EventDispatcher
	{
		protected var _applicationDomain:ApplicationDomain;
		private var loader:Loader;
		/**
		 * Charge un swf et recupere son ApplicationDomain. Cette diffuse les evenement Event.COMPLETE, ProgressEvent.PROGRESS, IOErrorEvent.IO_ERROR et Event.INIT.
		 * @param	url 	URL de la bibliothèque (fichier swf)
		 */
		public function SharedLibrary(url:String)
		{
			_applicationDomain=new ApplicationDomain()
			loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
			loader.contentLoaderInfo.addEventListener(Event.INIT, onInit);
			loader.load(new URLRequest(url));
		}

		public function get applicationDomain():ApplicationDomain {
			return _applicationDomain;
		}

		public function get percent():Number {
			var val:Number
			try
			{
				val=loader.contentLoaderInfo.bytesLoaded / loader.contentLoaderInfo.bytesTotal;
			}
			catch (err:Error)
			{
				val=0
			}
			return val;
		}
		public function getClass(className:String):Class
		{
			return _applicationDomain.getDefinition(className) as Class;
		}

		public function createClip(className:String):DisplayObject
		{
			var TheClass:Class;
			var theClip:DisplayObject;

			TheClass = getClass(className);
			theClip = new TheClass();
			return theClip;
		}

		private function onComplete(evt:Event) {
			/*
			* Chargement des classes contenus dans le fichier swf chargé
			*/
			// récupération d'une instance d'ApplicationDomain
			// sur la propriété applicationDomain du contentLoaderInfo (e.target)
			_applicationDomain = LoaderInfo(evt.target).applicationDomain;
			dispatchEvent(new Event(Event.COMPLETE));
		}

		private function onProgress(evt:ProgressEvent) {
			dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS,false, false, evt.bytesLoaded, evt.bytesTotal));
		}

		private function onError(evt:IOErrorEvent) {
			dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR, false, false, evt.text));
		}

		private function onInit(evt:Event) {
			dispatchEvent(new Event(Event.INIT));
		}

	}

}

Cette classe va charger le fichier .swf à l’URL spécifié et va renvoyer les évènements INIT et COMPLETE. Une fois ce fichier chargé, vous pouvez récupérer les clips qui ont été exportés.

Pour cela je crée le fichier media.fla qui contient une animation de chargement. Au moment où je crée le Movieclip de l’animation je coche la case « Export for ActionScript » et je nomme la class « Loader ». Une fois cela terminé je compile media.swf.

Je crée les fichiers main.fla et Main.as qui contiennent le code.

package  {
	import flash.display.MovieClip;
	import multifreid.utils.SharedLibrary;
	import flash.events.Event;

	public class Main extends MovieClip{
		var library:SharedLibrary;
		var clipLoader:MovieClip;

		public function Main() {
			// constructor code
			library = new SharedLibrary("media.swf");
			library.addEventListener(Event.COMPLETE, onComplete);
		}

		function onComplete(evt:Event)
		{
			clipLoader = library.createClip("Loader") as MovieClip;
			this.addChild(clipLoader);
			clipLoader.x = stage.stageWidth*.5;
			clipLoader.y = stage.stageHeight*.5;

		}

	}

}

Compilez main.swf et vous verrez votre animation se jouer.