Flash tutoriel drag and drop

De EduTech Wiki
Aller à la navigation Aller à la recherche

Introduction

Déplacer et déposer des objets ("drag and drop") est l'un des exercices les plus populaires dans le domaine des logiciels éducatifs. Cette section fait partie des tutoriels Flash CS4. Elle est plutôt réservée aux designers ayant déjà une petite expérience de programmation.

Note concernant CS5: Les fichiers marchent dans CS5, mais il faudrait imbriquer (embedd) les fontes. Sélectionner les zones de texte, cliquer sur "embedd" dans le properties panel et exporter au moins les caractères latin..... à préciser dans une édition future - Daniel K. Schneider 20 octobre 2010 à 20:05 (CEST).

Objectifs d´apprentissage
  • Apprendre à créer un simple programme drag and drop avec les composants Flash 9 (CS3)
  • Apprendre un peu d´Action Script 3

Prérequis

Dessin
Interactivité
Qualité et niveau
Ce tutoriel aidera les adeptes de la technique à démarrer. Le niveau de ce tutoriel pourrait être un peu élevé pour les novices mais peut servir de guide lors d'ateliers pratiques. Toutefois, certains éléments avancés ne seront pas expliqués ici.
Matériel d'apprentissage

Fichiers *.fla files à manipuler :

http://tecfa.unige.ch/guides/flash/ex/drag-and-drop-intro/

Astuce : cette page contient plus de code que de captures d'écrans. Il est conseiller de télécharger le code source et de jouer avec.

Résumé des étapes décrites dans ce tutoriel
  • Dessinez quelque chose sur la scène
  • Transformez-le en symbole animé (pas de bouton !)
  • Assignez-lui un nom d'instance
  • Nom_instance.startDrag()
  • Nom_instance.stopDrag()
  • Testez si l'objet est situé sur un objet cible (target) et coder l'action dans le script.

Code simple pour déplacer un objet

La capture d'écran ci-dessous est une simple application drag and drop : déplacer un cercle et un rectangle.

flash-cs3-drag-and-drop-intro.fla

Most simple drag and drop
Étape 1 - Dessinez un objet
  • Un objet simple, comme une forme par exemple
Étape 2 - Transformez cet objet en clip d'animation (Movie clip)
  • Pour cela, sélectionnez l'objet (ou tous les objets si vous en avez dessiné plusieurs pour composer votre dessin)
  • Clic droit>convert to symbol>movie clip
  • Donnez un nom d'instance à ce symbole dans le panneau de propriétés !
  • Attention! Si le movie clip que vous venez de créer contient à l'intérieur un objet de type texte (ou zone de texte), vérifiez que ce soit du texte simple. Modifiez les propriétés du texte dans le panneau properties panel en Static Text (texte statique). La fonction de drag ne marche pas sur du texte dynamique et encore moins sur du texte de type TLF
Étape 3 - Adaptez le code ci-dessous

Le code pour le drag and drop est particulièrement simple et suit les mêmes principes que ceux présentés dans le tutoriel Flash CS4 - Boutons.

  • le principe : associer un écouteur d'événement ("event listener") avec une fonction gestionnaire d'événement. Cette fois-ci, nous surveillons les événements "mouse down" et "mouse up" et pour chacun de ces événements nous devons définir une fonction qui va nous permettre d'effectuer le déplacement de l'objet avec la souris.
// Enregistre les fonctions d´événements de souris
blue_btn.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
blue_btn.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);

red_btn.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
red_btn.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);

// Définit le déplacement lorsque le bouton de la souris est enfoncé (l´utilisateur déplace l´objet)
function mouseDownHandler(evt:MouseEvent):void {
	var object = evt.target;
	// Limite le déplacement dans la zone définie
	object.startDrag();
}

function mouseUpHandler(evt:MouseEvent):void {
	var obj = evt.target;
		obj.stopDrag();
}
Résultats

Déplacer et déposer un objet sur un autre objet (drag and drop)

L'objectif est ici de créer une petite application Flash qui pourra dire à l'utilisateur s'il a correctement déplacé et déposé un objet sur un autre.

Étape 1 - Reprenez les étapes précédentes
  • A savoir : nous voulons que l'utilisateur dépose le bouton rouge sur le bouton bleu.
Étape 2 - Créez une zone de texte

Cette zone de texte sert à donner les instructions du jeu, puis un feedback "made it" (réussi) and "missed" (raté).

  • Utilisez l'outil Textool dans le panneau outil, puis entrez le texte.
  • Modifiez les propriétés du texte dans le panneau properties panel en Dynamic Text (texte dynamique).

Exemple pour flash CS3

Dynamic Text

Exemple pour flash CS5

  • Si le texte ne s'affiche pas correctement, cliquez dans la zone de texte, puis cliquez sur "embed" dans le panneau des propriétés. Dans la fenêtre qui s'ouvre, dans le champ de droite, donnez un nom à votre police de caractère ("myFont" par exemple), puis cliquez sur "ok". Rendez vous à nouveau dans le panneau des propriétés, et déroulez le menu "family". Vers le haut de ce menu, vous trouverez votre police avec une étoile à côté. Sélectionnez-la. Maintenant, le texte s'affichera correctement

ExempleCS5TF.jpg

Attention: Dans le cas où vous souhaiteriez ajouter du texte en français comportant des lettres avec accent (ex. "é"), il vous faudra sélectionner la case "All" lorsque vous ferez la manipulation "Embed", sans quoi si vous cochez "Basic Latin" par exemple, vos mots avec accent n'apparaîtront pas lorsque vous lancerez votre fichier *.fla.

Étape 3 - Code Action script
// Enregistre les fonctions d´événements de souris
blue_btn.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
blue_btn.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);

red_btn.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
red_btn.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);

// Définit l´événement mouse down handler (l´utilisateur déplace l´objet)
function mouseDownHandler(evt:MouseEvent):void {
	var object = evt.target;
	// limite le déplacement à l´intérieur du canevas
	object.startDrag();
}

function mouseUpHandler(evt:MouseEvent):void {
	var obj = evt.target;
	// obj.dropTarget donne la référence de la forme de l´objet sur laquelle déposer le bouton
	var target = obj.dropTarget;
	// Si l´objet existe ET qu´il s´agit du bouton bleu, alors le texte change. Comme obj.dropTarget est une forme, nous avons besoin de son parent.
	if (target != null && target.parent == blue_btn)
	{
		textField.text = "Made it !!";
	}
	else
	{
		textField.text = "Missed :(";
	}
	obj.stopDrag();
}
Résultats
Sources CS3
Sources CS5
Améliorations possibles
  • Styling de la zone de texte : à faire avec le panneau filtres (filters panel). Cliquer sur le signe + pour ajouter des filtres et utiliser les options disponibles.
  • Remettre le cercle rouge dans sa position initiale
  • Ajouter éventuellement des effets spéciaux

Application drag and match (version pour débutants)

Exemple 1

L'objectif est de déplacer des objets sur une zone de texte contenant la première lettre du nom de l'objet. Exemple : "Cat" devrait être déposé sur la boîte "C". Si l'objectif est atteint, l'utilisateur recevra un feedback positif et ne pourra plus bouger l'objet.

Étape 1 - Créez des objets movie clips
  • Suivez la même procédure que celle présentée plus haut pour les boutons rouges et bleus
  • Chaque objet devrait avoir un nom d'instance
Étape 2 - Créez des zones de texte
  • Suivez la procédure présentée plus haut
  • Créez une zone de texte pour chaque objet (Ex : "C" pour chat, etc.)
  • Assurez-vous que ces zones sont dynamiques et qu'elles portent un nom.
Étape 3 - Premier plan/Arrière plan

Assurez-vous que les zones de texte se situe à l'arrière plan et que les movie clips se situent au premier plan. Dans le cas contraire, l'objet à déposer ne trouvera pas sa cible.

  • Sélectionnez tous les movie clips et clic droit->Arrange->Bring to Front.
Étape 4 - Écrivez le code Action script

Le code ci-dessous est assez épouvantable mais il présente l'avantage d'utiliser une variété minimale d'AS3.

var hits = 0;

// Enregistre les fonctions d´événements de souris

dog.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
dog.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
rocket.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
rocket.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
cat.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
cat.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
bat.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
bat.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);

// Définit l´événement mouse down handler (l´utilisateur déplace l´objet)
function mouseDownHandler(evt:MouseEvent):void {
	var object = evt.target;
	// limite le déplacement à l´intérieur du canevas
	object.startDrag();
}

function mouseUpHandler(evt:MouseEvent):void {
	var obj = evt.target;
	// obj.dropTarget donne la référence de la forme de l´objet sur laquelle déposer l´objet
	var target = obj.dropTarget;
	// Si la cible existe, alors nous demandons à la fonction test_match function de comparer 
	//moved obj and target à l´endroit déposé.
	if (target != null)
	{
		test_match(target, obj);
	}
	obj.stopDrag();
}

function test_match(target,obj) {
	// Teste si l´une des quatre paires va ensemble
	if ( (target == box_c && obj == cat) ||
             (target == box_d && obj == dog) ||
	     (target == box_r && obj == rocket) ||
             (target == box_b && obj == bat) )
	{
		// Une paire va ensemble
		hits = hits+1;
		textField.text = "Yes ! You got one !";
		// Rendre l´objet transparent
		obj.alpha = 0.5;
		// Supprime l´écouteur d´événement. L´objet ne peut plus être bougé
		obj.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
		obj.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		// Vérifie si le jeu est fini
		if (hits == 4)
		{
			textField.text = "Made it !!";
		}
	}
	else
	{
		textField.text = "Missed :(";
	}
}
Résultats

Source CS3:

Source CS5:

Exemple 2

Application drag and drop simple, avec bouton et utilisation de MovieClip(root).

Pour voir le tutoriel et le résultat concret, c'est ici.

Application drag and match - autre version, un peu meilleure

Au lieu d'écrire une application uniquement pour quatre paires, nous pouvons écrire un code plus général. Ce code nécessite seulement quelques petites modifications pour adapter d'autres noms d'instances et de zones de texte. Vous pourrez ainsi insérer le nombre de paires que vous souhaitez. Assurez-vous simplement que les zones de texte cibles sont situées en arrière plan.

var dict = new Dictionary ();

// =================== START USER Config =====================
// Insérez autant de "dict[text_box] = movie;" que vous le souhaitez.
// Remplacez : text_box par le nom d'une zone de texte dynamique et movie par le nom de l'instance d'animation que l'utilisateur peut déplacer.

dict[box_c] = cat;
dict[box_d] = dog;
dict[box_r] = rocket;
dict[box_b] = bat;
dict[box_a] = apple;

// Ne changez/n´effacez AUCUNE autre ligne. Assurez-vous également de respecter la syntaxe (n´oubliez pas par exemple le ";" à la fin de chaque ligne.
// ===================== END USER Config ==================== 

var hits = 0; // compte le nombre de bonnes réponses
var max = 0;  // calcule la longueur de dictionary

// Pour chaque item dans le dictionary, nous ajoutons un écouteur d´événements
// "for each" va tourner en boucle entre les valeurs

for each (var item in dict)
{
	item.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
	item.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
	item.buttonMode = true; //needed for the hand cursor to work
	max = max + 1;
}


// Définit l´événement mouse down handler (l´utilisateur déplace l´objet)
function mouseDownHandler(evt:MouseEvent):void {
	var object = evt.target;
	// limite le déplacement à l´intérieur du canevas
	object.useHandCursor = true;
	object.startDrag();
}

function mouseUpHandler(evt:MouseEvent):void {
	var obj = evt.target;
	// obj.dropTarget donne la référence de la forme de l´objet sur laquelle déposer l´objet
	var target = obj.dropTarget;
	// Si la cible existe, alors nous demandons à la fonction test_match function de comparer 
	//moved obj and target à l´endroit déposé.
	// Pour comparer obj et target à l´endroit déposé
	if (target != null)
	{
		test_match(target, obj);
	}
	obj.stopDrag();
}

function test_match(target,obj) {
	// Teste si les paires vont ensemble
	if (dict[target] == obj)
	{
		// Une paire va ensemble
		hits = hits+1;
		textField.text = "Yes ! You got one !";
		// Rend l´objet transparent
		obj.alpha = 0.5;
		// Supprime l´écouteur d´événement. L´objet ne peut plus être bougé
		obj.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
		obj.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		// Vérifie si le jeu est fini
		if (hits == max)
		{
		        // Ici nous pouvons jouer une animation
			textField.text = "Made it !!";
		}
	}
	else
	{
		textField.text = "Missed :(";
	}
}
Résultats
Améliorations possibles
  • Rendre l'application plus "flashy" quand il y a réussite/échec et quand le jeu est terminé.
  • Ajouter du son. Un enfant ne peut pas lire des instructions mais un parent peut les expliquer:)
  • Ramener l'objet à sa position d'origine en cas d'échec.

Application drag and match - autre version, encore meilleure

Cette version comprendra

  • Du son (chargé depuis des fichiers externes !)
  • Des objets qui reprennent leur place d'origine
// Daniel K. Schneider - TECFA - sept 2007
// Copyright: See http://edutechwiki.unige.ch/en/

var dict = new Dictionary ();

// =================== START USER Config =====================
// Insérez autant de "dict[text_box] = movie;" que vous souhaitez
// Remplacez : text_box par le nom d'une zone de texte dynamique et movie par le nom d'une instance d'animation que l'utilisateur peut déplacer.

dict[box_c] = cat;
dict[box_d] = dog;
dict[box_r] = rocket;
dict[box_b] = bat;
dict[box_a] = apple;

// Ne changez/n´effacez AUCUNE autre ligne. Assurez-vous également de respecter la syntaxe (n´oubliez pas par exemple le ";" à la fin de chaque ligne.
// ===================== END USER Config ==================== 

// Son
var request:URLRequest = new URLRequest("applause_3.mp3");
var applause:Sound = new Sound();
applause.load(request);

var request2:URLRequest = new URLRequest("music.mp3");
var music:Sound = new Sound();
music.load(request2);

var request3:URLRequest = new URLRequest("baby_laugh.mp3");
var laugh:Sound = new Sound();
laugh.load(request3);

// Code Drag and match
var hits = 0; // counts succesful hits
var max = 0;  // used to compute dictionary length

var ori_x;
var ori_y;

// Pour chaque item dans le dictionary, nous ajoutons un écouteur d´événements
// "for each" va tourner en boucle entre les valeurs

for each (var item in dict)
{
	item.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
	item.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
	max = max + 1;
	item.buttonMode = true;
}


// Définit l´événement mouse down handler (l´utilisateur déplace l´objet)
function mouseDownHandler(evt:MouseEvent):void {
	var object = evt.target;
	ori_x = object.x
	ori_y = object.y
	object.useHandCursor = true;
	object.startDrag();
}

function mouseUpHandler(evt:MouseEvent):void {
	//stopper tous les sons
	SoundMixer.stopAll();
	var obj = evt.target;
	// obj.dropTarget donne la référence de la forme de l´objet sur laquelle déposer l´objet
	var target = obj.dropTarget;
	// Si la cible existe, alors nous demandons à la fonction test_match function de comparer 
	//moved obj and target à l´endroit déposé.
	// Pour comparer obj et target à l´endroit déposé
	if (target != null)
	{
		test_match(target, obj);
	}
	obj.stopDrag();
}


function test_match(target,obj) {
	// Teste si les paires vont ensemble
	if (dict[target] == obj)
	{
		// Une paire va ensemble
		hits = hits+1;
		textField.text = "Yes ! You got one !";
		applause.play();
		// Rend l´objet transparent
		obj.alpha = 0.5;
		// Supprime l´écouteur d´événement. L´objet ne peut plus être bougé
		obj.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
		obj.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		// Teste si le jeu est fini
		if (hits == max)
		{
			textField.text = "Made it !!";
			music.play(0,5);
		}
	}
	else
	{
		obj.x = ori_x;
		obj.y = ori_y;
		textField.text = "Missed :(";
		laugh.play();
	}
}
Résultats

Source CS3

Source CS5:

Améliorations possibles
  • Ajouter un bouton pour redémarrer le jeu
  • Réécrire ce code comme une application ActionScript 3 application qui traiterait des paires aléatoires
  • Le nom de l'objet devrait être prononcé à haute voix lorsqu'un utilisateur le saisit
  • etc ....

Gestion du son

Si vous utilisez ce code et que vous devez faire appel à plusieurs fichiers sons dans votre animation, que cela soit dans la même frame ou dans d'autres, il faut les distinguer.

Voici les explications d'un étudiant (à peaufiner un peu): Par exemple, si dans ma frame 1 j'ai ce code et que j'utilise un code pratiquement identique dans ma frame 2, alors le prochaine request pour le son commencera à 4. EXEMPLE : (changez ce qui est en majuscule et faites attention au nombre après Request)

Frame1

var request:URLRequest = new URLRequest("NOM_FICHIER_DANS_MEME_DOSSIER_QUE_FICHIER_FLA.mp3");
var NOM_SYSTEME_DANS_FLA:Sound = new Sound();
NOM_SYSTEME_DANS_FLA.load(request);

Frame2

var request2:URLRequest = new URLRequest("NOM_FICHIER_DANS_MEME_DOSSIER_QUE_FICHIER_FLA.mp3");
var NOM_SYSTEME_DANS_FLA:Sound = new Sound();
NOM_SYSTEME_DANS_FLA.load(request2);
var request3:URLRequest = new URLRequest("NOM_FICHIER_DANS_MEME_DOSSIER_QUE_FICHIER_FLA.mp3");
var NOM_SYSTEME_DANS_FLA:Sound = new Sound();
NOM_SYSTEME_DANS_FLA.load(request3);

Frame3

var request4:URLRequest = new URLRequest("NOM_FICHIER_DANS_MEME_DOSSIER_QUE_FICHIER_FLA.mp3");
var NOM_SYSTEME_DANS_FLA:Sound = new Sound();
NOM_SYSTEME_DANS_FLA.load(request4);
  • Pour activer le fichier : NOM_SYSTEME_DANS_FLA.play();

Sujets avancés

Contrôle de plusieurs objets

Lorsque la souris bouge sur un clip qui contient plusieurs objets, cela peut créer plusieurs événements et qu'il faudrait pouvoir contrôler.

  • Utiliser MouseEven.ROLL_OVER au lieu de MOUSE_OVER
  • Ou desactiver les objets dans le clip:
yourMC.mouseChildren=false;
yourMC.addEventListener(MouseEvent.MOUSE_OVER,yourOverHandlerFunction);

Source: stackoverflow, consulté Feb. 2012

Limiter la zone de Drag & Drop

Il est possible de limiter la zone dans laquelle un objet peut être déplacé. Pour cela, commençons par créer un rectangle qui limitera la zone de Drag & Drop:

var zoneLimite = new Rectangle(100, 100, 100, 100);

Ensuite, il suffit d'utiliser la méthode "startDrag" en indiquant la zone limite comme paramètre:

objet.startDrag(true,zoneLimite);

Ainsi, l'objet pourra être déplacé uniquement dans un rectangle de 100x100 pixels, positionné à x:100 et y:100.


Références (en anglais)

Sprites et DisplayObjects

Les objets que l'on déplace sont des Movie Clips. Ils sont les enfants de Sprites. Sprites ont intégré des graphiques.

Tiré de : ActionScript 3.0 Language and Components Reference:

La hiérarchie ressemble à ça : MovieClip -> Sprite -> DisplayObjectContainer -> InteractiveObject -> DisplayObject -> EventDispatcher -> Object

Lorsque vous déposez un sprite sur un autre sprite, Flash va donner au sprite la forme d'un objet cible. Cette forme est un DisplayObject à partir duquel nous pouvons accéder à son parent, c'est-à-dire un Movie Clip dans ce cas.

Important: Lorsque vous regardez la définition d'une classe, il y a des boutons permettant d'ouvrir les méthodes et les propriétés héritées. La plupart du temps vous en aurez besoin.

Dessins

Écouteurs d'événements

Dictionnaires

Zones de texte

Sons

  • Sound (Adobe AS3 reference)

Autre tutoriels

  • Un tutoriel facile à suivre sur le drag and drop dans Flash CS5 (en anglais).
  • Un autre tutoriel très détaillé et d'une vingtaine de minutes en tout (en anglais):
    • Drag and Drop Tutorial in Flash CS5 - Actionscript 3 (Part 1/3)
    • Drag and Drop Tutorial in Flash CS5 - Actionscript 3 (Part 2/3)
    • Drag and Drop Tutorial in Flash CS5 - Actionscript 3 (Part 3/3)