And so the coding begins!

27 01 2009

I’ve sat down now and structured up some of my thoughts into basic Interfaces but to be able to visually organize everything I start up with setting up a little folder structure. Just like this:

folderstructure

I will be using Flex 3 as my IDE so some future screens will probably showcase that environment. If you do not know how to set up a Papervision project in Flex 3 this site is actually not the right one to find the answers in. I’ve seen plenty of great tutorials out there so I won’t dive into that here.

As you can see a lot more folders and structures will be needed later on but his will be perfect for the start I intend to write.  I know you are all eager to begin setting up a scene with Papervision but I actually will first create a few small classes first that will make it easier for me to explain how the units (as I will call all combat vehicles from now on) will behave. Let’s actually start with something as weird as the game controllers (!)

package interfaces
{
	// this is the Interface for all controllers, be it local, ai or remote via multiplayer.

	public interface IUnitController
	{
		// each Controller gives away a ControlMatrix-object containing at least the following parameters:
		// horizontal: , vertical: , newLastPosition:   if true then these values are used: , posX:, posY:, rotation:
		function getControl():Object
	}
}

I want to make sure that the network gaming will be a part of all planning from start and this is a great way to do that. Above is an interface that will make all controllers to behave in the same way. To show you a normal implementation of this interface, lets create a normal, local controller.

package controllers
{
	import flash.ui.Keyboard;
	import se.xcom.input.ArcadeKeyboard;
	import interfaces.IUnitController

	public class LocalController implements interfaces.IUnitController
	{
		private var key:ArcadeKeyboard
		public function LocalController()
		{
			key = new ArcadeKeyboard(Main.scope)
		}

		public function getControl():Object
		{
			var tVert:Number=0
			var tHoriz:Number=0

			if (key.isDown(Keyboard.UP))
			{
				tVert++
			}
			if (key.isDown(Keyboard.DOWN))
			{
				tVert--
			}
			if (key.isDown(Keyboard.LEFT))
			{
				tHoriz--
			}
			if (key.isDown(Keyboard.RIGHT))
			{
				tHoriz++
			}
			var Ob:Object = {vertical:tVert,horizontal:tHoriz,newLastPosition:false}
			return Ob;
		}

	}
}

This little class over here checks whether the arrowkeys has been pressed. Instead of sending a true for each direction, this class actually creates a Vertical axis where UP becomes +1 and DOWN becomes -1. On the Horizontal axis RIGHT becomes +1 meanwhile LEFT returns -1. I will later on show you how this can be useful in such arcade game. Also I’ve used a custom keyboard-class called ArcadeKeyboard that I created a while ago as AS3 does no longer contain the useful “isDown” features that AS2 had.  I’ve temporarly packed this class + a degreeconverter down for download here if someone would find it useful.

Now, let’s create a temporary Unit file just to see if we can control it with our controllers. But first I want to set up a decent Interface for our units as there are functions that all units to perform, eg. moving around, checking for collisions, attacking etc. For now, let us create this interface:

package interfaces
{
	public interface IUnit
	{
		function transformUnit():void
		function checkCollisions():void
	}
}

What this small interface just tells us is that: Every single unit that is even trying to implant me must have a transformUnit function and a checkcollision function. Sweet! But we will not stop there this time. We KNOW that all units will behave in a certain way when it comes to movement and collisioncheck. We also already know that each unit will be a DisplayObject3D (Papervisions own piece of DisplayObject), that each unit will carry a badass gun etc etc. So why create all this code over and over again for all units? Let us create an abstract class! You don’t know what that is? heck.. I’m just starting to learn myself, but to make it simple: an abstract class is a class that will never be instantiated on it’s own as it only contains parts of the code. That part is the code that is similar to ALL classes that will extend from that abstract class.

This is not supposed to be a lesson in OOP, but if you find the upcoming things weird and stupid I suggest you to find some tutorials or books that will cover the basics of OOP-programming, inheritance and design patterns as it will totally change your way of coding.  Now let’s get to business and maybe things will clear out a bit:

package units
{

	import interfaces.*;
	import org.papervision3d.objects.DisplayObject3D;

	public class AUnit extends DisplayObject3D implements IUnit
	{
		private var mesh:DisplayObject3D
		private var control:IUnitController
		private var transformer:ITransformer
		private var unitId:uint

		public function AUnit(mesh:DisplayObject3D, control:IUnitController,transformer:ITransformer, id:uint)
		{
			this.unitId = id
			this.mesh = mesh
			this.transformer = transformer
			this.control = control
			this.addChild(mesh)
		}

		public function transformUnit():void
		{
			// move and rotate the object due to the transformer.
			transformer.transform(mesh,control.getControl())
		}

		public function checkCollisions():void
		{
			// abstract , must be implanted later on!
		}
	}
}

Ok, lets see what we have now. This is an abstract class that will be the foundation of all Units hereafter. To create a unit we must therefor pass in a 3D-model (which I from now on will call meshes), we must also pass in a control which we alread happened to have created one. Good.
Then there is a new strange thing which I now call a Transformer. This is the component that will lie BETWEEN the unit and the controller. So from the controller comes data which buttons has been pressed (sort of). Now this TRANSFORMER turns that data into something visually splendid like moving the unit forward, rotating it, making it roll, float or shrink…
So even if we have the same controller for every unit they units might behave differenly as they have different transformers connected to them. Sounds intruiging, ey? Let’s create a transformer. After that I think we are ready to actually see something visual in 3D :)

package interfaces
{
	import org.papervision3d.objects.DisplayObject3D;

	public interface ITransformer
	{
		function transform(mesh:DisplayObject3D,control:Object):void;
	}
}

Each Transformerclass is now forced to have the function “transform” in them and also do they need to pass the parameters ‘mesh’ and ‘control’. Good, thats all we need! Let’s for starters make a simple Car-transform class (making the unit behave just like a car when controlled).

package transformers
{
	import interfaces.ITransformer;
	import org.papervision3d.objects.DisplayObject3D;
	import se.xcom.math.Degrees;	

	public class CarTransform implements ITransformer
	{
		// simple carsteering with no skid

		private var speed:Number	// current speed
		private var acc:Number		// accelerating force
		private var moveFric:Number // friction force (0 - 1.0)
		private var rotSpeed:Number // turning speed

		public function CarTransform(acc:Number, movementFriction:Number, rotSpeed:Number)
		{
			// setting up simple physics variables
			this.acc = acc
			this.moveFric = movementFriction
			this.rotSpeed = rotSpeed
			reset()
		}

		public function reset():void
		{
			speed = 0
		}

// now heres that most important part where the mesh will be transformed using the data from the controller.
		public function transform(mesh:DisplayObject3D, control:Object):void
		{
			// movement
			speed += control.vertical*acc
			speed *=moveFric
			mesh.x += Degrees.dCos(mesh.rotationY)*speed
			mesh.z -= Degrees.dSin(mesh.rotationY)*speed

			// rotation
			mesh.rotationY += rotSpeed*speed*control.horizontal
		}

	}
}

You wonder what that weird Degree class is? Well let’s put it like this. I’m selflearned in every way. I have not studied programming, nor game design and definitely not Math. So when the inbuilt Math class decides to use radians instead of degrees (which all displayobjects are using when rotating) I decided to create a simple class that lets you use Cos and Sin with degrees. There you go. If you’re a mathohman, please convert it to whatever you like. If you are like me, you can find the class with the other ArcadeKeboard class here.

Damn! This is becoming a huge post. I know we haven’t even compiled the code once yet and we got nothing to show so far but underneath the surface something really nice is about to happen. I stop his post right here and will soon be in again with our first 3D visuals. Yes I promise! Next time it’s time to dive into Papervision’s wonderful sea (space?)

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: