Créer un effet de distorsion statique à l'aide du filtre de carte de déplacement

Deux fois par mois, nous revoyons certains des articles préférés de nos lecteurs dans l’histoire d’Activetuts +. Ce tutoriel a été publié pour la première fois il y a un an en janvier 2010.

Dans ce didacticiel, vous apprendrez à utiliser la classe DisplacementMapFilter d'AS3 pour créer un effet de distorsion statique réutilisable pour les renversements de boutons..


Aperçu du résultat final

Jetons un coup d'œil au résultat final sur lequel nous allons travailler:


Étape 1: À propos de la cartographie des déplacements

Une carte de déplacement fonctionne en utilisant les valeurs de couleur d'une image pour modifier la position des pixels dans une autre image. Cet effet est souvent utilisé pour «enrouler» un graphique plat autour d’une image dimensionnelle. Nous allons l'utiliser ici pour déformer un bouton afin qu'il ressemble à une interférence statique.

Vous pouvez en savoir plus sur la cartographie des déplacements ici.


Étape 2: Configurez votre fichier Flash

Créer un nouveau fichier Flash (ActionScript 3).

Les paramètres de votre film varient en fonction de votre jeu. Pour cette démo, je configure mon film en 500x300, sur fond noir et à 30 images par seconde.


Étape 3: Créer un bouton simple

Créez un nouveau symbole de bouton sur la scène (Insertion> Nouveau symbole). Concevez les 4 états pour votre bouton. La conception exacte doit correspondre à votre jeu. Quelque chose de brillant et semi-transparent fonctionne bien avec cet effet.
J'ai utilisé une police appelée Genetrix Square pour la mienne, mais vous devriez utiliser quelque chose qui correspond à l'apparence de votre jeu..

Donnez à votre bouton le nom d'occurrence 'bouton1'.


Étape 4: test

Si vous enregistrez et testez votre film (Contrôle> Tester le film), vous devriez voir votre bouton sur la scène répondre à la souris avec les états de survol que vous avez conçus. Comme ça:


Étape 5: Créer la classe JitteryButton

Nous devons ajouter une fonctionnalité personnalisée à notre bouton. Pour ce faire, nous allons créer une nouvelle classe personnalisée et y insérer notre simple bouton..

Créez un nouveau fichier ActionScript nommé "JitteryButton.as". Enregistrez ce fichier dans le même répertoire que votre fichier Flash principal. Ajoutez ce code pour créer le wrapper pour notre bouton:

 package import flash.display.Sprite; import flash.display.SimpleButton; Classe publique JitteryButton étend Sprite private var myButton: SimpleButton; // contient la référence à notre bouton simple // fonction publique CLASS CONSTRUCTOR JitteryButton (button: SimpleButton) myButton = button; // le bouton sur la scène est passé

Jusqu'ici, tout ce que ce code fait, c'est accepter le bouton simple et y stocker une référence. Nous ajouterons plus de fonctionnalités plus tard.


Étape 6: Créer la classe de jeu

Créez un nouveau fichier ActionScript nommé "Game.as". Ce sera la classe de document pour notre film. Enregistrez-le dans le même répertoire que le fichier Flash principal..

Ce code ajoutera notre wrapper de bouton personnalisé autour du bouton sur la scène:

 package import flash.display.MovieClip; public class Game s'étend sur MovieClip private var startButton: JitteryButton; // CLASS CONSTRUCTOR public function Game () // crée le bouton Jittery à partir du simple bouton de la scène startButton = new JitteryButton (button1); // ajoute le nouveau bouton à la scène addChild (startButton); 

Ce code crée une nouvelle instance de notre classe personnalisée JitteryButton et lui passe le bouton sur la scène ('button1').

Bien entendu, votre classe de document aura une apparence très différente, car elle contiendra le code de votre jeu. Ici nous sommes juste concernés par le code de notre bouton.

De retour dans votre fichier Flash, définissez la classe de document sur 'Jeu'. N'oubliez pas que vous n'incluez pas l'extension de fichier ici.


Étape 7: Testez à nouveau

Si vous enregistrez et testez à nouveau votre film à ce stade, vous devriez voir exactement la même chose que lorsque nous avons testé à l'étape 4. La seule différence est que notre code est maintenant configuré pour pouvoir ajouter notre comportement personnalisé..


Étape 8: Créer l'image de la carte de déplacement

Nous allons maintenant créer l'image du motif statique que nous utiliserons pour déformer notre graphique de bouton..

Ouvrez Photoshop et créez une nouvelle image remplie de gris neutre (n ° 808080). L'image doit être légèrement plus large que votre bouton et environ 3 ou 4 fois plus haute. Mon bouton est 277x56 et mon image est 310x220.

Nous commençons avec un gris neutre car cela n'affectera pas notre image.


Étape 9: Ajoutez du bruit

Nous allons maintenant ajouter un peu de bruit à notre image. Cela ne sera pas très visible dans notre effet statique, mais cela lui donnera un peu plus de brillance. Vous pouvez sauter cette étape si vous aimez.

Dupliquez le calque d'arrière-plan et nommez le nouveau calque «Bruit». Vous devriez maintenant avoir 2 couches remplies de gris neutre. Sélectionnez le nouveau calque de bruit et choisissez Filtre> Bruit> Ajouter du bruit. Ensemble Montant à 120% et Distribution à l'uniforme. Vérifier Monochromatique.

Hit OK.

Définissez le calque "Bruit" sur 10% d'opacité.


Étape 10: Ajouter des lignes

Créez un nouveau calque appelé "Lignes". Maintenant, utilisez un pinceau crayon 1px pour ajouter des lignes horizontales noires et grises à l'image.

Rappelez-vous comment ces lignes affecteront notre image: tout ce qui est plus sombre que le neutre changera notre image dans une direction et tout ce qui sera plus clair la changera dans l'autre..


Étape 11: Enregistrer l'image de la carte de déplacement

Choisissez Fichier> Enregistrer pour le Web et les périphériques et enregistrez votre image au format GIF de 8 couleurs intitulée "staticMap.gif"..


Étape 12:

De retour dans Flash, importez le 'staticMap.gif' dans votre bibliothèque (Fichier> Importer> Importer dans la bibliothèque?). Ouvrez les propriétés de liaison, cochez Exporter pour ActionScript, et définissez le nom de la classe sur 'StaticMap'.

Nous pouvons maintenant référencer cette image dans notre code en utilisant le nom de la classe StaticMap.


Étape 13: Créer le filtre de la carte de déplacement

Ajoutez cette fonction à votre classe JitteryButton:

 // crée la fonction privée du filtre de mappage de déplacement createDMFilter (): DisplacementMapFilter var mapBitmap: BitmapData = new StaticMap (0,0); // utilise les données bitmap de notre image StaticMap var mapPoint: Point = new Point (0, 0); // position de l'image StaticMap par rapport à notre bouton var channels: uint = BitmapDataChannel.RED; // quelle couleur utiliser pour le déplacement var composantX: uint = canaux; var composantY: uint = canaux; var scaleX: Nombre = 5; // la quantité de décalage horizontal var scaleY: Number = 1; // quantité de décalage vertical en mode var: String = DisplacementMapFilterMode.COLOR; var couleur: uint = 0; var alpha: nombre = 0; retourne un nouveau DisplacementMapFilter (mapBitmap, mapPoint, composantX, composantY, scaleX, scaleY, mode, couleur, alpha); 

Cette fonction crée simplement le filtre de carte de déplacement en utilisant BitmapData à partir de notre image StaticMap. Cela n'a pas besoin d'être dans sa propre fonction, je le fais juste pour plus de clarté.

Pour que cela fonctionne, nous devons importer ces classes en haut de notre classe JitteryButton:

 import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.filters.DisplacementMapFilter; import flash.filters.DisplacementMapFilterMode; import flash.geom.Point;

(Vous pouvez en apprendre plus sur la classe DisplacementMapFilter dans la documentation AS3)


Étape 14: Appliquer le filtre

Nous allons maintenant créer une variable pour contenir le filtre. Nous l'appliquons au bouton en définissant la propriété 'filters' du bouton sur un tableau contenant notre filtre..

Voici la classe JitteryButton jusqu'à présent (les lignes 18 et 25 sont nouvelles):

 package import flash.display.Sprite; import flash.display.SimpleButton; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.filters.DisplacementMapFilter; import flash.filters.DisplacementMapFilterMode; import flash.geom.Point; importer caurina.transitions.Tweener; Classe publique JitteryButton étend Sprite private var myButton: SimpleButton; // crée une variable pour contenir le filtre de la carte de déplacement private var dmFilter: DisplacementMapFilter = createDMFilter (); // fonction publique CLASS CONSTRUCTOR JitteryButton (button: SimpleButton) myButton = button; // applique le filtre au bouton myButton.filters = new Array (dmFilter);  // créer la fonction privée du filtre de mappage de déplacement createDMFilter (): DisplacementMapFilter var mapBitmap: BitmapData = new StaticMap (0,0); // utilise les données bitmap de notre image StaticMap var mapPoint: Point = new Point (0, 0); // c'est la position de l'image StaticMap par rapport à notre bouton var channels: uint = BitmapDataChannel.RED; // quelle couleur utiliser pour le déplacement var composantX: uint = canaux; var composantY: uint = canaux; var scaleX: Nombre = 5; // la quantité de décalage horizontal var scaleY: Number = 1; // quantité de décalage vertical en mode var: String = DisplacementMapFilterMode.COLOR; var couleur: uint = 0; var alpha: nombre = 0; retourne un nouveau DisplacementMapFilter (mapBitmap, mapPoint, composantX, composantY, scaleX, scaleY, mode, couleur, alpha); 

Étape 15: Testez à nouveau

Si nous sauvegardons et testons le fichier maintenant, nous pouvons voir que le filtre de carte de déplacement est appliqué à notre bouton:

Vous pouvez voir comment les lignes horizontales que nous avons dessinées dans StaticMap déplacent les pixels de notre bouton vers la gauche et vers la droite. La quantité de décalage dépend de l'obscurité des lignes de l'image et du paramètre scaleX de notre filtre de carte de déplacement..

Malheureusement, la statique n'anime pas, donc ça a l'air minable. Réglons ça maintenant?


Étape 16: Ajoutez la fonction randRange

C'est une fonction simple qui renvoie un entier aléatoire dans une plage spécifiée:

 // retourne un nombre aléatoire entre la plage spécifiée (incluse) fonction privée randRange (min: int, max: int): int var randomNum: int = Math.floor (Math.random () * (max - min + 1) ) + min; return randomNum; 

Je trouve que cela rend un peu plus facile de générer des valeurs aléatoires. Nous allons randomiser quelques valeurs différentes pour notre effet statique afin qu'il soit utile.

Ajoutez-le à votre classe JitteryButton.


Étape 17: Animation du filtre de la carte de déplacement

Il y a plusieurs façons d'animer l'effet statique. La première consistera à modifier le décalage horizontal appliqué à notre bouton. Ceci est fait par la propriété scaleX du DisplacementMapFilter.

Nous pouvons également animer la position de l'image StaticMap par rapport à notre bouton. Cela garantira que les mêmes zones du bouton ne sont pas toujours déplacées.

Pour animer l'effet, nous allons ajouter une fonction appelée 'displayStatic' qui s'appelle chaque image pour mettre à jour ces deux propriétés du filtre. Ajoutez cette fonction à votre classe JitteryButton:

 // appelé dans la fonction privée ENTER_FRAME displayStatic (e: Event): void dmFilter.scaleX = randRange (fuzzMin, fuzzMax); dmFilter.mapPoint = new Point (0, randRange (0, -160)); myButton.filters = new Array (dmFilter); 

La première ligne de cette fonction randomise le décalage horizontal sur une valeur comprise entre les variables fuzzMin et fuzzMax. Ajoutez ces deux variables à votre classe JitteryButton:

 var privé fuzzMin: int = 0; var privé fuzzMax: int = 2;

La deuxième ligne de la fonction displayStatic randomise la position Y de StaticMap par rapport à notre bouton. Nous avons déjà dit au filtre d’utiliser notre image StaticMap, nous avons donc juste besoin de mettre à jour la position..

La troisième ligne réapplique simplement le filtre à notre bouton.

La dernière chose à faire pour obtenir cette animation est d’ajouter l’auditeur d’événement ENTER_FRAME. Ajoutez cette ligne à la fonction constructeur JitteryButton:

 // commence à afficher l'effet statique addEventListener (Event.ENTER_FRAME, displayStatic);

Et n'oubliez pas d'importer la classe Event en haut du fichier JitteryButton:

 import flash.events.Event;

Étape 18: Testez à nouveau

Si vous enregistrez et testez le film maintenant, vous constaterez que l'effet rend notre bouton chatoyant et sautillant:

C'est plutôt cool, mais nous voulons que l'effet réagisse également à la souris. En avant?


Étape 19: Ajustez l'intensité de l'effet

Nous allons maintenant ajouter deux fonctions pour régler l’intensité de l’effet de gigue. Nous appellerons l'effet que nous avons actuellement Intensité faible, nous allons donc ajouter un réglage d'intensité moyenne et élevée. Ajoutez ces fonctions à votre classe JitteryButton:

 // augmente l'intensité de la fonction privée static to MEDIUM setStaticMedium (e: MouseEvent = null): void fuzzMin = 2; fuzzMax = 6; staticLength = randRange (8, 12);  // Augmente l'intensité de la fonction privée statique à HIGH. setStaticHigh (e: MouseEvent = null): void fuzzMin = 12; fuzzMax = 25; longueur statique = 12; 

Vous pouvez constater que nous ajustons l'intensité en définissant les valeurs des variables fuzzMin et fuzzMax. De cette façon, notre fonction displayStatic utilisera ces nouvelles valeurs quand elle définira le décalage horizontal du filtre..

Nous avons également ajouté une variable appelée staticLength. Nous allons l'utiliser pour définir la durée pendant laquelle l'effet le plus intense devrait durer (le nombre d'images) avant de revenir à une intensité faible. Ajoutez cette variable à votre classe JitteryButton et modifiez votre fonction displayStatic comme suit:

 private var staticLength: int; // appelé dans la fonction privée ENTER_FRAME displayStatic (e: Event): void dmFilter.scaleX = randRange (fuzzMin, fuzzMax); dmFilter.mapPoint = new Point (0, randRange (0, -160)); myButton.filters = new Array (dmFilter); staticLength--; if (staticLength <= 0) fuzzMin = 0; fuzzMax = 2;  

Ce nouveau code décrémente la variable staticLength et réinitialise fuzzMin et fuzzMax aux valeurs de faible intensité une fois que la valeur de staticLength atteint zéro..


Étape 20: Configuration des gestionnaires de basculement de bouton

Pour que notre bouton réagisse à la souris, nous devons ajouter deux écouteurs d’événement et un gestionnaire d’événements pour chaque souris..

Ajoutez les écouteurs de la souris dans la fonction constructeur de votre classe JitteryButton:

 // ajoute les écouteurs d'événement de survol au bouton myButton.addEventListener (MouseEvent.ROLL_OVER, onButtonRollOver); myButton.addEventListener (MouseEvent.ROLL_OUT, onButtonRollOut);

Créez maintenant les deux gestionnaires d’événements référencés dans ces deux nouvelles lignes. Ceux-ci vont également dans la classe JitteryButton:

 // appelé sur le bouton ROLL_OVER fonction privée onButtonRollOver (e: MouseEvent): void setStaticHigh ();  // appelé sur le bouton ROLL_OUT fonction privée onButtonRollOut (e: MouseEvent): void setStaticMedium (); 

Pour que tout cela fonctionne, nous devons importer la classe MouseEvent en haut de notre fichier JitteryButton:

 import flash.events.MouseEvent;

Désormais, lorsque notre bouton détecte un événement ROLL_OVER, il appelle le gestionnaire d’événements, qui à son tour appelle notre fonction setStaticHigh. Cette fonction augmente les valeurs de fuzzMin et fuzzMax (utilisées pour définir le décalage horizontal) pour la durée spécifiée par la variable staticLength.


Étape 21: Ajouter l'effet d'échelle

Nous pourrions nous arrêter ici. Notre effet s'anime bien et réagit aux renversements de la souris. J'ai toujours l'impression qu'il manque quelque chose ici. Ajoutons un petit effet d'échelle.

Vous devrez télécharger la bibliothèque Tweener pour cette étape si vous ne l'avez pas déjà. Placez le dossier 'caurina' dans votre répertoire de projet et importez les classes Tweener en haut de votre fichier JitteryButton:

 importer caurina.transitions.Tweener;

Tweener nous permet d’ajouter de jolis effets de mise à l’échelle avec seulement quelques lignes de code. Nous pouvons ajouter une ligne à chacun de nos gestionnaires d'événements de substitution:

 // appelé le bouton ROLL_OVER fonction privée onButtonRollOver (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1.1, time: .5, transition: "aisanceSoutElastique"); setStaticHigh ();  // appelé sur le bouton ROLL_OOUT fonction privée onButtonRollOut (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1, time: .5, transition: "aisance_Elastique"); setStaticMedium (); 

Nous ajoutons ici une animation au gestionnaire de substitution qui redimensionne la propriété scaleX du bouton à 110% sur 0,5 seconde. Nous utilisons un type de transition élastique pour lui donner une sensation de dynamisme. Dans le gestionnaire de déploiement, nous faisons la même chose en sens inverse, en le réduisant à 100%.

Vous pouvez en apprendre plus sur l'utilisation de Tweener dans la documentation de Tweener..


Étape 22: Ajouter du son

La dernière chose à faire pour compléter cet effet est d’ajouter du son. J'ai fait mon effet sonore dans Garage Band. Vous pouvez créer le vôtre ou essayer d'en trouver un en ligne.

Une fois que vous en avez un, importez-le dans votre bibliothèque et définissez le lien pour exporter en tant que 'StaticSound'.

Pour l'ajouter à notre JitteryButton, nous devons d'abord importer la classe Sound:

 import flash.media.Sound;

Ensuite, nous l'initialiserons (ajoutons cette ligne juste avant la fonction constructeur):

 private var staticSound: Sound = new StaticSound ();

Dans le gestionnaire de roulement, nous dirons au son de jouer:

 // appelé le bouton ROLL_OVER fonction privée onButtonRollOver (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1.1, time: .5, transition: "aisanceSoutElastique"); setStaticHigh (); staticSound.play (); 

Maintenant nous sommes prêts à partir. Testez votre film et tout devrait fonctionner. Si votre bouton ou son ne fonctionne pas correctement, vérifiez les fichiers source pour voir ma classe JitteryButton terminée.


Étape 23: Ajouter plus de boutons

La bonne chose à propos de la création de cet effet en tant que classe distincte qui enveloppe notre bouton est que nous pouvons facilement le réutiliser sur d’autres boutons..

Si vous souhaitez ajouter plus de boutons à votre menu de jeu, créez simplement un nouveau bouton et ajoutez-le à la scène. Donnez-lui le nom d'occurrence 'button2'. Ensuite, dans votre classe de documents (le fichier 'Game.as'), créez un nouveau JitteryButton et transmettez-le au nouveau bouton. Voici à quoi cela pourrait ressembler:

 package import flash.display.MovieClip; public class Game s'étend sur MovieClip private var startButton: JitteryButton; var privé menuButton: JitteryButton; // CLASS CONSTRUCTOR public function Game () // crée les boutons d'instabilité à partir des boutons simples de la scène startButton = new JitteryButton (button1); addChild (startButton); // ajouter un nouveau bouton est facile! menuButton = new JitteryButton (button2); addChild (menuButton); 

Conclusion

Vous aurez presque certainement besoin de changer un peu ce code pour l’intégrer à la structure de votre jeu. Espérons que ce tutoriel vous donnera un bon point de départ si.

Si vous souhaitez modifier l'aspect de cet effet, vous pouvez utiliser différents types d'images pour votre graphique StaticMap et ajuster les valeurs pour fuzzMin et fuzzMax..

Ceci est mon premier tutoriel alors laissez-moi savoir s'il y a quelque chose que je peux faire mieux la prochaine fois. Merci d'avoir lu!