00:00
00:00
Newgrounds Background Image Theme

Arnahan just joined the crew!

We need you on the team, too.

Support Newgrounds and get tons of perks for just $2.99!

Create a Free Account and then..

Become a Supporter!

AS: Collision Detection

18,946 Views | 57 Replies
New Topic Respond to this Topic

AS: Collision Detection 2005-06-23 12:28:22


AS: Main

Collision detection is an important part of many different types of animations. Everything from games to menu bars depend on some form of collision detection to trigger events. The main method for dealing with these things is hitTest().

The hitTest method is overloaded. This means the method can operate two different ways based on the parameters you send it. The first way is sometimes refered to as a "basic" hitTest and the second as an "advanced" hitTest.

Basic Hit Tests

For those of you following along at home, create two movie clips, place them on the stage and give them instance names object1 and object2. Add the following actionscript to one of the movie clips.

onClipEvent (load) {
if (_root.object1.hitTest(_root.object2)) {
trace("Objects are touching");
} else {
trace("Objects are not touching");
}}

Now, test the movie and you will see one of the two messages above in the output window. Try moving the objects around and changing their size or shape so that you can see when Flash registers this as a hitTest and when it doesnt.

As it turns out, the basic hit test will return true any time the bounding box of the two objects is overlapping. Fox example, if one of the objects in the above code is a circle, Flash calculates it as a sqaure with sides the length of the diameter of the circle. In laymans terms, this means that it isn't 100 percent accurate for objects that aren't rectangles. So to become more accurate, onward to the advanced hit tests.

Advanced Hit Tests

The basic hit test only accepts one parameter, the movie clip that is going to be tested against. Advanced Hit Tests require three parameters: a x-coordinate, a y-coordinate, and a shape flag boolean. So, to use this type of hit Test you would use something like this:

onClipEvent (load) {
if (_root.object1.hitTest(_root.object2._x, _root.object2._y, true)) {
trace("Objects are touching");
} else {
trace("Objects are not touching");
}}

Again, test it several times moving around the objects and changing the shape and getting a feel for when Flash registers this hitTest.

This will test to see if the x,y coordinate point is touching object1. But why is that any more helpful? Because we were able to set the third parameter (shape flag) to true. This means that if object1 is a circle, then it will only return true when the x,y point is actually touching the circle instead of just the bounding box.

So thats great, but what if you want it to test it against the whole second movie clip instead of just one point? Well, this is where it gets a little hairy. You have two options depending on how important efficiency is to you.

First, you can just simulate it by using several points. For example, you could do a hit test on each corner of your movie clip or you could do the middle of each side. You could easily calcuate each of these points with the getBounds() method.

getBounds() is a method that returns a custom object with four properties. These four properties are xMin, xMax, yMin and yMax. _root.object1.getBounds(_root).xMax will return the maximum x value of object1. So what is the _root part for? Well it is the target coordinate space. If for some reason you wanted the xMax of an embeded movie clip, you could specify that. If you are going to repeatedly use the properties, you could do something like: boundingBox = _root.object1.getBounds(_root); and then call each of the properties by using boundingBox.xMax or boundingBox.yMin.

Second, you can do a sort of double shape flag hit test. This is by far the least efficient way to calculate collision detection, but it is the most accurate. Note: when testing this type, make your objects are small so it will take less time to calculate. The code looks something like this:

onClipEvent (load) {
xArray = new Array();
yArray = new Array();
for (x= _root.object1.getBounds(_root).xMin; x<=_root.object1.getBounds(_root).xMax; x++) {
for (y=_root.object1.getBounds(_root).yMin; y<=_root.object1.getBounds(_root).yMax; y++) {
if (_root.object2.hitTest(x, y, true)) {
xArray = xArray.concat(x);
yArray = yArray.concat(y);
}
}
}
for (z=0; z<xArray.length; z++) {
if (_root.object1.hitTest(xArray[z], yArray[z], true)) {
trace("Point to Point Hit Test True");
break;
}
}
}

This loops through every pixel on the first movie clip using an advanced hit test to see if the pixel is touching the actual shape of the second movie clip. It then tests all of the points that were touching the second movie clip back against the shape of the first to see if it is touching that too. So, if your movie clips are 50 by 50 pixels Flash could comupte up to about 5000 hitTests each time.

Well there you have it. Four different suggestions for collision detection. Pick whichever one best fits your needs. Decide if you just need it to be approximatly accurate in a fast paced high efficiency scenario or if only the end result matters regardless of how many hours it takes to compute.

Response to AS: Collision Detection 2005-06-23 12:32:08


Very good tutorial. I hope this'll help reduce the amount of "Help with hitTest" thread created weekly.


ey

BBS Signature

Response to AS: Collision Detection 2005-06-23 12:33:38


Good tutorial,I hope people having hitTest questions(usally noobs :( )Will read this before posting.The problem is that they don't use the searchbar :/


BBS Signature

Response to AS: Collision Detection 2005-06-23 12:34:41


Thanks, and I hope so too, but I know thats not going to happen. At least I can just link them to it now, instead of having to take the few minutes to explain it each time.

Response to AS: Collision Detection 2005-06-23 12:54:17


It's useful having the AS:Main thread in the notepad,everybody who reads my post,please add it to your notepad!


BBS Signature

Response to AS: Collision Detection 2005-07-03 03:05:08


Wow, great collision primer. :)

Okay, I currently have eight instances of a movieclip named wall1, and their instance names are all BG. My collision code seems to work great, but only on the first BG I added to the Scene actually blocks my player movement. The other seven BG movieclips don't collide with the player at all. Is there any way I can make them all work equally well when they all share the same instance name?

If not, what's the easiest way to have eight objects that all use the same graphic and collide with the player?

(I'd rather not have to give them all unique names and have to step though them in an array every single frame. :P Unless I have to.)

Response to AS: Collision Detection 2005-07-03 03:17:12


Well for starters, if you name more than one thing the same instance name, Flash can only recognize the first one that got the name. So thats why the rest of your platforms aren't working. You have a few options. The first one you already know: give them all different instance names and loop through them each frame. With only eight it's not too bad, but I'm going to give you a tip that really has nothing to do with collision detection, but is handy anyway. Create an initialization function that will automatically name the platforms and add them to an Array. Huh? Well it would look something like this:

number = 0;
allPlatforms = new Array();
function getNextPlatformName() {
number++;
return "platform" + number;
}
function addPlatform(name) {
allPlatforms += name;
}

And then just put this on each platform.
onClipEvent (load) {
this._name = getNextPlatformName();
addPlatform(this._name);
}

Or you could even put that in an as file and then just use #include platform on each.

THE SECOND WAY:
Is to put all of the platforms in the same movie clip. You will then need to use the getBounds() method on the hero and do shapeFlag hitTests (as I explained above) against the allPlatforms MC. When I made my platform game, I used this method. I created 8 points on the outside of my hero to test against the ground mc. For each point you make it stop moving in that direction.

Response to AS: Collision Detection 2005-07-03 03:45:43


Wow! Thanks for the speedy reply, BleeBlap. :) And thanks for the code! That's probabaly a technique I was going to need to know eventually, anyway.

I'm using regular hitTests, implemented in a kind of funky way. Four boxes slanted at 45 degree angles form a diamond around my player object, and if one of them is overlapping an obstacle, I won't let the object mode in that direction, even if a movement key is down. So, at least if I do need to test it against an indeterminate number of objects, each individual collision check is one of the low-overhead ones. :

I eventually hope to have an ingame editor that writes "tree-in-the desert" style maps, only instead of tiles, the levels will be built from scaled and rotated rectangles. There will probabaly be between 16 and 32 obstacles on-screen at any given time, plus enemies, bullets, etc. Do you think Flash can handle it?

If you have time to look at it, I'd like to send you the fla, which is still in the early stages, and get your opinion on things like whether or not my collision solution is any good, and how my code could be better optimized.

(All the Action Script is in a single object, and it's somewhat commented. :) Ehhh? Ehhhhh? )

Anyway, if you feel like taking a look at it, let me know and I'll e-mail it to you.

If not, thanks for the help you've already given me. :)

Response to AS: Collision Detection 2005-07-03 03:59:21


At 7/3/05 03:45 AM, WarpZone wrote: Wow! Thanks for the speedy reply, BleeBlap. :) And thanks for the code!

You're Welcome. You're Welcome.

:Blah Blah game editor Blah Blah lag?
The very moment before I started writing this reply I was working on an in game level editor. Your's sounds like it is going to be a touch more complex than mine is. As far as the hitTest lag goes, I'm not really sure, the best way to test it would be to try it. I havn't used basic hitTests in a long time so I don't have a very good idea of how much more efficient they are. I can tell you that using advanced hit tests and 24 frames per second in my platformer, it takes about 8 enemies before it starts to lag. That would be 64 advanced hitTests against the ground plus another 20 or so for attacks and things, plus loops for whenever an enemy or character is going to come in contact with the ground. I know that doesn't translate very well into your game, but it gives you the idea that there is a chance you can run it without lag.

(All the Action Script is in a single object, and it's somewhat commented. :) Ehhh? Ehhhhh? )

Damn, I wish I commented all of my code :( or even just some of the convoluted stuff for myself when I go back through.

Anyway, if you feel like taking a look at it, let me know and I'll e-mail it to you.

Usually I'm not a big fan of this, but tonight I'm feeling nice and you seem intelligent enough to take whatever help I give you and actually use it, so sure.

Response to AS: Collision Detection 2005-07-03 07:42:19


thanks alot, i have been tryind to do this for ages but couldnt figure it out, easy to understand 2 .
thx again

Response to AS: Collision Detection 2005-07-03 23:52:46


At 7/3/05 03:17 AM, BleeBlap wrote: number = 0;
allPlatforms = new Array();
function getNextPlatformName() {
number++;
return "platform" + number;
}
function addPlatform(name) {
allPlatforms += name;
}

It gave me an error because the word "number" is a reserved AS command. :P

So I renamed it to RoomCount.

I've decided that my world will not be made up of walls, but rather, rooms. Each room will be either a non-rotated rectangle or a circle. I figure if the size and location of these are loaded into memory anyway, I should be able to detect the boundaries of each of these mathematically without using any collision commands at all.

The tricky part will be connecting the rooms to each other and teaching my code that if you pass from one room to another, it doesn't count as a barrier.

Now I can't seem to find the "collision between two spheres" code example. I had it earlier today... anybody know where I could find it?

Response to AS: Collision Detection 2005-07-04 00:55:42


Fool, you don't put them in load, you put them in enterFrame, otherwise it'll just run once.


wtfbbqhax

Response to AS: Collision Detection 2005-07-04 18:52:32


At 7/4/05 12:55 AM, SHITTYFLASHMAN wrote: Fool, you don't put them in load, you put them in enterFrame, otherwise it'll just run once.

Yes, I only wanted them to run once. What point would there be in showing the same result over and over again in the examples? There is no point in test every frame because the movieclips will be in the same place. If it where in a game, then yes, you would want to test it every frame.

And to the guy right above him, the circle hitTest is in Glaiel's collision tutorial located here: http://www.newgrounds.com/bbs/topic.php?id=296755

Response to AS: Collision Detection 2005-08-25 10:21:10


if (this.hitTest(_root.bg["wall"+i]._x , _root.bg["wall"+i]._y, true))
{
speed -= speed;
}

Why isn't this working???? I can't figure it out...


Visit JackSmack.com and submit your Flash Games!

BBS Signature

Response to AS: Collision Detection 2005-08-25 10:26:29


yes it is within an On clipevent(enterframe) handler....

I am really stumped.


Visit JackSmack.com and submit your Flash Games!

BBS Signature

Response to AS: Collision Detection 2005-08-25 10:30:03


At 8/25/05 10:27 AM, SpamBurger wrote: Well, when you enter the code does it say there are errors or it just doesnt work?

No... there are no errors at all. it starts up and runs but he goes right through the walls.

I'm using flash 5 could that be the reason? I thought that this should work in flash 5.


Visit JackSmack.com and submit your Flash Games!

BBS Signature

Response to AS: Collision Detection 2005-08-25 10:35:07


Is it in a for loop?

for(i=0;i<10;i++){
if (this.hitTest(_root.bg["wall"+i]._x , _root.bg["wall"+i]._y, true)){
speed = 0;
//it does the same thing..
}
}


Sup, bitches :)

BBS Signature

Response to AS: Collision Detection 2005-08-25 10:47:28


At 8/25/05 10:35 AM, -liam- wrote: Is it in a for loop?

for(i=0;i<10;i++){
if (this.hitTest(_root.bg["wall"+i]._x , _root.bg["wall"+i]._y, true)){
speed = 0;
//it does the same thing..
}
}

Yes it is in a for loop... but I've tryed it by just naming the wall "wall" and pointing this code directly at it... NADA..

I think I'm doing everything right that I should ... I will post all the code from the character that should help.

__________________________________________
__

onClipEvent (load) {
speed = 12;
bgspeed = 12;
}

//MOVEMENT
onClipEvent (enterFrame) {
if (Key.isDown(Key.UP)) {
_parent._y += bgspeed;
tellTarget (_parent.character) {
_y -= speed;
gotoAndStop ("up");
}
}
if (Key.isDown(Key.DOWN)) {
_parent._y -= bgspeed;
tellTarget (_parent.character) {
_y += speed;
gotoAndStop ("down");
}
}
if (Key.isDown(Key.LEFT)) {
_parent._x += bgspeed;
tellTarget (_parent.character) {
_x -= speed;
gotoAndStop ("left");
}
}
if (Key.isDown(Key.RIGHT)) {
_parent._x -= bgspeed;
tellTarget (_parent.character) {
_x += speed;
gotoAndStop ("right");
}
}

this.swapDepths((_y*2)-1);

//WALL HIT TESTS

for (i=1; i<30; i++) {

if (this.hitTest(_root.bg.wall._x , _root.bg.wall._y, true)){
speed -= speed;
//it does the same thing..
}

//INVENTORY HIT TESTS
if (this.hitbox.hitTest(_parent[item+v])){
}

//ENVIORNMENT HIT TESTS

if (this.hitbox.hitTest(_parent["fire"+i])) {
_root.hpscore -= 2;
}

if (this.hitbox.hitTest(_parent["poison"+i])) {
}

//ROLLING ROCKS

for (w=1; w<3; w++) {
if (this.hitbox.hitTest(_parent["rock"+w].lef
t)){
_parent["rock"+w]._x -= speed;
_parent["rock"+ w].sideroll._rotation -= 22.5
}
if (this.hitbox.hitTest(_parent["rock"+w].rig
ht)){
_parent["rock"+w]._x += speed;
_parent["rock"+ w].sideroll._rotation += 22.5
}
if (this.hitbox.hitTest(_parent["rock"+w].up)
){
_parent["rock"+w]._y += speed;

}
if (this.hitbox.hitTest(_parent["rock"+w].dow
n)){
_parent["rock"+w]._y -= speed;

}

if (_parent["rock"+w].left.hitTest(_parent["w
all"+i])){
_parent["rock"+w]._x -= speed;
_parent._x += speed;

}
if (_parent["rock"+w].right.hitTest(_parent["
wall"+i])){
_parent["rock"+w]._x += speed;
_parent._x -= speed;
}
if (_parent["rock"+w].up.hitTest(_parent["wal
l"+i])){
_parent["rock"+w]._y += speed;
_parent._y -= speed;
}
if (_parent["rock"+w].down.hitTest(_parent["w
all"+i])){
_parent["rock"+w]._y -= speed;
_parent._y += speed;
}

}

}

//DEATH
if (_root.hpscore<=0) {
tellTarget (_root) {
gotoAndStop ("gameover");
}
}
// DEPTH CHANGE

}
onClipEvent (load) {
this.swapDepths(this._y);
}
__________________________________________
_____________

do you see anything wrong here?

I've double checked and EVERYTHING is named right...


Visit JackSmack.com and submit your Flash Games!

BBS Signature

Response to AS: Collision Detection 2005-08-25 10:49:54


So you've tried this?

for(i=0;i<10;i++){
if (this.hitTest(_root.bg["wall"+i])){
speed = 0;
//it does the same thing..
}
}

If the wall is a square/rectangle/line then thats all you need.


Sup, bitches :)

BBS Signature

Response to AS: Collision Detection 2005-08-25 10:54:06


for the double bounding box check, why not make a version that loops through every 10th pixel? It wiuld still be accurate but it would also reduce the number of loops greaty (25 vs. 5000)

Response to AS: Collision Detection 2005-08-25 10:54:36


At 8/25/05 10:49 AM, -liam- wrote: So you've tried this?

for(i=0;i<10;i++){
if (this.hitTest(_root.bg["wall"+i])){
speed = 0;
//it does the same thing..
}
}

If the wall is a square/rectangle/line then thats all you need.

Well to be honest I want a 4 sided wall. That doesn't make the speed = 0 it makes it = -speed for one frame so that the character can't go through it.

Iglndor or however you spell it (you know who I'm talking about) laughed at me for how I had it set up earlier with hit tests.

I had square clips with 4 clips inside them for up down left and right movement. he said that was a waste of time and I should try this so I'm trying but it's just not workin...


Visit JackSmack.com and submit your Flash Games!

BBS Signature

Response to AS: Collision Detection 2005-08-25 10:56:45


At 8/25/05 10:54 AM, Glaiel_Gamer wrote: for the double bounding box check, why not make a version that loops through every 10th pixel? It wiuld still be accurate but it would also reduce the number of loops greaty (25 vs. 5000)

Just so you know... you are speaking greek to me there... not a clue what you are talking about.

I'll try opening this in mx and seeing if it works i guess.


Visit JackSmack.com and submit your Flash Games!

BBS Signature

Response to AS: Collision Detection 2005-08-25 10:59:38


At 8/25/05 10:56 AM, JackSmack wrote:
At 8/25/05 10:54 AM, Glaiel_Gamer wrote: for the double bounding box check, why not make a version that loops through every 10th pixel? It wiuld still be accurate but it would also reduce the number of loops greaty (25 vs. 5000)
Just so you know... you are speaking greek to me there... not a clue what you are talking about.

I'll try opening this in mx and seeing if it works i guess.

I was talking to the topic starter, and BTW I meant shapeflag instead of bounding box

Response to AS: Collision Detection 2005-08-25 11:16:52


At 8/25/05 10:59 AM, Glaiel_Gamer wrote: I was talking to the topic starter, and BTW I meant shapeflag instead of bounding box

oh sorry about that...

Yeah I tryed this in MX and it didn't work still... something has to be wrong with the code. it's not flash that is screwing up.


Visit JackSmack.com and submit your Flash Games!

BBS Signature

Response to AS: Collision Detection 2005-08-28 11:23:48


Hell im wondering about some thing.

---

I just need three things from you guys: [thank you]

1. Can you give me left, right, jump code. Please i need the script that when you go LEFT it shows left and WHEN right IT shows RIGHT and when jump it looks normal and goes up.

[i know this part: you make the mc of a character: 1fram = walking right, 2nd fame jumping and 3rd fame jump]

2. I need walls and im wondering if this is going to work:

(i=1; i<30; i++) {

if (this.hitTest(_root.bg.wall._x , _root.bg.wall._y, true)){
speed -= speed;
//it does the same thing..
}

3. And is this going to make my character die:

//DEATH
if (_root.hpscore<=0) {
tellTarget (_root) {
gotoAndStop ("gameover");
}
}

[so i just put it in a MC and thats it right? do i have to do anything with instance or var please tell me]

4. And im wondering about hitTests. When i reach to my portal to next level [MC] i put the hittest and im wondering how i can make it go to another FRAME. [please help on this]

----
And i looked at this and this is good for nothing what im talking about it is just like zelda only:

//MOVEMENT
onClipEvent (enterFrame) {
if (Key.isDown(Key.UP)) {
_parent._y += bgspeed;
tellTarget (_parent.character) {
_y -= speed;
gotoAndStop ("up");
}
}
if (Key.isDown(Key.DOWN)) {
_parent._y -= bgspeed;
tellTarget (_parent.character) {
_y += speed;
gotoAndStop ("down");
}
}
if (Key.isDown(Key.LEFT)) {
_parent._x += bgspeed;
tellTarget (_parent.character) {
_x -= speed;
gotoAndStop ("left");
}
}
if (Key.isDown(Key.RIGHT)) {
_parent._x -= bgspeed;
tellTarget (_parent.character) {
_x += speed;
gotoAndStop ("right");
}
}

this.swapDepths((_y*2)-1);

Response to AS: Collision Detection 2005-08-28 11:26:52


At 8/28/05 11:23 AM, mehrdad99 wrote: 1. Can you give me left, right, jump code. Please i need the script that when you go LEFT it shows left and WHEN right IT shows RIGHT and when jump it looks normal and goes up.

If I gave you a code, it would probably cause problems due to the fact it isn't personalized to your flash, so no.

2. I need walls and im wondering if this is going to work:

[code]

You copy and pasted that code from me.. I posted that the other day, wtf?

3. And is this going to make my character die:

[code]

No, copying and pasting snippets from others codes will not work.


Sup, bitches :)

BBS Signature

Response to AS: Collision Detection 2005-08-28 11:33:20


Why the fuck are you using tellTarget?

(i=1; i<30; i++) {

if (this.hitTest(_root.bg.wall._x , _root.bg.wall._y, true)){
speed -= speed;
//it does the same thing..
}
Why are you using a for loop? if you want to test multiple walls it should look something like:

for (i=1; i<30; i++) {

if (this.hitTest(["_root.bg.wall" + i]_x , ["_root.bg.wall" + i]_y, true)){

....etc

3. And is this going to make my character die:


//DEATH
if (_root.hpscore<=0) {
tellTarget (_root) {
gotoAndStop ("gameover");
}
}

[so i just put it in a MC and thats it right? do i have to do anything with instance or var please tell me]

Putting that on a MC within a handler such as enterFrame
will work

And im wondering about hitTests. When i reach to my portal to next level [MC] i put the hittest and im wondering how i can make it go to another FRAME. [please help on this]

if(this.hitTest(that)){
gotoAndPlay();
}

simple no?

And i looked at this and this is good for nothing what im talking about it is just like zelda only:

What are you talking about?

Response to AS: Collision Detection 2005-08-28 15:21:25


ok thank you for the walls and the auto hit THat HELPS so MUCH! and now when i was talking about zelda is that the move: up down, left & right. I want my character to have the JUMP and left And RIght Script. If you could give me that and the instance name that would be grate ful and please if your putting it tell me if its going to work the the codes you gave me for the walls & the dieing part & the next level.

[Simple way: whats the code for jump, left & right but i want it on a MC with go to FRAME 1 if key right, go to FRAME 2 if key left AND go to FRAME 3 if JUMP so ill draw a little character and on frame one ill make him right and second left and third is looking starigt so when he jumps he looks starirt unless u can give me the code with when jumping left it goes to FRAME 2 and hes going up and when they press right and jump it looks like the same way of right nut jumping.

Response to AS: Collision Detection 2005-08-28 16:05:59


At 8/25/05 10:54 AM, Glaiel_Gamer wrote: for the double bounding box check, why not make a version that loops through every 10th pixel? It wiuld still be accurate but it would also reduce the number of loops greaty (25 vs. 5000)

Because that would be too practical. I wrote it as I was writing this tutorial and I've never had a real need to use it. You could do it once every 10 pixels or once every 10th of the shape so the number of hitTests doesn't vary depending on the size (but the accuracy does). Before using the code in a game you would have to make that sort of modification.

mehrdad: I think you might be more interested in one of the platformer tutorials located: 1 2 3 Any of the above will give you code that will allow you to move like that and they explain the code (some better than others). If you still have specific questions about hit tests I would be glad to answer them here.

Response to AS: Collision Detection 2005-08-28 17:13:24


Woh. Thanks i like number 1 & 2. Number 1 is EXTREAMLY long but you gain atleast 50% of flash Scripts i think or more. ANd number 2 is just simple and easy i like that.

Thanks ALl