3D-Collisions basics

13 02 2009

One thing that is absolutely vital in most games is the actual event when two objects somehow collides.

Be it bullets that collides with it’s target, wheels touching the floor, a paperMario reaching the end of the map or just a FPS-player that tries to walk through a wall, we just need to see whether something is touching something else (especially if inappropriate :) ) Now, there are several ways to detect this and as usual it’s all about processor vs quality. The absolute best and accurate way to do this is to let every single face check with every other single face out there if it has intersected and then dispatch that a collision has occured. Now, this (we call it face <-> face collision) is extremely demanding and even top notch 3D accelerated AAA-titles barely uses it so let’s just put that aside for the mathgeeks and dreamers and let’s look at some realistic aternatives.

Let us start in the other end. How fast can we go??? Well, I say (you can bash me as much as you want to, I have not studied this at all) that he fastest kind of collisiontest you can have is to just make a static numbercheck.

if (mesh.y < 0) { mesh.y = 0}

Yes, we all fid it extremely obvious but sometimes people make things WAY to difficult for them. Still in this game I have used this collisiontype many times where some people would have tried a more demanding approach just for the sake of being dynamic. Just because of the processorpower it takes to detect collisions I have purposely chosen to create a rectangular arena, opposite to the arena I used in my last game. It doesnt have any walls at the moment but when it get walls I don’t have to create some difficult collisioncheck, just a static numbercheck will make the job!

What about the ground?? Well I could have added bumbs in a sandy arena but now I choose a flat one for several reasons.

1. As soon as something like the grenade goes Z < 0 it will bounce up again.

2. When it’s flat and no units will be able to jump/have physics, I can remove all bottom faces of the unit. You should see them, they are all stripped and seethrough from underneath.

3. Putting obstacles on the arena (extra walls, barrels etc) is as easy as Z=0

Now you probably already knew this stupid collisioncheck but I still want you all to remember this simple solution when creating your design for the game. Maybe your 3D pong should go with square walls instead of your freakishly new plasmastyle.

Now, lets start with some “real” collisiontesting then. After the static one, I might be brave enough to say that the next least perfomancedemanding collisioncheck is a single distancecheck. “How far from this object is that object?? Is it to close? then BOOOM!” -style.

In Papervision we got the math already done with it’s  function: DisplayObject3D.distanceTo(otherObj:DisplayObject3D) .  (no it’s not rocketsciencemath either but it’s nice we don’t have to dig out mr.Pythagoras more than needed)

If the distance is lesser than your set value, then you consider it to be a collision. Now, this method is very rarely used but if we enhance it just a liiiiittle bit you will have one of the most common collisiontests in games…

Sphere-collision

When I was a kid, (yes, I promise i have been) I just couldn’t understand how spherecollision could be faster to use than ermm.. other that we will bring up in a short while. Spheres are complicated and as soon as round shapes are involved it means using PI and Sinus and maybe derivata. No, not this time. If you just think of it for a second: distanceTo() is really a sphere. It doesn’t have any direction but checks the distance in EVERY direction building a kind of a “sphere” around the object where the distance is actually the radius of the sphere. Look at this image:

spherecollision

Here I have set a distanceTo limit on the Defender and a distanceTo limit on the grenade so in code it is just:

if (defender.distanceTo(grenade)- (defender.collisionSphereRadius+grenade.collisionSphereRadius) < 0)  { trace(“defender is FUBAR!!!”)}

It’s all about the distance between the objects but we added some kind of radius to each object simulating it’s size. In my game I have set this radius manually and actually do have a “showCollisionSphere” function on each unit and bullet so I can see that it is somewhat correct with the size of the mesh. Still in Papervision3D DisplayObject3D you already have tis kind of collisiondetection in the function: hitTestObject( obj:DisplayObject3D, multiplier:Number=1 ):Boolean

This function takes the furthest pixels away and creates a radius out of that. This could create a collisionsphere that might not be the best for the whole object and therefor there is also a multiplier parameter if you would like to increase or decrease the size of your “sphere”. It works great (I just wanted to create my own flexible collisioncheck but I recommend using the inbuilt one).

Box Collision

What if my object is very flat? It might even be a plane! Creating a collisionsphere around that would just be stupic as it would, in worst cases, trigger collisions way beyond the actual planes location. The other single method that is used just as much as sphere collisions is the box collision. You have probably done it a thousands times already keeping something within a boundary or similar tasks.. does this looks familiar?

if (obj.x > MAX_WIDTH){obj.x = MAX_WIDTH;}

else if (obj.x < MIN_WIDTH){obj.x = MIN_WIDTH;}

if (obj.y > MAX_HEIGHT){obj.y = MAX_HEIGHT;}

else if (obj.y < MIN_HEIGHT){obj.y = MIN_HEIGHT;}

this is actually the technique to use with box collisions. Just check wether a box is within another box.

In every DisplayObject3D that contains a geometryobject you can somewhat easily achieve this as the geometryobject contains a variable with the freakedout name: aabb

This is actually the bounding box we need ( yes it is short for AxisAlignedBoundingBox). It holds all the MAX and MIN values of your mesh in all 3 dimensions so it’s just a matter of creating a lot of “If”‘ rows and you will have your own box collisiontest. Box collision is not as fast as spherecollision but is a very good alternativ for meshes with different proportions.

This was just some simple theory. I will try to stitch this up in some real code in the game to show you later on. Now already I can tell you that if you want to optimize collisioncheck you really should think about WHICH objects really do need to be checked with each other?? Can I remove some of the collisionchecks without harm? All geometry will probably not need to be checked against each other and even some units doesnt have to be checked with some bullets (eg the unit that shot the grenade doesn’t need to be collisionchecked with the nade). I am fond of lists in different ways so I will probably create one now again where objects subscribes to the list where it needs to check with other objects in that particular list.

59

The just-released StreetFighter IV went back from polygon collision to use classical box-collision just to speed up and recreate the classical feel of the game.

Also one small notice is that there are several other types of collisionchecks but thse are by far the most common ones. They are also very easy to mix together and it’s not unusual that game uses BOX <-> SPHERE collisions and POLYGON <->BOX etc.   Hope I could at least enlighten someone with this basic theoretical text. Have a great time creating things I can play!

Advertisements




Kill your darlings

9 02 2009

One of the most important tips I could give you in here is not in any AS3 area nor is it a 3D tweak but it’s a pretty common saying in many creative industries.

‘Kill your darlings’. The simple meaning of this is to try to be as objective as possible and don’t fall in love in some of your best functions, your nicest effects or you genius structures. The hardest thing you will face is when you show your work to the crowd/your friends/or even worse your children and they just say..  “Why did it act like that?” It’s so idiotic obvious and STILL they have the guts and ask such a question??? Or maybe: “So what am I going to do now then?”, “It feels like it’s warping”. But bugs, and bad playability can be dealt with. The WORST thing you will face is when things work terrific! When your effect is just heavenly and you have just created the smartest AI ever and then you’re audience is telling you that, “The effect is bringing the speed down”, or “The guys act too smart, remember it is meant to be casual game. Let them just jump out and be shot!”

I’ve worked with a couple of game publishers and game development has never been as hard as when it is chopped, sliced and stripped from all genius quality just because it need to be more accessible for a bigger audience. You’re genius gameplay is switched with an old overused controlscheme, just because people want what they always done…

Now, we are not all there and most of us will probably face that problem having to answer in front of a publisher BUT this is an important lesson to be learnt in everyday game development. Take this tank I created today:

flamethrower

This tank has been in my plans for a long time and when I finally created the flamethrower I think it looks just great to be Papervision. Still I know I cannot even consider using this weapon after creating it. Why? Well, when holding down the mousebutton, spraying out all that fire the fps drops under 22 fps. It’s a nice effect and I’m quite proud of the result but I know that in the end, I will cut off a lot of players if I let such a demanding effect be in the game. 22 FPS is no big deal but this is just one tank, what if both players use the tanks? Many players will have lesser performing computers than I have, there is still a HUD to be implanted, some collisiondetection, environmentart, sound etc…

Listing it up like this it sounds obvious not to use the effect but I see this over and over again. People fall in love in their physics, in their animated textures, in their multiplied blendmodes.. and in the end as the FPS drops they just can’t ‘kill their darlings’ and instead loose the interest.

Have I removed the idea of the flamethrower? No, not yet, I still have a couple of methods to try but Papervision is really a tight area and demands optimization and chokes immediatly at the slightest overuse of effects or bad coding. Just face it. Choose what few elements you want to have and stick with it. You cannot have shadows, particles and physics and in the middle of development include environmentmaps. You will have great screenshots but you will never be able to release the game to public.

Kill them. Move on.





The importance of being lazy!

29 01 2009

I will soon code a LOT, actually I’ve started already behind this scene but before I make it official and show it all to you I want to pull the breaks and look in the rear window so I got all of you with me. Why’s that? Because if you don’t get the structure that’s in my head, a big part of the next upcoming code will be just a copy and paste experience and you’ll probably learn nothing so let’s take a look and let me explain some things for you. (naah you’re all smart, I’m just repeating it to understand it myself!)

Lets start with an Image:

classstructure

If we start from the bottom we have actually already created some of these “components”. The interesting thing as that all the words down there but “MESH” starts with an ‘I’. It’s because we are focusing the Interface of that component. Creating an interface makes it so much easier to code a bigger project as I don’t have to worry about how many different “transformers” I need to make or how they will be implanted. I don’t even have to create fully functional classes. This is called to “code towards the interface”. For OOP-experienced coders this is basic material but somehow Actionscript has attracted a lot of designers into the coding world and haven’t until AS3 really faced this way of programming.

So, now lets say I create a lot of controllers, transformers, weapons and shots (which will be the physical ‘bullet’ fired from the gun) I can now extend the AUnit (abstract class) into a unique unit, eg. Defender and place one of each component types in there.

As AUnit now already have the public function transformUnit() and also checkCollisions() it means that I can have as many units on the scene as I want to, looking different, behaving differntly, is controlled differently but still will be exactly the same to handle for the main core engine. Eg. Lets create 3 different units:

var arUnits:Array = new Array()
var player:AUnit = new Defender()
var computer:AUnit = new Tank()
var LANgamer:AUnit = new Soldier()

arUnits.push(player)
arUnits.push(computer)
arUnits.push(LANgamer)

for each(tempUnit:AUnit in arUnits)
{
	tempUnit.transformUnit()
	tempUnit.checkCollisions()
}

This simple code above creates 3 different units but they are all typed AUnit (!) this means we can treat them exactly the same and loop through them but they will react differently depending on which components they have inside them. Great!  I don’t have to code a loop for each unit! I don’t have to code the management for each controller, nor for each weapon.  I just code how they will behave. Now that I feel that I’ve sorted this out a little more I will start working on those weapons and clean up the previous code so we can focus on the fun part in here.





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?)





The challenge of creating a game without writing a single line of code

26 01 2009

If you’re new to OOP (which I still do consider myself to be) words like Interfaces, Abstract classes and Polymorphism might sound pretty intimidating, but trust me, it will make your life so much easier (no your private life, don’t mix polymorphism into that!). 3 years ago when I started up this project and coded in a very simple 3d environment (Blitz3D) I coded in classical functionbased way. Using a lot of codefiles and structured foldersystems worked but for each playerunit that was added the code got heavier to support and bugfix. The big catastrophy happened when I decided to look at networking and multiplayer parts.

The whole static code for each unit needed to be rewritten to allow smooth multiplayer communication. And so the project came to a halt.

Now how can we prevent this?? Well, at least we can make it much easier to support and change in code without the whole project is falling apart by using these nice OOP features and design patterns. Even if it also will mean some extra code for startes it will mean a lot LESS code by the end of the project as we will be able to reuse a lot of the code.

Now here is my challenge:

screen3

The actual game (stripped from multiplayer lobby, scoreboards, rankingsystems, boardmode etc) is a simple 2p fast paced game where the players control one unique unit chosen from 10 different units. They will drive, fly and roll around on an battlearena trying to kill each other with different types of weaponarsenal. Each type of unit will have different ways of control, transport, behaviour and weaponry. AND there will be networkcode! The game will be in 3D but the units themselves will be controlled on the flat arena surface (for now) which means that we can actually start creating this game as a 2D game until visuals will be an issue.

The first thing that pops up in my head is: components!

Yes, of course. If I just could have a general unit with actually no things mounted at all on it we could just add what is needed to create a unique unit. Say we add some way of transportation (wheels? wings? teleporter?). We also need some control system to use the transportation with. Then we add some kind of weaponry. To the weaponry we need ammo (as this could actually be different to one single gun). At last we could add a “black box” containing data about damage and such which could be useful in such a game.

Without really creating any useful code that does something, we at least have a structure of the units we will play around with. Using my small pieces of papers I could write down something like this:

UNIT

  • Controller
  • Transportation
  • Gun
  1. —– Ammo
  • BlackBox

Now we have a great foundation to create as many different combat units that we want to, structured in a meaningful way. All we need is to have some kind of engine to take each unit and go through these components step by step and give them the same general command.

Eg. Engine takes the first unit, a tank. First checks controller if any button been pressed, then it checks the transportation and uses the data it got previously to steer the tank in a “tankish” way. Finally it checks wether a gun has been fired and if thats the case it uses the weaponcomponent to fire away a bullet of the Ammo-type.

The same procedure will be used wether it be a single soldier, an aircraft, a laserbeam or guided missiles. Time to get it into code… stay tuned!