En este documento voy a crear un “automovil” y programar la interaccion con el teclado. Es relativamente sencillo.
Lo primero que vamos a necesitar son los assets. Las texturas de las ruedas y del auto, como no voy a utilizar una maya del automovil sino una caja, solo necesitaremos las fotos del auto desde diferentes vistas.
Como el proyecto que estoy usando es en FlashDevelop, sin librerías de flash vamos a hacer embeds de los assets de esta manera (también podría hacer Loaders, pero hoy no...):
[Embed(source = '../img/front.jpg')]
private var front:Class;
[Embed(source="../img/sideL.jpg", mimeType = "image/jpeg")]
private var sideL:Class;
[Embed(source="../img/sideR.jpg", mimeType = "image/jpeg")]
private var sideR:Class;
[Embed(source="../img/top.jpg", mimeType = "image/jpeg")]
private var top:Class;
[Embed(source="../img/back.jpg", mimeType = "image/jpeg")]
private var back:Class;
[Embed(source='../img/wheel.jpg')]
private var tire:Class;
para más información del tag Embed vea los enlaces del final.
Lo que acabamos de hacer aca es simplemente guardar los assets en objetos tipo Bitmap, ya que son solo jpgs.
Luego debemos crear todas las variables necesarias para manipular el auto como las ruedas el cubo principal que servira como el chasis del auto, etc..
private var cube:Cube;
private var car:DisplayObject3D;
private var wheelFR :Cylinder;
private var wheelFL :Cylinder;
private var wheelRR :Cylinder;
private var wheelRL :Cylinder;
private var Steer_FR :DisplayObject3D;
private var Steer_FL :DisplayObject3D;
También debemos inicializar todos los objetos básicos del entorno de papervision3D, viewport, camara, escena, etc.
viewport = new Viewport3D();
scene = new Scene3D();
camera = new Camera3D();
renderer = new BasicRenderEngine();
renderer.renderScene(scene, camera, viewport);
Una vez que todo este listo, creamos el automóvil. ( la caja =D ). para eso debemos obtener las texturas de los objetos que creamos de los jpg, hacemos un MaterialList con un arreglo de BitmapMaterials, de esta forma:
var m:MaterialsList = new MaterialsList( {
//all:
front: new BitmapMaterial((new front() as Bitmap).bitmapData),
back: new BitmapMaterial((new back() as Bitmap).bitmapData),
right: new BitmapMaterial((new sideR() as Bitmap).bitmapData),
left: new BitmapMaterial((new sideL() as Bitmap).bitmapData),
top: new ColorMaterial(0xFFFFFF, 1),
bottom: null
} );
cube = new Cube(m, 200, 400, 100, 4, 4, 4);
Ahora crearemos las ruedas y estas deben ser colocadas manualmente en su lugar. Nuevamente obtenemos el material de la rueda y lo aplicamos como un BitmapMaterial.
var materialForm:BitmapMaterial = new BitmapMaterial((new tire() as Bitmap).bitmapData);
Steer_FR = new DisplayObject3D();
Steer_FL = new DisplayObject3D();
wheelFR = new Cylinder(materialForm,40, 20, 10, 1)
wheelFL = new Cylinder(materialForm,40, 20, 10, 1)
wheelRR = new Cylinder(materialForm,40, 20, 10, 1)
wheelRL = new Cylinder(materialForm,40, 20, 10, 1)
Steer_FR.addChild(wheelFR);
Steer_FL.addChild(wheelFL);
car.addChild(wheelRR);
car.addChild(wheelRL);
car.addChild(Steer_FR);
car.addChild(Steer_FL);
wheelFR.rotationZ = 90;
Steer_FR.x = 110;
Steer_FR.y = -50;
Steer_FR.z = 120;
wheelFL.rotationZ = 90;
Steer_FL.x = -110;
Steer_FL.y = -50;
Steer_FL.z = 120;
wheelRR.rotationZ = 90;
wheelRR.x = 110;
wheelRR.y = -50;
wheelRR.z = -120;
wheelRL.rotationZ = 90;
wheelRL.x = -110;
wheelRL.y = -50;
wheelRL.z = -120;
Nótese que las ruedas delanteras estan metidas dentro de otro contenedor (DisplayObject3D), debido a que estas deben girar conforme el auto avanza, pero también deben girar a ambos lados del auto.
Después de esto necesitamos construir un handler que se encargue de la interacción con el teclado, el cual va a hacer que nuestro vehiculo gire y avance o retroceda.
switch ( event.keyCode ) {
case Keyboard.UP :
keyForward = true;
keyReverse = false;
break;
case Keyboard.DOWN :
keyReverse = true;
keyForward = false;
break;
case Keyboard.LEFT :
keyLeft = true;
keyRight = false;
break;
case Keyboard.RIGHT :
keyRight = true;
keyLeft = false;
break;
case Keyboard.CONTROL :
camera.lookAt(car);
break;
}
entonces cada vez que presionamos Keyboard.UP la variable keyForward pasará a true y el siguiente código el cual se ejecuta con el Event.ENTER_FRAME:
private function driveCar():void {
// Speed
if ( keyForward ) {
topSpeed = 45;
} else if ( keyReverse ) {
topSpeed = -30;
} else {
topSpeed = 0;
}
speed -= ( speed - topSpeed ) / 30;
// Steer
if ( keyRight ) {
if ( topSteer <>
topSteer += 35;
}
} else if ( keyLeft ) {
if ( topSteer > -45 ) {
topSteer -= 35;
}
} else {
topSteer -= topSteer / 24;
}
steer -= ( steer - topSteer ) / 2;
// Mover el cubo
car.yaw( (speed*.1) * steer / 50 );
car.moveForward( speed );
var roll :Number = speed ;
wheelFR.rotationY -= roll;
wheelRR.rotationY -= roll;
wheelFL.rotationY -= roll;
wheelRL.rotationY -= roll;
Steer_FR.rotationY = steer * .5;
Steer_FL.rotationY = steer * .5;
}
Esta es la función encargada de la conducción del vehículo, avanzar, girar, etc.. todo sucede aquí. Como puedes ver las ruedas de dirección se giran desde el contenedor Steer_FR y Steer_FL, para maniobrar y adentro de estos contenedores se encuentran las ruedas que giran hacia adelante o hacia atras. Luego la funcion car.yaw( (speed*.1) * steer / 50 ); es la que s encarga de girar el auto según la velocidad.
Es un ejemplo muy sencillo, espero poder meterle cosas mas interesantes luego.
Puedes descargar el código completo aquí.
Frazko...
AS Developer
Recursos:
Flash Develop
http://www.flashdevelop.org/community/viewtopic.php?f=11&t=4374
Embed Tags en AS3
http://www.bit-101.com/blog/?p=853