I. Introduction▲
Le but de ce tutoriel est de vous montrer comment créer un composant dans Flash MX 2004. Pour l'appréhender correctement, il est préférable d'avoir déjà de bonnes connaissances en Flash. Surtout en ce qui concerne les clips et les classes en général.
I-A. Qu'est-ce qu'un composant▲
Un composant est un objet intégrant toute une série de fonctionnalités utilisables dans n'importe quelle animation sans devoir déployer un effort particulier au niveau développement. Les composants sont disponibles dans la fenêtre des composants de Flash MX2004. Contrairement aux composants de Flash MX, ceux de MX 2004 sont compilés, il n'est donc plus possible d'éditer les composants standards tels que Checkbox, button, Scrollpane… L'avantage des composants est principalement leur réutilisabilité et leur paramétrage via la fenêtre des propriétés ou via l'inspecteur des composants. Un autre avantage est aussi que l'on peut distribuer un composant facilement. Si vous êtes indépendant, vous pourriez créer vos propres composants et les distribuer à vos clients. L'avantage est que le code associé au composant est compilé. De ce fait, la discrétion concernant la réalisation et le code source est préservée.
I-B. Quel type de composant nous proposons vous ?▲
Nous vous proposons une bannière d'images. Cette bannière chargera dans un scrollpane les images dont les chemins sont définis dans un fichier XML de votre choix. La structure de ce fichier XML est très simple et sera décrite plus loin. L'utilisation du composant est ultra simple.
I-C. Propriétés de notre composant▲
Description des propriétés
Nom de la propriété |
Valeur(s) possible(s) |
Description |
---|---|---|
Alpha |
true ou false |
Défini à true, un effet de transparence apparaîtra au survol des images. À false, aucun effet ne sera défini |
Fichier Son |
URL pointant sur l'emplacement du fichier son |
L'URL indiquera au composant quel fichier son il faut exécuter lors du clic sur une image. Si ce paramètre est vide, aucun son ne sera joué |
Fichier XML |
URL pointant sur l'emplacement du fichier XML |
L'URL indiquera au composant quel fichier XML contient les chemins des images |
Fonction associée |
Un nom de fonction que vous avez développé |
La valeur que vous attribuerez éventuellement à ce paramètre doit correspondre au nom d'une fonction que vous avez développée. Cette fonction sera alors déclenchée lorsque l'utilisateur cliquera sur une image. Si vous laissez ce paramètre vide, aucune action ne sera déclenchée lors du clic sur une image. Le composant passe le clip courant en paramètre à votre fonction. Vous comprendrez vite le fonctionnement en visionnant le fichier Banner.fla disponible en téléchargement |
Largeur Images |
un nombre |
Il sert à déterminer la coordonnée X des images. Si par exemple vous attribuez la valeur 100 à ce paramètre, les images seront positionnées tous les 100 pixels. Si vous avez des images de taille différente, il est préférable d'attribuer la plus grande taille à ce paramètre. Comme vous l'aurez sans doute deviné, il est préférable d'avoir des images de même taille pour un affichage parfait. |
I-D. À quoi ressemble-t-il ?▲
II. POO en MX2004▲
Avec Flash MX 2004, Macromedia a introduit l'actionscript 2 (AS2) et a radicalement changé la philosophie de développement dans Flash. L'AS2 propose à présent des concepts proches de ceux que l'on peut trouver dans Java et C++. De cette manière, ils « standardisent » la programmation objet en Flash et permettent aux développeurs Java et C++ de s'intéresser d'avantage à Flash et de l'appréhender plus rapidement.
II-A. Qu'est-ce que le classpath▲
Tout d'abord vous devez savoir que toute programmation de classe doit être faite dans un fichier externe à Flash. Les classes doivent être programmées dans les fichiers .as (Flash->nouveau document->fichier actionscript). Ces fichiers .as sont stockés quelque part sur le disque dur. Afin de ne pas restreindre le choix d'emplacement de ces fichiers, Flash utilise des classpath qui pointent vers ces emplacements.
Pour définir votre propre classpath, vous pouvez aller dans le menu Edition -> préférences -> onglet actionscript -> paramètres actionscript 2. Si vous ajoutez un classpath de type « c:\monclasspath\ », vous pourrez dorénavant stocker vos fichiers .as dans le répertoire c:\monclasspath\. Vous pouvez ajouter plusieurs classpaths.
II-B. Classe dynamique ou statique▲
Sans le mot clé « dynamic » précédent le mot clé « class », une classe actionscript 2 est considérée comme statique. Lorsqu'une classe est statique, on ne peut pas lui ajouter des propriétés ou méthodes de manière dynamique.
Lorsqu'une classe est dynamique, on peut lui ajouter autant de propriétés et de méthodes que l'on souhaite via l'occurrence de classe que l'on a instanciée.
Exemple :
//On crée juste une classe vide pour l'exemple
class
dvp{
function
dvp
(
){
}
}
//Dans un fla
var
dvpobj:
dvp=
new
dvp
(
);
dvpobj.
MaPropriete=
1
;
//Génère une erreur
En ajoutant le mot clé « dynamic » devant le mot clé « class », on sera autorisé à ajouter la propriété « MaPropriete ». Il en va de même pour les méthodes.
Notez cependant que cette protection ne paraît valable que lorsque l'on utilise le « strong typing », c'est-à-dire une déclaration de variable ressemblant à ceci :
var
dvpobj:
dvp;
Si nous avions déclaré la variable comme suit :
var
dvpobj=
new
dvp
(
);
Nous n'aurions pas eu de problèmes pour rajouter une propriété ou une méthode. Ceci est à mon sens un bug et ceci est malheureusement valable pour les méthodes et propriétés privées. Espérons que Macromédia réagisse rapidement à ce problème.
Le mot clé « static » s'applique aux propriétés et méthodes d'une classe. Lorsqu'on les préfixe de ce mot clé, elles sont uniquement accessibles au sein même de la classe ou par une classe ayant hérité de celle-ci. Ces méthodes et propriétés ne sont pas accessibles via l'occurrence de la classe.
Exemple :
class
dvp{
function
dvp
(
){
}
static
function
dvp_message
(
){
trace
(
"cette méthode est statique"
);
}
}
//Dans un FLA
var
dvpobj:
dvp=
new
dvp
(
);
dvpobj.
dvp_message
(
);
//Génère une erreur. Par contre, ceci est correct
dvp.
dvp_message
(
);
II-C. private et public▲
Une méthode ou propriété privée est une méthode qui ne peut être accédée par une occurrence de classe.
Exemple :
class
dvp{
function
dvp
(
){
}
private
function
affiche_message
(
):
Void
{
trace
(
"message"
);
}
//Dans un fla
var
dvpobj:
dvp=
new
dvp
(
);
dvpobj.
affiche_message
(
);
//Génère une erreur
En retirant le mot clé « private » devant la déclaration de la méthode ou en le remplaçant par « public », on aurait pu accéder à cette méthode via l'occurrence dvpobj. Comme je l'ai dit ci-dessus, ce n'est valable que lorsque l'on utilise le « strong typing ».
II-D. L'héritage▲
L'héritage s'effectue via le mot clé « extends ». Lorsqu'une classe hérite d'une autre classe, elle peut accéder à toutes les propriétés et méthodes de cette classe, même celles déclarées en « private ».
La syntaxe est simple :
class
dvp1{
function
dvp1
(
){
}
private
function
affiche_message
(
) :
Void
{
trace
(
"message"
);
}
}
//Dans un autre fichier de classe, on définit cette classe:
class
dvp2 extends
dvp1{
function
dvp2
(
){
affiche_message
(
);
}
}
Étant donné que dvp2 a hérité des propriétés et méthodes de dvp1, on peut directement appeler une méthode de dvp1.
Note : lorsque l'on fait référence à une méthode ou une propriété, on peut préfixer cette référence via le mot clé « this ».
II-E. interface et implements▲
Une interface représente une définition de méthodes. Cette définition devra être respectée par les classes implémentant cette interface. L'interface ne peut contenir :
- de déclaration de propriété ;
- d'implémentation de méthode ;
- l'usage de méthodes « private » ou « static ».
L'interface comprend en somme le prototype des méthodes qui devront être utilisées par les classes qui implémentent cette interface.
Exemple :
//définition d'une interface
interface
dvp_interface {
function
dvp2
(
):
Number
;
function
dvp3
(
):
String
;
}
//définition d'une classe implémentant cette interface
class
dvp implements
dvp_interface{
function
dvp2
(
):
Number
{
return
10
;
}
function
dvp3
(
):
String
{
return
"dvp"
;
}
}
//Cette classe est correcte, car elle respecte bien l'interface dvp_interface.
class
dvp implements
dvp_interface{
function
dvp2
(
):
String
{
return
"dvp"
;
}
function
dvp3
(
):
String
{
return
"dvp"
;
}
}
//dvp_interface. En effet la méthode dvp2 retourne un type String alors qu'elle est censée retourner un Number.
Note : toutes les méthodes définies dans l'interface doivent être implémentées dans une classe qui implémente l'interface. En cas d'omission d'une déclaration de méthode, le compilateur génèrera une erreur.
L'intérêt des interfaces est de pouvoir consolider et valider son code. Si l'on base plusieurs classes sur la même interface, on saura que toutes ces classes implémentent les méthodes définies dans l'interface. Les interfaces permettent en somme d'ajouter un peu de rigueur dans le développement.
III. Étapes de création de notre composant▲
Maintenant que vous avez vu sommairement les concepts liés aux classes, on peut passer à la pratique. Pour la création du composant bannière, j'ai procédé comme suit :
Étapes |
|
---|---|
Création d'un clip vide nommé « Banner ». |
Cliquez sur le menu « insertion » -> « New symbol » -> « Movie clip » et nommez-le « Banner » |
Liaison de la classe Banner dont le code est expliqué plus bas avec le clip « Banner » |
Affichez la bibliothèque (CTRL+L) -> Cliquez avec le bouton droit sur le clip « Banner », choisissez « Linkage » -> Export for Actionscript(décochez « Export in first frame ») ->Dans la zone « AS 2.0 Class », tapez Banner (correspond au nom de la classe Banner.as)-> Cliquez sur OK |
Définition du composant |
Réaffichez la bibliothèque, cliquez avec le bouton droit sur le clip Banner -> Component definition -> Dans la zone « AS 2.0 Class », tapez Banner -> Cliquez sur OK -> Si tout s'est bien passé, l'aspect du clip « Banner » a changé. Une icône représentant un composant et le mot « Component » devraient apparaître à côté du clip |
Exportation du composant |
Réaffichez la bibliothèque, cliquez avec le bouton droit sur le clip Banner -> Export SWC file. Le répertoire dans lequel il faut stocker les composants dépend de votre système d'exploitation, pour être certain de trouver ce répertoire, faites une recherche sur le répertoire « Components ». Sur XP, ce répertoire se trouve normalement ici: |
Redémarrez Flash |
IV. Code de la classe à associer au composant▲
Vous l'aurez deviné, il faut bien sûr d'abord écrire la classe avant de procéder aux étapes décrites ci-dessus.
//Liste des paramètres disponibles dans le panneau des propriétés
/*
Inspectable est une "balise" de type metadata interprétée par flash.
Dans notre exemple, la structure est toujours la même
-name représente ce qui va être affiché dans le panneau des propriétés
-variable est le nom de la variable qui stockera la valeur entrée
-type est le type de variable
-defaultValue est la valeur par défaut si l'utilisateur n'attribue pas d'autre valeur
-enumation permet d'afficher une liste de valeurs à l'utilisateur
*/
[
Inspectable
(
name
=
"Largeur Images"
,
variable
=
"imgwidth"
,
type
=
"Number"
,
defaultValue=
100
)]
[
Inspectable
(
name
=
"Fichier XML"
,
variable
=
"xmlfile"
,
type
=
"String"
,
defaultValue=
""
)]
[
Inspectable
(
name
=
"Fonction associée"
,
variable
=
"onpressevent"
,
type
=
"String"
,
defaultValue=
""
)]
[
Inspectable
(
name
=
"Alpha"
,
variable
=
"playalpha"
,
enumation "true,false"
,
type
=
"Boolean"
,
defaultValue=
false
)]
[
Inspectable
(
name
=
"Fichier Son"
,
variable
=
"soundfile"
,
type
=
"String"
,
defaultValue=
""
)]
dynamic
class
Banner extends
MovieClip
{
public
var
__imageWidth:
Number
;
public
var
__xmlFile:
String
;
private
var
_XmlParser:
XML
;
public
var
__ImagesArray:
Array
;
public
var
__left:
Number
=
0
;
public
var
__function:
String
;
public
var
__alpha:
Boolean
;
public
var
__sound:
Sound
;
public
var
__soundFile:
String
;
//Constructeur
function
Banner
(
){
this
.
init
(
);
}
/*Initialisation des propriétés avec les valeurs reçues en paramètre via le panneau
des propriétés du composant.
*/
function
init
(
){
__imageWidth=
this
.
imgwidth;
__xmlFile=
this
.
xmlfile;
__function=
this
.
onpressevent;
__alpha=
this
.
playalpha;
//Gestion du son, si le fichier son a été donné en paramètre, on le charge
__soundFile=
this
.
soundfile;
if
(
__soundFile !=
""
){
__sound=
new
Sound
(
);
__sound.
onLoad
=
function
(
success){
if
(
success){
this
.
__soundOk=
true
;
}
}
__sound.
loadSound
(
__soundFile,
false
);
}
if
(
__xmlFile !=
""
){
this
.
ParseXml
(
);
}
}
/*Cette fonction parse le fichier XML afin de récupérer les chemins des images.
Elle est assez simple étant donné que la structure du fichier XML l'est
*/
private
function
ParseXml
(
){
XmlParser=
new
XML
(
);
XmlParser.
Owner=
this
;
//Astuce pour lier la méthode onLoad de XML et l'objet courant
XmlParser.
onLoad
=
function
(
success){
if
(
success){
XmlParser.
Owner.
__ImagesArray=
new
Array
(
);
for
(
i=
0
;
i<
this
.
firstChild
.
childNodes
.
length
;
i++
){
if
(
this
.
firstChild
.
childNodes
[
i].
attributes
.
path !=
undefined
){
//Ici on construit un tableau qui contiendra tous les chemins des images
XmlParser.
Owner.
__ImagesArray.
push
(
this
.
firstChild
.
childNodes
[
i].
attributes
.
path);
}
}
XmlParser.
Owner.
BuildClip
(
);
}
}
//Instruction pour charger le fichier XML
XmlParser.
load
(
__xmlFile);
}
private
function
BuildClip
(
){
//On parcourt notre tableau
for
(
i=
0
;
i<
__ImagesArray.
length
;
i++
){
//On crée un clip vide
this
.
createEmptyMovieClip
(
"img"
+
i,
i);
i
//Si un nom de fonction a été donné en paramètre, il faut l'affecter à l'évènement onPress du clip
if
(
__function !=
""
){
this
[
"img"
+
i].
Owner=
this
;
this
[
"img"
+
i].
onPress
=
function
(
){
if
(
this
.
Owner.
__sound.
__soundOk){
//Si le son a été chargé
this
.
Owner.
__sound.
start
(
);
}
eval
(
this
.
Owner.
__function)(
this
);
}
}
//Cette partie gère la transparence de l'image selon le paramètre alpha du composant
if
(
__alpha){
this
[
"img"
+
i].
onRollOver
=
function
(
){
this
.
_alpha
=
50
;
}
this
[
"img"
+
i].
onRollOut
=
function
(
){
this
.
_alpha
=
100
;
}
}
/*On recrée un clip vide, car ici aussi il y a une astuce. Pour pouvoir charger l'image dans un clip et attribuer une
action à l'évènement onPress, il faut passer par deux clips vides, car le loadMovie "écrase" la méthode onPress affectée.
Donc, on crée un premier clip vide "conteneur" auquel on associe une action à onPress et, dans ce clip, on en crée un
deuxième qui contiendra l'image.*/
this
[
"img"
+
i].
createEmptyMovieClip
(
"sub_img"
+
i,
i);
with
(
this
[
"img"
+
i][
"sub_img"
+
i]
) {
//On positionne l'image grâce au paramètre "largeur d'images" passé au composant
_x
=
this
.
__left;
_y
=
20
;
loadMovie
(
this
.
__ImagesArray[
i]
);
}
__left+=
__imageWidth;
}
/*Le composant étant attaché à un clip qui lui-même est lié à un scrollpane. On sait que le parent du composant
est le clip et que le parent du clip est le scrollpane. Étant donné que le Scrollpane est probablement le composant
standard le plus ennuyeux à utiliser dû à son comportement pas toujours très cohérent. J'ai été obligé d'appeler la méthode
redraw qui redessine le scrollpane après chargement de son contenu. Sans cet appel, le scroll n'affichait pas tout le contenu
chargé. De surcroît, un simple appel à redraw ne suffisait pas, il fallait absolument l'appeler via un évènement associé au
scrollpane, comme mouseMove ou mouseUP. Si vous trouvez une autre méthode, faites-moi signe :-)*/
if
(
this
.
_parent
.
_parent
!=
undefined
){
this
.
_parent
.
_parent
.
onMouseMove
=
function
(
){
this
.
redraw
(
true
);
}
}
}
V. Structure du fichier XML▲
La structure du fichier XML est on ne peut plus simple. Pour pouvoir utiliser le composant, vous allez devoir créer votre propre fichier XML qui devra OBLIGATOIREMENT respecter cette structure :
<images>
<img
path
=
"http://stephaneey.developpez.com/cameleon.jpg"
></img>
<img
path
=
"http://stephaneey.developpez.com/lemurien.jpg"
></img>
<img
path
=
"http://stephaneey.developpez.com/escargot.jpg"
></img>
<img
path
=
"http://stephaneey.developpez.com/cameleon.jpg"
></img>
<img
path
=
"http://stephaneey.developpez.com/lemurien.jpg"
></img>
<img
path
=
"http://stephaneey.developpez.com/escargot.jpg"
></img>
</images>
Pour faciliter la compréhension du mécanisme, le contenu du fichier XML ci-dessus est le même que celui du fichier XML que j'ai utilisé dans la section « A quoi ressemble-t-il? »
L'attribut « path » contient l'URL où se trouve l'image à afficher et est récupéré par le composant dans la méthode « ParseXml ».
Note: pour des raisons de sécurité, Flash n'autorise pas le chargement de fichier XML ou autre se trouvant dans un autre domaine que le swf. Donc, si votre animation tourne sur http://www.monsite.com/animation.swf, le fichier xml doit aussi se trouver sur http://www.monsite.com/ ou un sous-répertoire de cette racine web.
VI. Particularité du paramètre fonction du composant▲
Comme nous l'avons vu plus haut, un paramètre « fonction » est associé au composant et vous permet d'exécuter votre propre fonction lorsque l'utilisateur clique sur une image.
Le composant passe l'instance du clip contenant l'image à cette fonction. Vous devrez donc déclarer un argument à celle-ci, comme montré ci-dessous.
function
ma_fonction
(
obj){
// l'argument obj contiendra l'instance du clip contenant l'image cliquée
trace
(
obj);
}
Cela vous permettra d'exécuter des actions particulières sur votre clip.
VII. Intégrer ce composant dans une animation Flash▲
Pour intégrer le composant dans une animation Flash, il faut procéder aux étapes suivantes :
- créez un clip et nommez-le comme vous voulez ;
- insérez-y le composant (drag and drop) sur la scène, aux coordonnées x:0 et y:0 OBLIGATOIREMENT ;
- renseignez les propriétés du composant (le paramètre fonction n'est pas obligatoire) ;
- affichez la bibliothèque, sélectionnez le clip et liez-le à actionscript (clic droit->linkage) ;
- revenez sur la scène principale ou dans un autre clip et insérez-y un composant scrollpane (drag and drop) ;
- via le panneau des propriétés du scrollpane, insérez le nom de votre clip dans la propriété contentPath ;
- n'oubliez bien sûr pas de créer votre fichier XML comme expliqué en section 5 ;
Et voilà, vous pouvez lancer votre animation !
VIII. Téléchargement▲
- Téléchargez le fichier zip et dézippez-le sur votre machine.
- Procédez aux étapes décrites en section 3.
IX. Conclusion▲
Vous êtes à présent capable de créer vos propres composants ou de faire évoluer celui-ci. Afin de vous pousser à reproduire les étapes décrites en section 3, j'ai laissé intentionnellement le clip « Developpez.com. Club … » dans le composant. Si vous désirez l'enlever, il vous faudra recréer le composant. Au cas où vous le recréez, vous devrez changer une ligne de code dans la classe actionscript2. La ligne :
_y
=
20
;
devra être remplaçée par :
_y
=
0
;