Be a Supporter!

As: Circle To Shape Hittest

  • 6,923 Views
  • 19 Replies
New Topic Respond to this Topic
23450
23450
  • Member since: May. 28, 2003
  • Offline.
Forum Stats
Supporter
Level 27
Blank Slate
As: Circle To Shape Hittest 2006-04-16 19:00:34 Reply

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.


BBS Signature
Vengeance
Vengeance
  • Member since: Mar. 18, 2005
  • Offline.
Forum Stats
Member
Level 28
Blank Slate
Response to As: Circle To Shape Hittest 2006-04-16 19:03:11 Reply

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
23450
23450
  • Member since: May. 28, 2003
  • Offline.
Forum Stats
Supporter
Level 27
Blank Slate
Response to As: Circle To Shape Hittest 2006-04-16 19:04:14 Reply

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.


BBS Signature
TrueDarkness
TrueDarkness
  • Member since: Aug. 31, 2004
  • Offline.
Forum Stats
Member
Level 27
Blank Slate
Response to As: Circle To Shape Hittest 2006-04-16 19:32:13 Reply

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!

23450
23450
  • Member since: May. 28, 2003
  • Offline.
Forum Stats
Supporter
Level 27
Blank Slate
Response to As: Circle To Shape Hittest 2006-04-16 21:28:50 Reply

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.


BBS Signature
Hoeloe
Hoeloe
  • Member since: Apr. 29, 2004
  • Offline.
Forum Stats
Member
Level 37
Game Developer
Response to As: Circle To Shape Hittest 2006-07-24 02:56:52 Reply

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


Song of the Firefly is on Steam Greenlight and Kickstarter. Give them a look and support the project!
------------------------------

BBS Signature
23450
23450
  • Member since: May. 28, 2003
  • Offline.
Forum Stats
Supporter
Level 27
Blank Slate
Response to As: Circle To Shape Hittest 2006-07-24 04:02:11 Reply

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. : )


BBS Signature
Snubby
Snubby
  • Member since: Dec. 4, 2004
  • Offline.
Forum Stats
Member
Level 21
Game Developer
Response to As: Circle To Shape Hittest 2006-07-24 04:08:52 Reply

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.

23450
23450
  • Member since: May. 28, 2003
  • Offline.
Forum Stats
Supporter
Level 27
Blank Slate
Response to As: Circle To Shape Hittest 2006-07-24 04:23:51 Reply

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.


BBS Signature
ShortMonkey
ShortMonkey
  • Member since: Apr. 1, 2006
  • Offline.
Forum Stats
Member
Level 32
Blank Slate
Response to As: Circle To Shape Hittest 2006-10-07 02:21:53 Reply

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.


BBS Signature
Jesus
Jesus
  • Member since: Mar. 10, 2005
  • Offline.
Forum Stats
Member
Level 07
Blank Slate
Response to As: Circle To Shape Hittest 2006-10-07 03:03:39 Reply

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?

ShortMonkey
ShortMonkey
  • Member since: Apr. 1, 2006
  • Offline.
Forum Stats
Member
Level 32
Blank Slate
Response to As: Circle To Shape Hittest 2006-10-07 03:07:58 Reply

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


BBS Signature
mercedess
mercedess
  • Member since: Nov. 25, 2006
  • Offline.
Forum Stats
Member
Level 01
Blank Slate
Response to As: Circle To Shape Hittest 2007-12-18 18:54:39 Reply

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.

Disarray-yarrasiD
Disarray-yarrasiD
  • Member since: Nov. 14, 2004
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Response to As: Circle To Shape Hittest 2007-12-18 21:01:24 Reply

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
kid-dude
kid-dude
  • Member since: May. 12, 2005
  • Offline.
Forum Stats
Member
Level 06
Blank Slate
Response to As: Circle To Shape Hittest 2008-07-03 10:31:04 Reply

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

Coolio-Niato
Coolio-Niato
  • Member since: Jun. 30, 2005
  • Offline.
Forum Stats
Member
Level 28
Blank Slate
Response to As: Circle To Shape Hittest 2008-07-03 10:37:07 Reply

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)

kid-dude
kid-dude
  • Member since: May. 12, 2005
  • Offline.
Forum Stats
Member
Level 06
Blank Slate
Response to As: Circle To Shape Hittest 2008-07-03 11:44:23 Reply

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

kid-dude
kid-dude
  • Member since: May. 12, 2005
  • Offline.
Forum Stats
Member
Level 06
Blank Slate
Response to As: Circle To Shape Hittest 2008-07-03 11:54:40 Reply

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

West-End-Pro
West-End-Pro
  • Member since: Feb. 15, 2006
  • Offline.
Forum Stats
Member
Level 24
Blank Slate
Response to As: Circle To Shape Hittest 2008-07-03 14:24:36 Reply

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

dogdgey5
dogdgey5
  • Member since: Mar. 8, 2008
  • Offline.
Forum Stats
Member
Level 07
Blank Slate
Response to As: Circle To Shape Hittest 2008-07-31 18:27:43 Reply

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;
}