PDA

View Full Version : Built-in hitTest() vs this one...



wkt
July 16th, 2009, 06:59 AM
Hi there

On my way to learn how to do the SAT way (separating axis theorem way), I created a function like this:



function cDetect (ob1:MovieClip,ob2:MovieClip) {
var xOverlap:Boolean
var yOverlap:Boolean
var b1:Object = ob1.getBounds(_root)
var b2:Object = ob2.getBounds(_root)
if (b1.xMin > b2.xMax or b1.xMax < b2.xMin) {
xOverlap = false
} else {
xOverlap = true
}
if (b1.yMin > b2.yMax or b1.yMax < b2.yMin) {
yOverlap = false
} else {
yOverlap = true
}
if (xOverlap and yOverlap) {
_root.cPhrase._visible = true//There is collision between the 2 objects
} else {
_root.cPhrase._visible = false//There is no collision between the 2 objects
}
_root.xoText.text = xOverlap
_root.yoText.text = yOverlap
}


Will this thing be any better than the Flash built-in MovieClip.hitTest(x,y,shapeFlag)?

They do the same. My function cDetect() does bounding box hitTest.

Thanks in advance.

Gnoll
July 16th, 2009, 07:08 AM
I think the inbuilt hitTest probably does the same thing,
Gnoll

SparK_BR
July 16th, 2009, 10:03 AM
hehehe

transformed it into a "native" function for every movieclip

note: AS3 version wasn't tested


//AS3
MovieClip.prototype.overlaps = function(obj:MovieClip):Boolean{
var xOverlap:Boolean = false;
var yOverlap:Boolean = false;
var b1:Object = this.getBounds(DisplayObjectContainer);
var b2:Object = obj.getBounds(DisplayObjectContainer);
if (b1.xMin < b2.xMax && b1.xMax > b2.xMin)
xOverlap = true;
if (b1.yMin < b2.yMax && b1.yMax > b2.yMin)
yOverlap = true;

if (xOverlap && yOverlap)
return true;

return false;
}
note: AS2 version wasn't compared with built-in hitTest


//AS2
MovieClip.prototype.overlaps = function(obj:MovieClip):Boolean{
var xOverlap:Boolean = false;
var yOverlap:Boolean = false;
var b1:Object = this.getBounds(_root);
var b2:Object = obj.getBounds(_root);
if (b1.xMin < b2.xMax and b1.xMax > b2.xMin)
xOverlap = true;
if (b1.yMin < b2.yMax and b1.yMax > b2.yMin)
yOverlap = true;

if (xOverlap and yOverlap)
return true;

return false;
}
usage:


if(this.overlaps(<target object>)){
trace("they're touching!");
}

dandylion13
July 16th, 2009, 01:53 PM
The built-in hitTestObject doesn't tell you by how much the object's are overlapping, which you need to know if you want to seperate them accurately.

Sirisian
July 16th, 2009, 08:25 PM
Your code wasn't optimal. Unless you needed the overlap booleans for something.
Short-Circuit Evaluation (http://en.wikipedia.org/wiki/Short-circuit_evaluation)


function cDetect (ob1:MovieClip,ob2:MovieClip):void
{
var b1:Object = ob1.getBounds(_root);
var b2:Object = ob2.getBounds(_root);
if (b1.xMin < b2.xMax && b1.xMax > b2.xMin && b1.yMin < b2.yMax && b1.yMax > b2.yMin)
{
//There is collision between the 2 objects
_root.cPhrase._visible = true;
}
else
{
//There is no collision between the 2 objects
_root.cPhrase._visible = false;
}
}

TOdorus
July 16th, 2009, 09:15 PM
The built-in hitTestObject doesn't tell you by how much the object's are overlapping, which you need to know if you want to seperate them accurately.



private function overlap(A1:Number, A2:Number, B1:Number, B2:Number):Number {
var Alow:Number
var Ahigh:Number
var Blow:Number
var Bhigh:Number
var points:Array = [A1, A2, B1, B2]

if (A1 < A2) {
Alow = A1
Ahigh = A2
} else {
Alow = A2
Ahigh = A1
}
if (B1 < B2) {
Blow = B1
Bhigh = B2
} else {
Blow = B2
Bhigh = B1
}
points.sort(Array.NUMERIC)
var dist:Number = points[3] - points[0]
var added:Number = (Ahigh - Alow) + (Bhigh - Blow)
var OVERLAP:Number = (added - dist)*.5 //if there is no overlap overlap < 0
//

return(OVERLAP)
}


EDIT: sorry it's a bit late and I decided to do one last read of my favorite forums, so I just copy pasted it from some project.

SparK_BR
July 17th, 2009, 12:56 AM
private function overlap(A1:Number, A2:Number, B1:Number, B2:Number):Number {
....
}
EDIT: sorry it's a bit late and I decided to do one last read of my favorite forums, so I just copy pasted it from some project.

a1 and a2 object A and b1 and b2 are object B?
then you call it twice, for x and for y, and it will give you >0 if they touch?

but how do i know how much of the object is inside another?

when i say A is in 1 to 4 in X axis and B is in 2 to 5 in X axis it returns 1
but i really think it should return 3, since points 2 to 4 are colliding!
i hope you understood

edit: just changed the last line to
var OVERLAP:Number = (added - dist)+1;

now it gives me the negative distance betwen the objects
and if they overlap it will return how much

TOdorus
July 17th, 2009, 06:18 AM
a1 and a2 object A and b1 and b2 are object B?
then you call it twice, for x and for y, and it will give you >0 if they touch?

but how do i know how much of the object is inside another?

when i say A is in 1 to 4 in X axis and B is in 2 to 5 in X axis it returns 1
but i really think it should return 3, since points 2 to 4 are colliding!
i hope you understood

edit: just changed the last line to
var OVERLAP:Number = (added - dist)+1;

now it gives me the negative distance betwen the objects
and if they overlap it will return how much

If overlap = 0 then they are touching exactly and can't be seperated on that axis so >=0 means overlap ( as <0 means no overlap). The function was supposed to return the distance each object needs to move (now it's just dived by two) to move out of each other. If you change the last line it should work fine and give you the exact overlap on that axis.


var OVERLAP:Number = (added - dist);


4-2 = 2, so the distance is 2 and not 3. If something doesn't overlap, the negative number will indicate at what distance the object is on that axis (as a positive number is overlap, a negative number is clearance).