Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Utilisation des boucles en ActionScript 3

Compatible ActionScript 3. Cliquer pour en savoir plus sur les compatibilités.Par tannoy (Antony Chauviré), le 24 février 2011

C'est quoi une boucle ?

Une boucle, c'est une structure de contrôle qui va vous permettre d'exécuter les mêmes instructions plusieurs fois de suite.

On pourrait prendre l'exemple d'un nageur qui va exécuté plusieurs fois de suite des mouvements de bras et de jambes identiques pour réaliser une course ou un entraînement.

Par contre, il va falloir indiquer à notre traitement de s'arrêter à un moment donné car contrairement à notre nageur, l'ordinateur ne va pas se fatiguer et est capable de répéter les instructions à l'infini.

C'est pourquoi, on indique toujours une condition de fin à une boucle. Dans le cas de notre nageur, la condition de fin serait la distance de course (50m, 100m…) ou la durée de l'entraînement (30mn, 1h…)

Nous allons voir 5 types de boucles en ActionScript 3:

  • while
  • do…while
  • for
  • for…in
  • for each…in

La boucle while

Définition

La boucle while permet d'exécuter un bloc de code tant qu'une condition est vrai

Syntaxe

La syntaxe d'une boucle while est la suivante:

while(/* condition */)
{
    //Instructions à répéter
}

On peut donc traduire le bloc de code par:
Tant que la condition est vraie, répète les instructions entre les accolades

Exemple

var compteur:int = 1;
while (compteur < 11)
{
	trace("Bienvenue chez Mediabox");
	compteur++;
}

Les explications de l'exemple ci-dessus:

  1. Nous avons une variable nommé compteur qui vaut 1 au départ du programme.
  2. La boucle while indique de réaliser les traitements tant que le compteur est inférieur à 11. Le compteur valant 1, nous allons donc rentrer dans la boucle
  3. Et afficher le texte « Bienvenue chez Mediabox » dans la fenêtre de sortie avec l'instruction trace().
  4. Nous demandons ensuite au compteur d'augmenter sa valeur de 1 en utilisant l'opérateur d'incrémentation ++. Le compteur vaut désormais 2.
  5. L'accolade fermante indique la fin de la boucle donc on repart au début et on refait le test du while. Le compteur, qui a pour valeur 2, est bien inférieur à 11 donc on entre de nouveau dans la boucle pour réaliser les instructions

Les opérations vont se répéter jusqu'à ce que compteur prenne la valeur 11 et donc dans ce cas, le compteur n'est pas strictement inférieur à 11, le résultat de la condition est faux donc le programme sort de la boucle.

La boucle do...while

La boucle do…while ressemble fortement à la boucle while. Elle permet elle aussi d'exécuter un bloc de code tant qu'une condition est vrai mais par contre elle exécute d'abord le bloc d'instructions puis examine la condition. Cela signifie donc que le bloc de code est exécuté au moins 1 fois.

Cette boucle est beaucoup moins utilisé que la précédente.

Nous allons prendre l'exemple d'une application AIR qui veut créer un fichier de log dans un dossier contenant déjà des fichiers et qui va incrémenter un index tant qu'il trouvera un fichier portant déja ce nom.

var compteur:int = 1;
do {
  file.name = "log" + (++compteur);
}
while (file.exist ());
file.write();
Merci à dada pour l'exemple.

La boucle for

La boucle for est une équivalence à la boucle while mais écrite de façon différente.

Syntaxe

La syntaxe d'une boucle for est la suivante:

for(/* initialisation */; /* condition */; /* valorisation */)
{
    //Instructions à répéter
}

Le traitement d'une boucle for nécessite 3 expressions :

  1. L'initialisation permet de définir la valeur de départ du compteur de la boucle.
  2. La condition, comme pour la boucle while, permet d'indiquer si la boucle doit s'arrêter ou continuer.
  3. La valorisation permet à chaque fin de tour de boucle, de définir la nouvelle valeur du compteur

Exemple

for(var i:int = 0; i<11; i++)
{
	trace(i + ". Bienvenue chez Mediabox");
}

Les explications de l'exemple ci-dessus:

  • Dans une boucle for, on utilise généralement une variable nommée i en tant que compteur. Cependant, rien ne vous empêche de donner le nom que vous souhaitez à votre variable. Par convention et afin que le code puisse être lisible par un grand nombre de personnes, je vous conseille d'utiliser i.
  • Il est possible de déclarer le compteur à l'intérieur ou à l'extérieur du for
    var i:int = 0;
    for(i; i<11; i++)
    {
    	trace(i + ". Bienvenue chez Mediabox");
    }
  • La valorisation du compteur à la fin d'un tour de boucle se fera généralement par une incrémentation (augmentation de la valeur de 1) en utilisant l'opérateur ++ précédé du compteur (i++). On pourra aussi faire une décrémentation (diminution de la valeur de 1), i– ou n'importe quelle valorisation comme par exemple si on souhaite avance de 5 en 5, on utilisera alors i += 5 qui signifie que la nouvelle valeur sera égale à la valeur actuelle plus 5.

Un exemple concret d'utilisation d'une boucle: une table de multiplication

Présentation

Nous allons voir à travers cet exemple, une petite application permettant d'afficher les tables de multiplication.

L'utilisateur pourra cliquer sur des boutons allant de 1 à 5 et la table de multiplication du nombre choisi s'affichera.

Voici l'application finale:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Préparation de l'interface

Afin de se focaliser sur le sujet qui vous intéresse, je vous propose donc de télécharger le fichier Fla de départ pour continuer la suite du tutoriel

Nous avons donc 5 boutons nommé bt1 jusqu'à bt5. Vous verrez que ces noms auront une importance par la suite. Ces boutons devront afficher la bonne table de multiplication lors du clic.

Si vous n'êtes pas familier avec l'utilisation des boutons et des événements, je vous encourage vivement à lire le tutoriel de Nataly: AddEventListener : Clics et événements souris sur les bouton et les clips

Le code

Nous allons donc ajouter aux boutons un écouteur pour l'événement clic. En réponse au clic sur l'un des boutons, une fonction d'écoute sera appelée et réalisera le traitement voulu.

import flash.events.MouseEvent;
 
bt1.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt2.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt3.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt4.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt5.addEventListener(MouseEvent.CLICK, button_clickHandler);
 
function button_clickHandler(event:MouseEvent):void
{
 
}

L'idée est que lorsque l'on clique sur un bouton, l'application nous affiche la table de multiplication du numéro du bouton.

Comme le traitement est le même pour tous les boutons, nous utiliserons une seule fonction d'écoute. Dans cette fonction, nous allons devoir connaître le bouton sur lequel on a cliqué, afin d'en récupérer son numéro.

Nous allons pour cela utiliser l'objet d'événement passé à la fonction d'écoute et en particulier sa propriété currentTarget.

import flash.events.MouseEvent;
import flash.display.SimpleButton;
 
bt1.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt2.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt3.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt4.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt5.addEventListener(MouseEvent.CLICK, button_clickHandler);
 
function button_clickHandler(event:MouseEvent):void
{
	var boutonClique:SimpleButton = SimpleButton(event.currentTarget);
}

Maintenant que nous connaissons le bouton sur lequel nous avons cliqué, nous allons récupérer son nom en utilisant la propriété name.

import flash.events.MouseEvent;
import flash.display.SimpleButton;
 
bt1.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt2.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt3.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt4.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt5.addEventListener(MouseEvent.CLICK, button_clickHandler);
 
function button_clickHandler(event:MouseEvent):void
{
	var boutonClique:SimpleButton = SimpleButton(event.currentTarget);
	var nomBouton:String = boutonClique.name;
}

Enfin, pour récupérer le numéro associé au bouton, nous allons extraite tout ce qui se trouve après les 2 premiers caractères du nom car nous avons nommé nos boutons bt1, bt2, bt3, bt4 et bt5.

Pour extraire du texte d'une chaîne de caractères, nous allons utiliser la méthode substring() de la classe String. Cette méthode attend un premier paramètre qui est le numéro du caractère à partir duquel l'extraction doit démarrer. Cette numérotation commence à 0 donc dans notre cas, nous allons utiliser la position 2 correspondant au 3ème caractère. Le second paramètre indique la position du caractère après laquelle l'extraction s'arrête. Ce paramètre est facultatif et lorsqu'il n'est pas indiqué, l'extraction se termine à la fin de la chaîne.

import flash.events.MouseEvent;
import flash.display.SimpleButton;
 
bt1.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt2.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt3.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt4.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt5.addEventListener(MouseEvent.CLICK, button_clickHandler);
 
function button_clickHandler(event:MouseEvent):void
{
	var boutonClique:SimpleButton = SimpleButton(event.currentTarget);
	var nomBouton:String = boutonClique.name;
	var numero:int = int(nomBouton.substring(2));
}

Maintenant que nous connaissons le numéro pour lequel on souhaite afficher la table de multiplication, nous allons créer une boucle démarrant à 1 et se terminant à 10 dans laquelle on réalisera l'affichage des lignes de la table de multiplication.

Nous allons dans un premier temps créer 2 variables définissant le début et la fin de la boucle et créer une boucle for permettant l'affichage des lignes dans le champ de texte. Nous allons aussi effacer le champ de texte avant de réécrire dedans.

import flash.events.MouseEvent;
import flash.display.SimpleButton;
 
bt1.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt2.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt3.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt4.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt5.addEventListener(MouseEvent.CLICK, button_clickHandler);
 
function button_clickHandler(event:MouseEvent):void
{
	var boutonClique:SimpleButton = SimpleButton(event.currentTarget);
	var nomBouton:String = boutonClique.name;
	var numero:int = int(nomBouton.substring(2));
	var compteur:int = 1;
	var finBoucle:int = 10;
	txtResultat.text = "";
	for(compteur; compteur <= finBoucle; compteur++)
	{
 
	}
}

Dans chaque passage de la boucle, nous allons créer une variable stockant le résultat de la multiplication de notre numéro avec le compteur.

import flash.events.MouseEvent;
import flash.display.SimpleButton;
 
bt1.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt2.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt3.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt4.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt5.addEventListener(MouseEvent.CLICK, button_clickHandler);
 
function button_clickHandler(event:MouseEvent):void
{
	var boutonClique:SimpleButton = SimpleButton(event.currentTarget);
	var nomBouton:String = boutonClique.name;
	var numero:int = int(nomBouton.substring(2));
	var compteur:int = 1;
	var finBoucle:int = 10;
	txtResultat.text = "";
	for(compteur; compteur <= finBoucle; compteur++)
	{
		var resultat:int = numero * compteur;
	}
}

Puis nous allons afficher l'opération et son résultat dans le champ de texte.

import flash.events.MouseEvent;
import flash.display.SimpleButton;
 
bt1.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt2.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt3.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt4.addEventListener(MouseEvent.CLICK, button_clickHandler);
bt5.addEventListener(MouseEvent.CLICK, button_clickHandler);
 
function button_clickHandler(event:MouseEvent):void
{
	var boutonClique:SimpleButton = SimpleButton(event.currentTarget);
	var nomBouton:String = boutonClique.name;
	var numero:int = int(nomBouton.substring(2));
	var compteur:int = 1;
	var finBoucle:int = 10;
	txtResultat.text = "";
	for(compteur; compteur <= finBoucle; compteur++)
	{
		var resultat:int = numero * compteur;
		txtResultat.appendText(compteur + " * " + numero + " = " + resultat + "\n");
	}
}

La boucle for each in

Définition

La boucle for each in permet d'itérer les items d'une collection qui peut-être un objet XML, un objet, un tableau… Elle renvoie directement l'item.

Syntaxe

for each(/* item */ in /* collection */)
{
    //Instructions à répéter
}

On peut donc traduire le bloc de code par:
Pour chaque élément dans la collection, répète les instructions entre les accolades

Exemple

var tableau:Array = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin"];
for each(var mois:String in tableau)
{
	trace(mois);
}

On remarque que l'élément de la boucle est directement utilisable dans les instructions.

La boucle for in

Définition

La boucle for in permet d'itérer sur les clefs (index) des propriétés d'un objet.

Syntaxe

for(/* index */ in /* objet */)
{
    //Instructions à répéter
}

On peut donc traduire le bloc de code par:
Pour chaque clé de ligne dans la collection, répète les instructions entre les accolades

Exemple

var semestre:Object = {"mois1":"Janvier", "mois2":"Février", "mois3":"Mars", "mois4":"Avril", "mois5":"Mai", "mois6":"Juin"};
for (var index:* in tableau)
{
	trace(tableau[index]);
}

Contrairement à la boucle for each…in, la boucle for…in renvoie la clé (index) de l'élément à traiter dans l'objet. On utilise donc l'opérateur d'accès au tableau pour récupérer la valeur de l'élément à traiter.

A noter qu'elle ne permet d'itérer que sur les propriétés créées dynamiquement, ce qui implique que la classe de la collection soit déclarée avec l'attribut dynamic (Array, Object, Dictionary, XML, XMLList, MovieClip, etc).

Stopper une boucle

L'instruction break permet de stopper une boucle et de terminer son exécution. Elle est souvent utilisée dans un test conditionnel dans la boucle.

Syntaxe

for each(/* item */ in /* collection */)
{
     if(/* condition */)
    {
        break;
    }
    //Instructions à répéter
}

Exemple

var tableau:Array = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin"];
for each(var mois:String in tableau)
{
	if(mois == "Mai")
	{
		break;
	}
}

Dans l'exemple précédent, nous arrêtons la boucle lorsque nous avons trouvé la valeur “Mai”.

Stopper une boucle dans une imbrication de boucles

Dans cet exemple, nous allons utiliser un tableau de films de type science-fiction et un tableau de films de type comédie. Ces 2 tableaux seront stockés dans un troisième tableau qui sera notre dvdthèque.

var film1:Object = { titre: "Les bronzés" };
var film2:Object = { titre: "La grande vadrouille" };
var film3:Object = { titre: "Marche à l'ombre" };
var comedie:Array = [];
var film4:Object = { titre: "Minority Report" };
var film5:Object = { titre: "Independence Day" };
var film6:Object = { titre: "Island" };
var scienceFiction:Array = [film4, film5, film6];
var dvdtheque:Array = [comedie, scienceFiction];

Nous souhaitons parcourir notre dvdthèque à la recherche du film Minority Report. Nous allons donc utiliser une première boucle pour parcourir les listes de films puis une seconde boucle pour parcourir les films d'une liste.

var film1:Object = { titre: "Les bronzés" };
var film2:Object = { titre: "La grande vadrouille" };
var film3:Object = { titre: "Marche à l'ombre" };
var comedie:Array = [];
var film4:Object = { titre: "Minority Report" };
var film5:Object = { titre: "Independence Day" };
var film6:Object = { titre: "Island" };
var scienceFiction:Array = [film4, film5, film6];
var dvdtheque:Array = [comedie, scienceFiction];
 
for each(var liste:Array in dvdtheque)
{
	for each(var film:Object in liste)
	{
 
	}
}

Nous allons donc utiliser une instruction break pour stopper la boucle des films lorsque nous avons trouvé le film voulu.

var film1:Object = { titre: "Les bronzés" };
var film2:Object = { titre: "La grande vadrouille" };
var film3:Object = { titre: "Marche à l'ombre" };
var comedie:Array = [];
var film4:Object = { titre: "Minority Report" };
var film5:Object = { titre: "Independence Day" };
var film6:Object = { titre: "Island" };
var scienceFiction:Array = [film4, film5, film6];
var dvdtheque:Array = [comedie, scienceFiction];
 
for each(var liste:Array in dvdtheque)
{
	for each(var film:Object in liste)
	{
		if(film.titre == "Minority Report")
		{
			break;
		}
	}
}

Le problème, c'est que nous arrêtons la boucle qui parcourt les films de la liste mais pas la boucle qui parcourt les liste de la dvdthèque or puisque nous avons trouvé notre film, ce n'est pas nécessaire de parcourir toute la dvdthèque.

Afin de pouvoir stopper une boucle précise avec une instruction break, nous allons utiliser une instruction label. Cette instruction permet de référencer une boucle avec un nom et donc d'utiliser ce nom avec une instruction break.

var film1:Object = { titre: "Les bronzés" };
var film2:Object = { titre: "La grande vadrouille" };
var film3:Object = { titre: "Marche à l'ombre" };
var comedie:Array = [];
var film4:Object = { titre: "Minority Report" };
var film5:Object = { titre: "Independence Day" };
var film6:Object = { titre: "Island" };
var scienceFiction:Array = [film4, film5, film6];
var dvdtheque:Array = [comedie, scienceFiction];
 
mesdvd: for each(var liste:Array in dvdtheque)
{
	for each(var film:Object in liste)
	{
		if(film.titre == "Minority Report")
		{
			break mesdvd;
		}
	}
}

Ignorer certaines instructions d'une boucle

Définition

L'instruction continue permet d'ignorer les instructions qui la suivent et passe à l'itération suivante de la boucle.

Exemple

Dans cet exemple, nous avons un tableau de nombres et nous souhaitons uniquement afficher les nombres pairs. Nous allons pour cela utiliser l'instruction continue dans un test conditionnel.

var tableau:Array = [12, 27, 5, 6, 14, 18, 21, 30];
for each(var nombre:int in tableau)
{
	if(nombre%2 != 0)
	{
		continue;
	}
	trace("Nombre pair: " + nombre);
}

Si le reste de la division est différent de 0, il s'agit donc d'un nombre impair et l'instruction trace n'est pas exécutée puisque l'instruction continue indique de passer à l'itération suivante.