Category Archives: Actionscript 3.0

Adobe Flash / Actionscript 3.0

How to check for collisions in AS3

Hi !
I am going to share another tip for all the as3 developers making games out there.
Today, we’re going to talk about collision detection in Actionscript 3.0
There are 3 different methods for testing the collision between two graphical objects (displayobject) in as3:
The first is using hitTestObject, a simple method that will test if the two objects hit each other. The main problem with this method is that it uses the DisplayObject bounding box which means that if the shape of your object is irregular, there will be empty spaces that will be considered to hit other objects even if they are graphically separated.

The second is using hitTestPoint. This is better because it allows you to test the collision of a DisplayObject with a specific point. It also has an option (boolean) to check for the actual pixels of the object and not the bounding box. This is a good option if you want to test smaller objects (like projectiles) against complex shapes.

The third is using the BitmapData of the object: BitmapData.hitTest.
However, this is much more complex and will require more CPU, probably impacting the performance of your game. There are ways to diminish this impact, such as first testing with a hitTestObject then using the bitmapdata, using quadtrees, etc.
But as those are rather complex and since most games don’t actually require pixel-perfect collisions, i won’t be talking about that.

The best way to do a somewhat accurate collision detection in AS3 i found was this:
Using hitTextObject!
“Wait…you said it wasn’t working with complex shape!” is what you’re probably thinking now…and you are correct. However, what if we were using several displayObjects instead of a single one ?
Here is a picture of how collision detection is used in my game:
AS3 hitboxes

In blue is the normal bounding box for the movieclip. In purple you can see the different hitboxes i will be using to check the collisions. It sure takes much more time to test all those but it is much faster than checking ALL the opaque points like the bitmapData.hitTest would do.
So here is what we do: test the collision with hitTestObject. If it is a hit, test it again but with each hitBox (you can stop the loop when it has hit one, that is a small optimization). Have an Array or Vector. in your objects containing the hitboxes (you can get them from the scenario using getChildAt in a loop).

Insert this in a game logic loop or as a collision method(assuming public properties…in your game, use getters instead):

if (object1.hitTestObject(object2))
{
for (var i:int = 0; i < object2.hitBoxes.length; ++i)
{
if (object1.hitTestObject(object2.hitBoxes[i])
{
trace("COLLISION!!");
break; //comment this if you want to test each hitbox even if one was hit)
}
}
}

And voilĂ  ! Collision detection that works with complex shapes. If you want to test 2 complex shapes, you will have to add another loop and test each hitbox against each hitbox which is obviously a bit more time consuming for the game but it will work and be faster than pixel-perfect tests anyway…
Here are 2 examples. In the first one, i use simple hitTestObject collision testing:

In this one, however, i use the multiple hitboxes method i described earlier:


As you can see, even if it is not pixel-perfect, it is much better! You could eventually come very close to pixel perfect collision testing if you added a lot of hitboxes but remember the more hitboxes you have, the more tests are done…

Download the source code

Hope this helps some of you, good luck on your game development!

FPS independent gameplay in Flash/Actionscript 3.0

I’m currently developing a game for PC/MAC using Adobe Air and Actionscript 3.0 which has led me to test quite a few methods to achieve smooth gameplay. At first, i tried to use a timer instead of the enter_frame loop i often see because i’m more used to C / C++ and that is usually how you make a game loop in those languages. However, i soon found out that in Flash, the timers aren’t really fps independent. By testing my game in settings that lowered the frames per second (such as heavy population of hundreds of movieclips, software rendering, etc.), i discovered than even if i wasn’t relying on the ENTER_FRAME event for my updates, the gameplay would slow down to the point of being almost synchronized with the fps. That was a big issue and even though i managed to have the game really smooth at 60fps by using the GPU scaling (stage.fullScreenSourceRect), if a fps drop occured you would feel it gameplay wise.

For a video game, gameplay updates are what is really important. Smooth framerates are nice but hard to achieve because of the variety of configurations of the pc market. What should never be different on any computer is of course the gameplay, and this is why in other languages you usually update the screen and gameplay asynchronously. In Flash, there is no way to do this the way you would do it in…say, C++ for exemple. The best way to ensure the gameplay will be smooth is actually to use the ENTER_FRAME event listener and, inside the function called, check the time elapsed between updates. Once you’ve checked that time, you need to see if enough time has passed to allow for one or more updates to the gameplay. Or you can use the delta time (time difference between previous call and the current one) and pass it to your game objects to update them accordingly.

package
{
import flash.display.MovieClip;
import flash.utils.getTimer;
import flash.events.Event;

public class GameLoop extends MovieClip
{
  private var oldTime, newTime: int;
  private var frequency:int = 16;

  public function GameLoop()
  {
   addEventListener(Event.ADDED_TO_STAGE, initok);
  }

  private function initok(e:Event):void
  {
   newTime = 0;
   oldTime = getTimer();

   addEventListener(Event.ENTER_FRAME, loop);
  }

  private function loop(e:Event):void
  {
    newTime = getTimer();
    while (newTime >= oldTime + frequency)
    {
      oldTime += frequency;

      /* Gameplay logic */

    }
  }

OR
  private function loop(e:Event):void
  {
    newTime = getTimer();
    if (newTime >= oldTime + frequency)
    {
      var deltaTime:int = newTime - oldTime;

      /* Gameplay logic exemple */
      gameObject.update(deltaTime);

      oldTime = getTimer();

    }
  }


 }
}

And there you have it. It’s as simple as that. You can test it with a crappy fps set in your flash file and a better one. Gameplay wise, your game won’t be any different (unless you’re playing on a very old machine or doing intense computing inside the gameplay logic, but in that case you should probably try to optimize that anyway). Of course, since we’re relying on the ENTER_FRAME event, if you get less than 10fps the game will probably feel a bit choppy…but at least the gameplay will stay the same and it won’t change your game.

Hope this helps someone avoid the struggles i’ve been fighting against during this development.
Stay tuned for more and probably some game making tutorials in AS3, C++/SFML and other languages!