Création de jeux (4eme partie) : déplacement d’un véhicule

L’article précédent présentait la base d’un moteur de déplacement pouvant être appliqué a un ensemble de jeu assez limité.
Cet article présente un moteur de déplacement plus évolué pouvant être utilisé pour déplacer tous types de véhicule (le véhicule accélère par rapport à son axe de rotation (comme une voiture ou une fusée)).

exemple (utilisation des touches fléchés pour déplacer le véhicule) :

code :

package {
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.ui.Keyboard;
 
 
 
	[SWF(width = 600, height = 600, backgroundColor = 0x0, frameRate = 30)]
 
	/**
	 * @author Lorenzo
	 */
	public class test4_Deplacement extends Sprite {
 
		public function test4_Deplacement():void {
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
 
		private var _shapeVoiture:Shape;
 
		private var _gauche:Boolean = false;
		private var _droite:Boolean = false;
		private var _haut:Boolean = false;
		private var _bas:Boolean = false;
 
		private const VITESSE_MAX:Number = 11;
		private const VITESSE_ACCELERATION:Number = 1;
		private const VITESSE_FRICTION:Number = 0.96;
		private var _vitesseVoiture:Number = 0;
 
		private const ROTATION_MAX:Number = 10;
		private const ROTATION_ACCELERATION:Number = 1;
		private const ROTATION_FRICTION:Number = 0.85;
		private var _vitesseRotationVoiture:Number = 0;
 
 
 
		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			stage.scaleMode = 'noScale';
 
			// création d'une Shape "voiture"
			_shapeVoiture = this.addChild(new Shape()) as Shape;
			_shapeVoiture.x = stage.stageWidth / 2;
			_shapeVoiture.y = stage.stageHeight / 2;
 
			var g:Graphics = _shapeVoiture.graphics;
			g.lineStyle(1, 0x00FFFF, 1);
			g.beginFill(0x0080C0, 1);
			g.drawCircle(0, 0, 10);
			g.endFill();
			g.moveTo(0, 0);
			g.lineTo(30, 0);
 
 
			// écouteurs
			stage.addEventListener(KeyboardEvent.KEY_DOWN, evtStageKeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, evtStageKeyUp);
			stage.addEventListener(Event.ENTER_FRAME, evtStageEnterFrame);
		}
 
		private function evtStageKeyUp(ev:KeyboardEvent):void {
			if (ev.keyCode == Keyboard.LEFT) {
				_gauche = false;
			}
			if (ev.keyCode == Keyboard.RIGHT) {
				_droite = false;
			}
			if (ev.keyCode == Keyboard.UP) {
				_haut = false;
			}
			if (ev.keyCode == Keyboard.DOWN) {
				_bas = false;
			}
		}
 
		private function evtStageKeyDown(ev:KeyboardEvent):void {
			if (ev.keyCode == Keyboard.LEFT) {
				_gauche = true;
			}
			if (ev.keyCode == Keyboard.RIGHT) {
				_droite = true;
			}
			if (ev.keyCode == Keyboard.UP) {
				_haut = true;
			}
			if (ev.keyCode == Keyboard.DOWN) {
				_bas = true;
			}
		}
 
		/**
		 * Deplacement de la voiture
		 */
		private function evtStageEnterFrame(ev:Event):void {
			if ( _gauche ) {
				_vitesseRotationVoiture -= ROTATION_ACCELERATION;
				if ( _vitesseRotationVoiture < -ROTATION_MAX ) {
					_vitesseRotationVoiture = -ROTATION_MAX;
				}
			}else if ( _droite ) {
				_vitesseRotationVoiture += ROTATION_ACCELERATION;
				if ( _vitesseRotationVoiture > ROTATION_MAX ) {
					_vitesseRotationVoiture = ROTATION_MAX;
				}
			}
 
			// ralentissement de la vitesse de rotation
			if ( !_gauche && !_droite ) {
				_vitesseRotationVoiture *= ROTATION_FRICTION;
			}
 
			if ( _haut ) {
				_vitesseVoiture += VITESSE_ACCELERATION;
				if ( _vitesseVoiture > VITESSE_MAX ) {
					_vitesseVoiture = VITESSE_MAX;
				}
			}else if ( _bas ) {
				_vitesseVoiture -= VITESSE_ACCELERATION;
				if ( _vitesseVoiture < -VITESSE_MAX ) {
					_vitesseVoiture = -VITESSE_MAX;
				}
			}
 
			// ralentissement de la vitesse de déplacement
			if ( !_haut && !_bas ) {
				_vitesseVoiture *= VITESSE_FRICTION;
			}
 
			_shapeVoiture.rotation += _vitesseRotationVoiture;
			var angleRad:Number = _shapeVoiture.rotation * Math.PI / 180;
 
			var dx:Number = Math.cos(angleRad) * _vitesseVoiture;
			var dy:Number = Math.sin(angleRad) * _vitesseVoiture;
 
			_shapeVoiture.x += dx;
			_shapeVoiture.y += dy;
		}
	}
}

-En utilisant différentes valeurs pour les constantes définissant l’accélération ou la rotation on peut arriver à régler finement le type de conduite désiré.
-Pour ceux ne voulant pas de marche arrière, il suffit de modifier le bloc de code correspondant a la touche arrière :

			.......
			}else if ( _bas ) {
				_vitesseVoiture -= VITESSE_ACCELERATION;
				if ( _vitesseVoiture < 0 ) {
					_vitesseVoiture = 0;
				}
			}

-En rajoutant une autre constante + une petite modif du code on peut avoir une vitesse en marche arrière différente de celle de la marche avant.
-Le moteur comporte aussi des coefficients de friction, qui s’appliquent à la rotation et à la vitesse de déplacement du véhicule … plus le coefficient est proche de 1 et plus son effet est nul (un coefficient > 0.985 et <=1 est parfait pour un vaisseau dans l'espace).
-L'utilisation de booléens (_haut/_bas/_gauche/_droite) pour suivre les actions sur les touches de déplacement permet de gérer plusieurs touches enfoncés en même temps.

Laisser un commentaire

*