3D : projection, point de fuite et champ de vision.

1ere partie : projection, point de fuite et angle du champ de vision.


Au vu des possibilités 3D rajoutés à l’ActionScript, il devient assez simple d’utiliser la 3D dans une animation, il serait donc dommage de s’en priver.
Avant la v10 du lecteur Flash, il fallait soit être très calé en math pour gérer la 3D dans flash ou alors utiliser une librairie tel que sandy3d, papervision3D
note : il ne faut pas penser que les librairies proposant des moteurs 3D pour Flash sont devenus inutile … elles proposent encore et toujours des fonctionnalités absentes de l’ActionScript tel que la gestion des sources lumineuses ainsi que des aides pour la création d’objets 3D , le mappage des textures, …etc


Histoire de commencer facilement, le 1er tutoriel aura pour but de visualiser la projection de perspective.
On commence par créer un nombre quelconque de Shape (cercles), ces cercles sont tous positionnés au centre de la scène mais décalés entre eux en Z.
La scène est cliquable afin de modifier la valeur de la propriété projectionCenter (représente le point de fuite de la projection) sur la position de la souris.
J’ai rajouté en haut de la scène un composant perso (Reglette) qui permet de visualiser et de modifier la propriété fieldOfView qui représente l’angle du champ de vision de la projection.


Documentation utile :

Attention : la propriété transform est bien un membre de la classe DisplayObject mais si vous voulez atteindre la propriété transform.perspectiveProjection la cible doit être de type DisplayObjectContainer !


Atteindre et définir la propriété fieldOfView afin de modifier l’angle du champ de vision :

(cible:DisplayObjectContainer).transform.perspectiveProjection.fieldOfView = 110;

Attention : la valeur doit être comprise en 0.0001 et 179.9999, assigner une valeur égal à 0 ou 180 provoque une erreur !

Atteindre et définir la propriété projectionCenter afin de modifier la position du point de fuite :

(cible:DisplayObjectContainer).transform.perspectiveProjection.projectionCenter = new Point(200, 100);


Le SWF :

Le code (sans la Reglette) :

package {
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFormat;
 
	[SWF(width = 800, height = 600, backgroundColor = 0xFFFFFF, frameRate = 25)]
 
	/**
	 * Projection de perspective.
	 * Visualisation et modification du pointe fuite.
	 *
	 * @author Lorenzo
	 */
	public class Main extends Sprite {
		// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
		// ——————————————————————————————————— Constructeur ——————————————————————————————————
		// ___________________________________________________________________________________
		public function Main():void {
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			stage.scaleMode = "noScale";
 
			var tx:TextField = this.addChild(new TextField()) as TextField;
			tx.defaultTextFormat = new TextFormat("Courier New", 13, 0);
			tx.text = "Cliquer sur la scène pour modifier la position du point de fuite";
			tx.autoSize = "left";
			tx.mouseEnabled = false;
			tx.x = 5;
			tx.y = stage.stageHeight - tx.height;
 
			creerCercles();
 
			// valeur de l'angle du champ de vision
			this.transform.perspectiveProjection.fieldOfView = 110;
 
			stage.addEventListener(MouseEvent.MOUSE_DOWN, evtDebutProjection);
			stage.addEventListener(MouseEvent.MOUSE_UP, evtFinProjection);
		}
 
		// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
		// ———————————————————————————— Gestionnaire d'évènements ————————————————————————————
		// ___________________________________________________________________________________
		private function evtDebutProjection(ev:MouseEvent):void {
			// annuler le click si l'objet sous la souris n'est pas le Stage
			if ( !(ev.target is Stage) ) return;
			modifierPointDeFuite(ev.stageX, ev.stageY);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, evtProjection);
		} 
 
		private function evtProjection(ev:MouseEvent):void {
			modifierPointDeFuite(ev.stageX, ev.stageY);
		} 
 
		private function evtFinProjection(ev:MouseEvent):void {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, evtProjection);
		}
 
		// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
		// ————————————————————————————— Déclaration des méthodes ————————————————————————————
		// ___________________________________________________________________________________
		/**
		 * modification de la position du point de fuite de la projection.
		 *
		 * @param	x
		 * @param	y
		 */
		private function modifierPointDeFuite(x:Number, y:Number):void {
			this.transform.perspectiveProjection.projectionCenter = new Point(x, y);
		}
		/**
		 * Création d'un cercle.
		 *
		 * @param	x
		 * @param	y
		 * @param	z
		 * @param	rayon
		 * @return
		 */
		private function creerCercle(x:Number, y:Number, z:Number, rayon:Number):Shape {
			var sh:Shape = new Shape();
			sh.graphics.lineStyle(0, 0, 0.2);
			sh.graphics.beginFill(Math.round(Math.random()*0xFF), 0.1);
			sh.graphics.drawCircle(0, 0, rayon);
			sh.graphics.endFill();
			sh.x = x;
			sh.y = y;
			sh.z = z;
			return sh;
		}
		/**
		 * Création des cercles.
		 * Les cercles sont tous alignés le centre de la scene (en x et y)
		 * mais ils sont décalés en z.
		 */
		private function creerCercles():void {
			var nbCercles:uint = 50;
			var decalageZ:uint = 50;
			// pour avoir 2 cercles au dessus de la scène et un autre au meme niveau
			// (permet de mieux visualiser les changements apportés par fieldOfView)
			var z:int = -decalageZ * 2;
 
			var x:Number = stage.stageWidth / 2;
			var y:Number = stage.stageHeight / 2;
			for (var i:uint = 0; i < nbCercles; i++, z += decalageZ) {
				this.addChild(creerCercle(x, y, z, 100));
			}
		}
 
	}
}


Jouer avec la perspective et la profondeur en Z d’objets en 2D peut donner des idées de composant visuels, tel que :

  • Gestion de liste (photos,musique,..)
  • Menu de navigation
  • ..etc
  • Mettre en place ce genre de composant va demander peu de connaissance mais je suis sur que l’on peut arriver a un effet visuel bien sympa !

Laisser un commentaire

*