Saturday, February 12, 2011

Away3D & Groups: Object Containers with 3D Tank Game Development Tutorial

The tank flash game can be seen here: Two Tanks 3D Tank Flash Game


Calculating When To Blow Up

The bullet fired from a tank is checked for impact with another tank or the ground elevation's height level at the X,Y coordinate that it is at.

if (earth.y < elevationreader.getLevel(earth.x, -earth.z, -3500) || meshEnemy.distanceTo(earth) < 350) 

LOL: -3500 is just some offset that I'm using with the Away3D elevation reader. Sounds important though. I could do a tutorial on tinkering with the built-in terrain code to get what you want out of it but it's not That difficult... even though it is... I think I just need to figure it out better! I'm postponing any such thing in case better Away3D documentation comes out or the output of the terrain library is easier to guess in terms of scale, size, etc.


Tank Controls: Keyboard Input Code In Away3D

The following exposes a great deal of information to 3D video game developers on how a simple tank rig needs to be constructed with code in Away3D. Moving the mouse while the button is clicked down adjusts the object container group cannonMesh. With the way that the groups were setup, the rotation X property uses a range from 0 to 37 degrees for the range of movement in which the tank barrel is allowed to aim "up and down". There was some very tricky 3D coding needed to set this up which will be covered towards the end of the post. Turning the entire tank is provided for but not in the following code. So, the only movements left to explain are rotating the barrel around the tank. In this case the tank barrel turns freely all 360 degrees if it likes and so cannonMesh and bulletMarkerDummyRotationObject are rotated together. I am using bulletMarkerDummyRotationObject as an easy way to locate the end of the barrel when we need to fire a shot off in the code. When the player shoots the tank or the enemy fires upon the player, Away3D just grabs the position of bulletMarkerDummyRotationObject which thanks to the groups setup is already rotated right into place to take the correct x,z,y coordinates. Also, cameraMarkerDummyRotationObject is another "dummy object" used to track and tween the position of the camera around the tank:
if (move) 
{
cannonMesh.rotationX += (stage.mouseY - lastMouseY) * .01;
if(cannonMesh.rotationX < 0)
{cannonMesh.rotationX = 0; }
if(cannonMesh.rotationX > 37)
{cannonMesh.rotationX = 37; }
}

if (qispressed)
{
cannonMesh.rotationY -= 4;
bulletMarkerDummyRotationObject.rotationY -= 4;
}
if (eispressed)
{
cannonMesh.rotationY += 4;
bulletMarkerDummyRotationObject.rotationY += 4;
}
if (zispressed)
{
cameraMarkerDummyRotationObject.rotationY -= 3;
}
if (cispressed)
{
cameraMarkerDummyRotationObject.rotationY += 3;
}
mesh.rotationY = mesh.rotationY + (accelerationSideRate / 3);

At the end I had first come up with a little trick to fake the tank being level with the ground on uneven terrain like the side of a hill but I came up with the real thing a while later. It doesn't twitch as if it's matching the angle of the terrain but it actually matches the angle quite well and in terms of computation... inexpensively as well.


Health Bar With Rendered Text Status: Critical

I chose to use a health status display of pre-rendered image assets that need to switch based on tank's health percentage range. I am using a function called getStatus which returns the index number of the correct image in our array of images which corresponds to that tank's current class of health.

public function recalculateHealthBar():void
{
//cgg edit: this was causing error now that its in flash 10 debugger and not flash 9 which worked previously
removeChild(currentHealthBar);
var playerStatus:int = getStatus(tankhealth);
var enemyStatus:int = getStatus(tankhealthEnemy);
currentHealthBar = bitmapArray[playerStatus][enemyStatus];
addChild(bitmapArray[playerStatus][enemyStatus]);
}


The getStatus function simply sorts out which range the player's health is in and returns the appropriate integer:

public function getStatus( health:uint ):uint
{
if (health == 100) return 0;
if (health < 100 && health >= 80) return 1;
if (health < 80 && health >= 40) return 2;
if (health < 40 && health >= 0) return 3;
return 0;
}


Enjoy Away3D! I have really appreciated all of the work that the Away3D team is doing with Away3DLite. Even more exciting is Adobe's Molehill release of Flash 11 and the 3D card support coming into the works as we speak.

No comments:

Post a Comment

Give me your best comment. *_*