So I’ve been working on a little game and in beginning I was simply using Slick and regular rectangles for collision detection. This worked fine for a while. Even with rotated shapes still generally worked. But then I had a bad guy that was 2x as long as he was wide. I tried to couple 2 rectangles to him but it was having issues. Then I ran into a problem with my “laser beam” which I was trying to use a super long rectangle(100 long x 1 wide)
Anyways, I realized I needed to learn how to better do collision detection. I kept seeing separating axis theorem and AABB(Axis Aligned Bounding Boxes) stuff. Most of the time it was either in other language code or abstract math.
I was frustrated. :’(
I was always running into problems with built in polygons and other issues. Specifically when it came to rotating and whatnot.
I decided to build a custom detection system from the ground up, that works for me.
It may work for you. Its more complicated then a simple rectangular or distance check. ;D
This is not yet optimized, but I tried to simplify it as much as I can for right now.
FYI, this currently supports ANY Convex Polygons.
You can manually set it to any polygon you want, I just have it set to auto random polygons.
Separating Axis Theorem Collision Detection
Basic Collision Check Version 1.1
Example of it in action: http://code.newrog.com/examples/collide_v1_1.html
Source Code: http://code.newrog.com/examples/collide_v1_1.rar
(skeleton.class is just a modified java 4k template)(I abstracted it away to not interfere with trying to read what all I did)
You may do whatever you want with it. Some code is mine, some are abstract ideas pulled from a dozen different sites.
http://code.newrog.com/examples/TouchnoTouch.png
I start with with 2 sets of Bodies. :persecutioncomplex: :point:
You can create multiple polygons per body if you would like for more complicated shapes.
It generates a random number of points and random angle then generates a polygon.
During update, we check if A collides with B. (or vice versa)
If they do, we notify both of them
First thing we do test separation of axises
http://code.newrog.com/examples/sat.png
From Wikipedia
Extract Example from inside 1 polygon:
public boolean collide(Poly other){
// test separation axes of current polygon
for(int j = count-1, i = 0; i < count; j = i, i++)
{
Vector v0 = vertices[j];
Vector v1 = vertices[i];
Vector edge = new Vector(0,0);
edge.x = v1.x - v0.x; // edge
edge.y = v1.y - v0.y; // edge
Vector axis = edge.perp(); // Separate axis is perpendicular to the edge
if(separatedByAxis(axis, other))
return false;
}
// test separation axes of other polygon
for(int j = other.count-1, i = 0; i < other.count; j = i, i++)
{
Vector v0 = other.vertices[j];
Vector v1 = other.vertices[i];
Vector edge2 = new Vector(0,0);
edge2.x = v1.x - v0.x; // edge
edge2.y = v1.y - v0.y; // edge
Vector axis = edge2.perp(); // Separate axis is perpendicular to the edge
if(separatedByAxis(axis, other))
return false;
}
return true;
}
public void calculateInterval(Vector axis) {
this.min = this.max = (float) vertices[0].dot(axis);
for (int i = 1; i < count; i++) {
float d = (float) vertices[i].dot(axis);
if (d < this.min)
this.min = d;
else if (d > this.max)
this.max = d;
}
}
public boolean intervalsSeparated(float mina, float maxa, float minb, float maxb) {
return (mina > maxb) || (minb > maxa);
}
public boolean separatedByAxis(Vector axis, Poly poly) {
calculateInterval(axis);
mina = min;
maxa = max;
poly.calculateInterval(axis);
minb = poly.min;
maxb = poly.max;
return intervalsSeparated(mina, maxa, minb, maxb);
}
You first need to find the perpendicular to each edge. and then simply do a check against distance
If the distance between them overlaps, we have collision!
For interactive version of how all this works. Please visit http://www.metanetsoftware.com/technique/tutorialA.html
I plan to add more features/functions in other future versions/posts. If you see anything that could be simplified or optimized. Let me know. Typically i want it to keep it as simple/short as possible so others can modify it to work with their code.
Future version’s features:
Will add to this post as I add them.
p.s. I am an “Appreciation whore”
SAT Version 2.1: Displacement
Example:http://code.newrog.com/examples/collide_v2_1.html
Source Code: http://code.newrog.com/examples/deflection_collide_v2.rar
Left click to toggle between the 2 bodies. 1 can push the other, whereas 1 resists movements.
You either are pushing or resisting toggle modes to demonstrate 2 separate principles.
As you can see in the picture, the blue shape will show the minimal deflected position. Its not perfect but its a fairly good behavior.