 00:00
00:00 AS: Art-based normal detection

4,159 Views | 20 Replies

AS: Art-based normal detection 2006-06-15 16:13:19

http://denvish.net/u..1150395360_angle.php

It works great so long as the sphere is not completely surrounded by land. Which you shouldnt have happen in a game anyway.

NOTE: For purposes of a demonstration, the edge is divided into 360 segments. This would not be practical for a use in a game as that is a heavy loop for flash, so in a game it would be more practical to set it to a much lower number.

So the code. Don't be alarmed at the immense complexity and mathematical difficulty of the script.

r = _width/2;
seg = 360;
}
onClipEvent (enterFrame) {
_x = _root._xmouse;
_y = _root._ymouse;
var nmbr = 0;
xval = 0;
yval = 0;
for (i=1; i<seg; i++) {
var tx = _x+r*Math.sin(i*(360/seg)*(Math.PI/180));
var ty = _y-r*Math.cos(i*(360/seg)*(Math.PI/180));
if (_root.land.hitTest(tx, ty, true)) {
nmbr++;
xval += tx;
yval += ty;
}
}
if (nmbr>0) {
_root.arr._x = xval/nmbr;
_root.arr._y = yval/nmbr;
_root.arr._rotation = Math.atan2(_x-xval/nmbr, _y-yval/nmbr)/(Math.PI/180)*-1+90;
_root.arr._visible = true;
} else {
_root.arr._visible = false;
}
}

Ok so I lied about the complexity of it. So what exactly does it do? It seems simple but is very powerful. Let's look at it line by line.

r = _width/2;
seg = 360;
}

r is the radius of the circle. Seg is the amount of points on the circle we are going to check. I did 360 for demonstration purposes.

onClipEvent (enterFrame) {
_x = _root._xmouse;
_y = _root._ymouse;
var nmbr = 0;
xval = 0;
yval = 0;

this drags the circle, and initiates some key temporary variables. nmbr is the amount of points colliding with the wall. xval and yval will be used later to find the average of the points hitting the wall, the center so to say.

for (i=1; i<seg; i++) {
var tx = _x+r*Math.sin(i*(360/seg)*(Math.PI/180));
var ty = _y-r*Math.cos(i*(360/seg)*(Math.PI/180));
if (_root.land.hitTest(tx, ty, true)) {
nmbr++;
xval += tx;
yval += ty;
}
}

this for loop chacks the points on the circle against the wall. tx and ty are temporary variables used to represent the x and y of points on the circumference of the circle. It uses a little trig to find the values, there's another AS tutorial on that... look it up. Then it does a shapeflag collision detection between the edge point and the ground. If it's hitting, it increases the NMBR variable, and adds the x and y of the edge point to the xval and yval variables

if (nmbr>0) {
_root.arr._x = xval/nmbr;
_root.arr._y = yval/nmbr;
_root.arr._rotation = Math.atan2(_x-xval/nmbr, _y-yval/nmbr)/(Math.PI/180)*-1+90;
_root.arr._visible = true;
} else {
_root.arr._visible = false;
}

and the last part of the code. Rather simple. _root.arr is the MC used to show the normal of the wall where the ball is hitting. It places it's _x and _y at the average of the points that are colliding with the wall, and then finds the direction using arctangents from that point to the center of the ball. It's rather simple. Finding the average of the points colliding with the wall will find a point that is basicall in the center of these points.

So now what can you do with this normal? Well, for starters it would be a useful tool for bouncing objects on an art based map. You can also use it to rotate a character so he's aligned with the slope of the ground. It could help in making a pinball game, and many other circumstances.

NOTE: When i originally was thinking up how to do this, i thought of taking the midpoint of the line made by connecting the points where the sphere enters and exits hitting the ground, where it collides with the edges of the ground. But, it would still have to loop through all the points, so this method is better.

Oh ya, and
AS: Main Response to AS: Art-based normal detection 2006-06-15 16:23:04

pretty much the same way i have mine, only ofcourse not 360 points

"Don't be alarmed at the immense complexity and mathematical difficulty of the script."

your sarcasm always seems to amaze me :D

the only thing i would tend to do differently is when working with a large circle like this, to test smaller circles aswell incase of a thin piece of land, to better estimate the normal in all occasions Response to AS: Art-based normal detection 2006-06-15 16:31:40

Very nice tutorial Glaiel. Easy to understand. Only the best from you!

:)

Response to AS: Art-based normal detection 2006-06-15 16:34:28

Nice tutty, but why would you need to know the normal? Can you give an example of where you would use the normal in a 2D game?

Sup, bitches :) Response to AS: Art-based normal detection 2006-06-15 16:37:28

At 6/15/06 04:34 PM, liaaaam wrote: Nice tutty, but why would you need to know the normal? Can you give an example of where you would use the normal in a 2D game?

i did

wall bouncing, pinball, rotating the character to the ground, etc. Response to AS: Art-based normal detection 2006-06-15 16:42:08

Nice lol, Khao had circle to line hittesting which kinda did the same. even thought your code is more simple.

*User Page under construction* Response to AS: Art-based normal detection 2006-06-15 16:43:01

kickass

I still dont see me using this sort of stoff on a game for quite a while.

Response to AS: Art-based normal detection 2006-06-15 17:08:57

At 6/15/06 04:43 PM, Darkfire_Blaze wrote: kickass

I still dont see me using this sort of stoff on a game for quite a while.

Its really usefull when it comes to platformers lol. This can be used to get the rotation of a character.

*User Page under construction* Response to AS: Art-based normal detection 2006-06-15 17:14:35

Good for accurately calculating the vector a character would realisticically take when jumping off of a slope too...like in fancy pants...excellent tutorial.

Response to AS: Art-based normal detection 2006-06-15 17:18:59

At 6/15/06 05:14 PM, bomtoons wrote: (was this practice for your sonic game?)

no.. that boss had no slopes anyway.

I was going to use it for a pinball game but then i realized all the possibilities... like reflections and all that good stuff. Response to AS: Art-based normal detection 2006-06-15 18:19:19

man, i was so close to making this engine one time. I had everything working except i could not get the arrow to be direcly in the middle, it was always at the edge of the ball. Oh wells.

Response to AS: Art-based normal detection 2006-06-15 18:35:50

http://denvish.net/u..1150404838_angle.php

I made a slight modification to the engine

r = _width/2;
seg = 360;
cvt = Math.PI/180;
xspeed = 0;
yspeed = 0;
_root.arr._visible = false;
}
onClipEvent (enterFrame) {
_x += xspeed;
_y += yspeed;
yspeed += 1;
var nmbr = 0;
xval = 0;
yval = 0;
for (i=1; i<seg; i++) {
var tx = _x+r*Math.sin(i*(360/seg)*(cvt));
var ty = _y-r*Math.cos(i*(360/seg)*(cvt));
if (_root.land.hitTest(tx, ty, true)) {
nmbr++;
xval += tx;
yval += ty;
}
}
if (nmbr>0) {
_root.arr._rotation = Math.atan2(_x-xval/nmbr, _y-yval/nmbr)/(cvt)*-1+90;
_root.arr._x = _x-r*Math.sin((_root.arr._rotation+90)*cvt
);
_root.arr._y = _y+r*Math.cos((_root.arr._rotation+90)*cvt
);
px = _x-r*Math.sin((_root.arr._rotation+90)*cvt
);
py = _y+r*Math.cos((_root.arr._rotation+90)*cvt
);
}
if (nmbr>0 && nmbr<seg) {
ix = ((px-_x)/r)*-1;
iy = ((py-_y)/r)*-1;
speed = Math.sqrt(xspeed*xspeed+yspeed*yspeed)*.9;
//speed<=1?speed=0:0
var spa = Math.atan2(xspeed, yspeed)/(cvt)*-1+90;
var nr = 2*(_root.arr._rotation-spa)+spa-180;
_root.arr._rotation = nr-180;
xspeed = Math.sin((nr+90)*cvt)*speed;
yspeed = -Math.cos((nr+90)*cvt)*speed;
while (_root.land.hitTest(px, py, true)) {
_x += ix;
_y += iy;
px = _x-ix*r;
py = _y-iy*r;
}
}
//Math.abs(xspeed)<.5?xspeed=0:0
//Math.abs(yspeed)<.5?yspeed=0:0
_root._x = 275-_x;
_root._y = 200-_y;
}

//commented code meanns i took it out cause it didnt work right but was going to find out how to make it work later. Response to AS: Art-based normal detection 2006-06-15 18:55:58

in case anyone is interested, here is a nicely encapsulated prototyped function i have written and use, to the same effect as this (slight differences)

mine does like i said earlier, sub circles within the larger circle to get an accurate normal on thin terrain like you can see in demo on top right, and in this, does a total of 160 hittests

_global.pi2 = Math.PI*2;
var inc:Number = pi2/32;

MovieClip.prototype.findNormal = function(targ:MovieClip):Array
{
var nx:Number = 0;
var ny:Number = 0;
var nn:Number = 0;
for(var r:Number = 1; r<10; r+=2)
{
for(var ang:Number = 0; ang<pi2; ang+=inc)
{
var tx:Number = r*Math.sin(ang);
var ty:Number = r*Math.cos(ang);
if(targ.hitTest(this._x+tx,this._y+ty,true
))
{
nx += tx/r;
ny += ty/r;
++nn;
}
}
}
if(nn==0) ny = 1;
else
{
var d:Number = 1/Math.sqrt(nx*nx+ny*ny);
nx *= d;
ny *= d;
}
return new Array(nx,ny);
}

http://denvish.net/u..0406115_testnorm.php

but ofcourse, like anything, numbers can be reduced to give faster, but less accurate approximations Response to AS: Art-based normal detection 2006-06-15 19:01:54

ah yeh, my function returns a normalised normal vector, so in my sample, i draw the blue line by

var n:Array = mc.findNormal(land);
mc.clear();
mc.lineStyle(1,0xffff,100);
mc.lineTo(20*n,20*n); Response to AS: Art-based normal detection 2006-06-15 19:13:35

At 6/15/06 04:34 PM, liaaaam wrote: Nice tutty, but why would you need to know the normal? Can you give an example of where you would use the normal in a 2D game?

I used it to help with bullet ricochets in this old engine of mine:
http://www.negativeflash.com/prey6b.html
(Still uploading at time of post, so it might be a broken link for a couple of minutes yet) Response to AS: Art-based normal detection 2006-06-15 19:16:22

At 6/15/06 07:13 PM, NegativeONE wrote: (Still uploading at time of post, so it might be a broken link for a couple of minutes yet)

...
Hrm, nevermind, I guess. Damn hosting woes.
Anyway, I used a different method to go about finding the normal, but both seem to work well. Response to AS: Art-based normal detection 2006-06-15 19:57:52

damn.i wish i could code like that.
nice one.

Response to AS: Art-based normal detection 2006-06-25 02:37:44

hey that looks nice :D i was gonna make a engine like this sooner or latter :P

Response to AS: Art-based normal detection 2006-06-25 06:26:09

At 6/15/06 04:23 PM, -dELta- wrote: "Don't be alarmed at the immense complexity and mathematical difficulty of the script."

your sarcasm always seems to amaze me :D

Lol @ shvitzer fight. Response to AS: Art-based normal detection 2006-06-25 06:35:39

At 6/25/06 06:26 AM, -Toast- wrote:
At 6/15/06 04:23 PM, -dELta- wrote: "Don't be alarmed at the immense complexity and mathematical difficulty of the script."

your sarcasm always seems to amaze me :D
Lol @ shvitzer fight.

shvitzer? 