Today we will finally be detecting a collision with SAT. We know how SAT works, we’ve built classes to work with SAT, now we can use all of this to detect a real, live collision!

Using the classes we created last time, this is quite simple. First create a shape:

var shape1:Polygon = Polygon.rectangle(530, 30, new Vector2D(270, 360));

It’s a simple polygon created using the static function of the rectangle class. Now we need another shape to collide with:

var shape2:Polygon = Polygon.rectangle(20, 50, new Vector2D(260, 350));

And now we need to test for a collision:

var data:CollisionData = Collision.testShapes(shape1, shape2);

When you run this, you should get a result with a separation of -30px, a separation vector of Vector2D x:0, y:-30 and a unit vector of Vector2D x:0, y:1. This tells us that there is in fact a collision, and the two shapes overlap on 30 pixels. The easiest way to separate them is by moving a shape 30 pixels or both shape 15 pixels.

But how do we know which shape to move in which direction? The way this function returns data is so that when the values in the separation vector are added to shape2′s x and y, the shapes will not be colliding anymore.

shape2.x += data.separation.x;
shape2.y += data.separation.y;

However, if you want to move shape one, you need to subtract the values.

shape1.x -= data.separation.x;
shape1.y -= data.separation.y;

This is just how the collis

ion function works. If you want to move both shapes equally apart, then you can do this:

shape1.x -= data.separation.x/2;
shape1.y -= data.separation.y/2;
shape2.x += data.separation.x/2;
shape2.y += data.separation.y/2;

This will move each shape half the distance away from the collision.

While this may be cool, it’s not very useful. There’s no motion, and there’s nothing to look at. We’ll create a simple demo with motion and visuals now!


package {
import flash.display.Sprite;
import flash.events.Event;
import com.rocketmandevelopment.collisions.sat.Collision;
import com.rocketmandevelopment.collisions.sat.CollisionData;
import com.rocketmandevelopment.collisions.shapes.Polygon;
import com.rocketmandevelopment.math.Vector2D;

[SWF(width=550, height=400, frameRate=30)]
public class SatTest extends Sprite {
private var shape1:Polygon;
private var shape2:Polygon;

public function SatTest() {
graphics.lineStyle(0);

shape1 = Polygon.rectangle(530, 30, new Vector2D(270, 360));
shape1.draw(graphics);

shape2 = Polygon.rectangle(20, 50, new Vector2D(250, 50));
shape2.draw(graphics);

addEventListener(Event.ENTER_FRAME, update);
}

private function update(e:Event):void {
graphics.clear();
graphics.lineStyle(0);

shape2.y += 3;//moving shape2

var data:CollisionData = Collision.testShapes(shape1, shape2);
if(data) {
shape2.x += data.separation.x;
shape2.y += data.separation.y;
}

shape1.draw(graphics);
shape2.draw(graphics);
}
}
}

This simple class creates two shapes, draws them using the draw function in the BaseShape class, and tests for collisions. If it finds a collision, it moves shape two out of the collision. This is a simple example where shape1 is the unmovable ground and shape2 is possibly a moving player. The resulting SWF looks something like this. This may not seem like it’s all that great, but try rotating the ground rectangle, see how the “player” slides down the slope?

The collision response isn’t all that great in this example, but that’s a topic for another post. Hopefully now you can see how this demo was created, and I bet you could even create something very similar on your own!