For a project I’m working on I need to create a virtual 3D space that I can move about in. Sort of like a first person shooter. It’s surprisingly simple to create the space and simple movements with Away3D. The only complication that I ran into has nothing much to do with Away3D but with the nuances with trigonometry.

view source

I cover how to build the mesh, that makes up the ground, with a dynamic HeightMapModifier here.

The simplest movement components are the tilting and pivoting of the camera. Here's how to handle to look up/down along the x-axis.

// Tilt the camera up/down based on mouse position.
_camera3D.rotationX += -( mouseY - ( this.height/2 ) ) * 0.005;

And the pivoting about the y-axis.

// spin the camera around based on mouse position.
_camera3D.rotationY += ( mouseX - 275 ) * 0.005;

To move in space when the mouse is pressed down is going to require a bit of trig. We're just converting the _camera3D.rotationY from degrees to radians and then taking the sine for the xComponent and cosine for the zComponent. Multiplying by 10 is arbitrary to adjust the speed so that we move at something more than a crawl.

// If the mouse is down then movie in space.
if( _isMouseDown ) {
	var xComponent:Number = Math.sin( _camera3D.rotationY * Math.PI / 180 ) * 10;
	var zComponent:Number = Math.cos( _camera3D.rotationY * Math.PI / 180 ) * 10;
	_camera3D.position = new Vector3D(
		_camera3D.x + xComponent, _camera3D.y, _camera3D.z + zComponent );
}

Now, to enable keyboard movement is pretty much the same approach as how we did it with the mouse above.

private function walk():void {
	// These variables help us move forward/backward or left/right based
	// on the direction the _camera3D is pointed. Multiplying by 10 is arbitrary
	// and sets the speed which which we move. It would be simple enough to set
	// the multiplier as a variable to simulate acceleration.
	var xComponent : Number = Math.sin( _camera3D.rotationY * Math.PI / 180 ) * 10;
	var zComponent : Number = Math.cos( _camera3D.rotationY * Math.PI / 180 ) * 10;

	if( _isUpKeyDown ) {
		_camera3D.position = new Vector3D(
			_camera3D.x + xComponent,
			_camera3D.y,
			_camera3D.z + zComponent );
	}
	if( _isDownKeyDown ) {
		_camera3D.position = new Vector3D(
			_camera3D.x - xComponent,
			_camera3D.y,
			_camera3D.z - zComponent );
	}
	if( _isLeftKeyDown  ) {
		_camera3D.position = new Vector3D(
			_camera3D.x - zComponent,
			_camera3D.y,
			_camera3D.z + xComponent );
	}
	if( _isRightKeyDown ) {
		_camera3D.position = new Vector3D(
			_camera3D.x + zComponent,
			_camera3D.y,
			_camera3D.z - xComponent );
	}
	if( _isPgUpDown ) {
			_camera3D.position = new Vector3D(
			_camera3D.x, _camera3D.y + 10, _camera3D.z );
	}
	if( _isPgDwDown ) {
		_camera3D.position = new Vector3D(
		_camera3D.x, _camera3D.y - 10, _camera3D.z );
	}
}

This gives is the ability to move around pretty much the same way you would in a first person shooter. You can drive with the mouse looking in one direction while walking in another. And because I'm keeping track of each of the direction keys independently we can move in multiple directions at once - diagonally.

What do you think?