Forum Topic: As: Circle To Shape Hittest

(3,614 views • 20 replies)

This topic is 1 page long.

<< < > >>
None

23450

Reply To Post Reply & Quote

Posted at: 4/16/06 07:00 PM

23450 LIGHT LEVEL 27

Sign-Up: 05/28/03

Posts: 7,297

AS: Main

WorkingFile

The concepts for this type of hitTest are all in AS: Main, but i figure i could combine a few to create a neat hitTest. I will show you how to create a hitTest between a circle and any other shape. It will involve a loop and some simple trig. So, first set up your radius variables in an onLoad handler.

radius= ###

Make radius whatever the radius of your circle may be. Next we will crate the loop.

for (=0; i<360; i++) {

This loop is going to be used for your angle. Since a cirlce has 360 degrees, you want the loop to be 360 in order to cover the entire circle.

X = (Math.cos(i*(Math.PI/180))*radius)+_x;
Y = (Math.sin(i*(Math.PI/180))*radius)+_y;

This will calculate the _x and _y components of the entire 360 degree angle for your circle. As you will see, the angle in the script is represented by the loop variable. Next is the hitTest.

if (_root.shape.hitTest(X, Y, true)) {

_root.shape is the movie clip that you would want to preform the hitTest with. Here is the full script:

onClipEvent (load) {
radius = ###
}
onClipEvent (enterFrame) {
for (i=0; i<360; i++) {
X = (Math.cos(i*(Math.PI/180))*radius)+_x;
Y = (Math.sin(i*(Math.PI/180))*radius)+_y;
if (_root.shape.hitTest(X, Y, true)) {
trace("hit")
}
}
}

And there you have it. Short and simple, but hopefuly someone out there will find it at least slightly useful. And if not, then at least i finally made an AS topic of my own. Its getting hard to make them, most topics have been gone through already.

Halo 3 GamerTag: XCornDawgX


None

Vengeance

Reply To Post Reply & Quote

Posted at: 4/16/06 07:03 PM

Vengeance EVIL LEVEL 28

Sign-Up: 03/18/05

Posts: 5,049

short and good.

for (=0; i<360; i++) {

this is the only problem i see, it would cause major lag. i suggest making it like this:
for (=0; i<360; i+=5) {
and then only hitTesting every 5 degree's.

========|| WWWWWWWW>[-[Blog] - [Audio] - [Userpage] - [Flash] - [Last.fm]-]<WWWWWWWW ||========

BBS Signature

None

23450

Reply To Post Reply & Quote

Posted at: 4/16/06 07:04 PM

23450 LIGHT LEVEL 27

Sign-Up: 05/28/03

Posts: 7,297

At 4/16/06 07:03 PM, -Vengeance- wrote: short and good.
for (=0; i<360; i++) {
this is the only problem i see, it would cause major lag. i suggest making it like this:
for (=0; i<360; i+=5) {
and then only hitTesting every 5 degree's.

eh. Whatever floats your boat. thanks for pointing that out though. Yes, 360 is a bit harsh for a loop.

Halo 3 GamerTag: XCornDawgX


None

TrueDarkness

Reply To Post Reply & Quote

Posted at: 4/16/06 07:32 PM

TrueDarkness EVIL LEVEL 27

Sign-Up: 08/31/04

Posts: 4,718

Great tut, pretty simple, and probably shorter than what I would do. I would just use shapeFlag hitTesting to detect the collision. for example

if(_root.land.hitTest(_x+this._width/2, _y+this._height/2, true)){
hit=true
}

That way it would detect the right side of the circle and the bottom, but that is just the way I do it. Your way looks a lot nicer and more professional to be honest, but like -Vengance- said, 360 for a for loop is a lot, it would make it lag a lot =/

Good job!


None

Reed

Reply To Post Reply & Quote

Posted at: 4/16/06 08:36 PM

Reed FAB LEVEL 17

Sign-Up: 03/25/04

Posts: 3,049

Very cool tut! You tought me stuff =D

BBS Signature

None

23450

Reply To Post Reply & Quote

Posted at: 4/16/06 09:28 PM

23450 LIGHT LEVEL 27

Sign-Up: 05/28/03

Posts: 7,297

At 4/16/06 07:32 PM, True_Darkness wrote: if(_root.land.hitTest(_x+this._width/2, _y+this._height/2, true)){
hit=true
}

Yah, that would not really do the same thing. Thanks for liking the tut though, i might make a couple others here soon.

At 4/16/06 08:36 PM, -Reedo11- wrote: Very cool tut! You tought me stuff =D

Well, at least somebody learned something from it all.

Halo 3 GamerTag: XCornDawgX


None

Hoeloe

Reply To Post Reply & Quote

Posted at: 7/24/06 02:56 AM

Hoeloe LIGHT LEVEL 22

Sign-Up: 04/29/04

Posts: 3,976

Thanks so much! This could be INSANELY helpful for a game i'm helping to make....

I never claim to know everything, people just assume I do anyway.
------------------------------
THE LAST WIZARD AND THE DOOMSDAY RINGS NOW IN PRODUCTION!

BBS Signature

None

23450

Reply To Post Reply & Quote

Posted at: 7/24/06 04:02 AM

23450 LIGHT LEVEL 27

Sign-Up: 05/28/03

Posts: 7,297

At 7/24/06 02:56 AM, Hoeloe wrote: Thanks so much! This could be INSANELY helpful for a game i'm helping to make....

im happy it could help. : )

Halo 3 GamerTag: XCornDawgX


None

Snubby

Reply To Post Reply & Quote

Posted at: 7/24/06 04:08 AM

Snubby FAB LEVEL 20

Sign-Up: 12/04/04

Posts: 3,145

for (=0; i<360; i++) {

I'm not as good at actionscript as you, though I do know a lot of it. And to me, you forgot an 'i' here. I'm probably wrong but shouldn't it be this?

for (i=0; i<360; i++) {

if not, explain.


None

23450

Reply To Post Reply & Quote

Posted at: 7/24/06 04:23 AM

23450 LIGHT LEVEL 27

Sign-Up: 05/28/03

Posts: 7,297

At 7/24/06 04:08 AM, Snubby wrote:
for (=0; i<360; i++) {
I'm not as good at actionscript as you, though I do know a lot of it. And to me, you forgot an 'i' here. I'm probably wrong but shouldn't it be this?

for (i=0; i<360; i++) {

if not, explain.

yah, it seems you are right. but that is only in the explaination part, in the full code it is corrected. thanks for pointing that out.

Halo 3 GamerTag: XCornDawgX


None

ShortMonkey

Reply To Post Reply & Quote

Posted at: 10/7/06 02:21 AM

ShortMonkey LIGHT LEVEL 26

Sign-Up: 04/01/06

Posts: 6,606

I must've done it wrong. Can someone explain to me what I did wrong? This was the action script I put in for a totally round plate for the "sho_ball" to hit with:

onClipEvent (load) {
radius = 360
}
onClipEvent (enterFrame) {
for (i=0; i<360; i+=5) {
X = (Math.cos(i+=5(Math.PI/180))*180)+_x;
Y = (Math.sin(i+=5(Math.PI/180))*180)+_y;
if (_root.sho_ball.hitTest(X, Y, true)) {
trace("hit")
}
}
}

Help will be appreciated.


None

Jesus

Reply To Post Reply & Quote

Posted at: 10/7/06 03:03 AM

Jesus EVIL LEVEL 07

Sign-Up: 03/10/05

Posts: 234

At 10/7/06 02:21 AM, ShortMonkey wrote: onClipEvent (load) {
radius = 360
}
onClipEvent (enterFrame) {
for (i=0; i<360; i+=5) {
X = (Math.cos(i+=5(Math.PI/180))*180)+_x;
Y = (Math.sin(i+=5(Math.PI/180))*180)+_y;
if (_root.sho_ball.hitTest(X, Y, true)) {
trace("hit")
}
}
}

Are you sure your radius is 360? And are you sure you put it in the MC which isn't sho_ball?


None

ShortMonkey

Reply To Post Reply & Quote

Posted at: 10/7/06 03:07 AM

ShortMonkey LIGHT LEVEL 26

Sign-Up: 04/01/06

Posts: 6,606

I made the circle using the circle tool and holding onto shift while making it! anyway, I found another AS so all is good!


Shouting

mercedess

Reply To Post Reply & Quote

Posted at: 12/18/07 06:54 PM

mercedess NEUTRAL LEVEL 01

Sign-Up: 11/25/06

Posts: 2

When i colide with the ball at high speed against the line ( my shape) it just ignores the line and continues, but when i do the same at low speed, it works normally. can someone help me please?.
and ...if someone knows any perfect physics AS let me know.


None

Disarray-yarrasiD

Reply To Post Reply & Quote

Posted at: 12/18/07 09:01 PM

Disarray-yarrasiD DARK LEVEL 08

Sign-Up: 11/14/04

Posts: 1,468

A better way to do it might be as follows (this actually may be slower since it uses arrays):

onClipEvent (load) {
var radius:Number = 1;
var colArray = new Array();
var constant:Number = Math.PI/180;
//defining this prefents flash from calculating it 360 time a frame
for (var i = 0; i<360; i++) {
X = (Math.cos(i*constant*radius));
Y = (Math.sin(i*constant*radius));
colArray.push([X, Y]);
//the array stores the values so they don't have to be recalculated, I think this takes less time but I am
//not sure.
}
}
//
onClipEvent (enterFrame) {
for (var i = 0; i<colArray.length; i++) {
if (_root.shape.hitTest(_x+colArray[i][0], y+colArray[i][1], true)) {
trace("hit");
}
}
}

that should work, but I did not test it. Of course using hitTest, which isn't very accurate, there is really no need to test 360 times. Take a look at this example I just through together:

The color of the ball shows its speed.
For some strange reason 36 tests is much faster than 8 tests.

8 tests * 100 balls
36 tests * 100 balls
360 tests * 100 balls

Press space to shoot.

BBS Signature

None

kid-dude

Reply To Post Reply & Quote

Posted at: 7/3/08 10:31 AM

kid-dude DARK LEVEL 06

Sign-Up: 05/12/05

Posts: 508

One thing I did to speed things up was but this before the for loop (say the objects are ball and floor)

if(ball.HitTest(floor)){

So it only runs the foor loop when the ball is in the area covered by the floor mc.

What do you think?

szafranko wrote:
im willing to put much credit for somone who can create a dorito's character to my likeing....
Linkage: Cracked | Geekologie | xkcd | smbc

BBS Signature

None

Coolio-Niato

Reply To Post Reply & Quote

Posted at: 7/3/08 10:37 AM

Coolio-Niato LIGHT LEVEL 24

Sign-Up: 06/30/05

Posts: 1,689

At 10/7/06 02:21 AM, ShortMonkey wrote: I must've done it wrong. Can someone explain to me what I did wrong? This was the action script I put in for a totally round plate for the "sho_ball" to hit with:

onClipEvent (load) {
radius = 360
}
onClipEvent (enterFrame) {
for (i=0; i<360; i+=5) {
X = (Math.cos(i+=5(Math.PI/180))*180)+_x;
Y = (Math.sin(i+=5(Math.PI/180))*180)+_y;
if (_root.sho_ball.hitTest(X, Y, true)) {
trace("hit")
}
}
}

Help will be appreciated.

You silly boy. Only add the i+=5 in the for loop, not in the main code itself! >:)

Pretty good tutorial, very useful if you later want to calculate the angle at which the ball has to jump off at after a collision.

Noice job =) Now to make it work for irregular shapes (triangles, pentagons and watnot)

=)

BBS Signature

None

kid-dude

Reply To Post Reply & Quote

Posted at: 7/3/08 11:44 AM

kid-dude DARK LEVEL 06

Sign-Up: 05/12/05

Posts: 508

I've been throwing some numbers into the function and seeing how it would effect the _x and _y values and I am obviously confusing myself.

My mc has its register crosshair thingy in its centre, so its _x and _y values are for its centre. That means that if you are looping values for the circumference of the ball you would have to add and take away values of x and y.

So I chuck i = 0 in and get _x + r and _y + 0 which is great, showing that for the first iteration its just checking the point on the circle furthest most to the right, the line connecting them just goes straight right. Perfect.
So I chuck in i = 180 expecting to get _x - r and _y + 0 (as this would be the opposite of above) but I dont. Instead I get _x + r and _y + 0.5r.

Is this just error in my logic or is the register for my mc in the wrong place? All help appreciated.

szafranko wrote:
im willing to put much credit for somone who can create a dorito's character to my likeing....
Linkage: Cracked | Geekologie | xkcd | smbc

BBS Signature

None

kid-dude

Reply To Post Reply & Quote

Posted at: 7/3/08 11:54 AM

kid-dude DARK LEVEL 06

Sign-Up: 05/12/05

Posts: 508

correction, when i put 1 = 180 in i got _y + 0.05 (so im guess thats just a rounding error and should be 0)

Sodding decimal places :P

szafranko wrote:
im willing to put much credit for somone who can create a dorito's character to my likeing....
Linkage: Cracked | Geekologie | xkcd | smbc

BBS Signature

None

West-End-Pro

Reply To Post Reply & Quote

Posted at: 7/3/08 02:24 PM

West-End-Pro NEUTRAL LEVEL 23

Sign-Up: 02/15/06

Posts: 2,359

Instead of using a for loop, use a while loop. It runs far faster in AS2.


Sad

dogdgey5

Reply To Post Reply & Quote

Posted at: 7/31/08 06:27 PM

dogdgey5 EVIL LEVEL 07

Sign-Up: 03/08/08

Posts: 91

hey here is what i've got and i was woundering if any one could now tell me how to let my char. move away from the object :<

onClipEvent (enterFrame) {
for (i=0; i<360; i++) {
X = (Math.cos(i*(Math.PI/180))*radius)+_x;
Y = (Math.sin(i*(Math.PI/180))*radius)+_y;
if (_root.bush.hitTest(X, Y, true)) {
trace("hit");
(hitTest) = true;
speed = 0;
}


All times are Eastern Standard Time (GMT -5) | Current Time: 01:26 PM

<< Back

This topic is 1 page long.

<< < > >>
You need a Grounds Gold Account to post on the NG BBS! If you don't have one, click here to sign up now! It's fast, free, and easy — and opens up tons of great NG features!