 You are using an insecure version of your web browser. Please update your browser! Using an outdated browser makes your computer unsafe. For a safer, faster, more enjoyable user experience, please update your browser today or try a newer browser.

# Physics!

Geschrieben von am 7. March 2012

UPDATE: Improved (and actually working) version can be found in this new blog post. So the next step since I fixed up the collision polygons last time was integrating physics into the game. Even though the game will not really be physics-based, it's a nice thing to have if only for the collision detection. After I had a little look around I decided to use JBox2D which is a Java port of the Box2D Physics library written in C. I also ha a look at fizzy which is supposed to be a nice wrapper around JBox2D, but unfortunately it hasn't been updated in a while and is simply broken.

The first problem that I stumbled onto was that Box2D is quite picky about polygons. It can only handle convex polygons - so I had to find a way to split my polygons up into nice convex parts. After looking around for a while I came back to Slick2D and its triangulation functionalities. With that you can split up a polygon into triangles (which luckily are always convex). Still that produces a lot of triangles and leaves some room from optimization. First off the polygons needed to be simplified, since they contained unnecessary vertices (which results in a lot of triangles). So here is some code for that:
public static Polygon simplify(Polygon poly)
{
Polygon simple = new Polygon();

int max = poly.getPointCount() - 1;

for (int i = 0; i < poly.getPointCount(); i++) { // Grab the points next to the current one float[] last = (i == 0) ? poly.getPoint(max) : poly.getPoint(i - 1); float[] point = poly.getPoint(i); float[] next = (i == max) ? poly.getPoint(0) : poly.getPoint(i + 1); // Calculate the gradient the two edges at the current point float gradient1 = (last - point) / (last - point); float gradient2 = (point - next) / (point - next); // Only add points which is at an angle if (gradient1 != gradient2) { simple.addPoint(point, point); } } return simple; }[/pygmentize] And now after triangulating the polygon I wanted to optimize the results, so add triangles back together if possible. For that I adapted some code I found on this website. There are some functions used in this snippet which I will not explain as their use should be obvious (if you're still interested, have a look at the source code):
private static Collection polygonizeTriangles(ArrayList triangles)
{
Collection polys = new ArrayList();

// Still some triangles left?
while (triangles.size() > 0)
{
// Grab the triangle and turn it into a polygon
Polygon poly = triangles.remove(0).asPolygon();

// Now check the remaining polygons
for (int j = 1; j < triangles.size();) { // Try and add the triangle to the polygon Polygon new_poly = ShapeUtil.addTriangle(poly, triangles.get(j)); // If the triangle was added and the result is still convex, keep that result if (new_poly != null && ShapeUtil.isConvex(new_poly)) { poly = new_poly; // The other triangle is also handled now triangles.remove(j); } else { j++; } } polys.add(poly); } return polys; }[/pygmentize] With those new fancy polygons I then hooked up the game entities with physical bodies as well. The result can be seen in the picture at the beginning of the article. To render all the debug stuff for the physics system I used this awesome class which I just changed a bit to use the view port of the game (I will probably optimize this to use a built-in Box2D view port). Now I can finally start to get some actual gameplay starting...