July 12, 2014

Working Out Collisions

I have decided to cut out SpriteKit for collisions and use it only for rendering. In place of SK Physics, I will reimplement the physics and collision system from the Objective-C engine. I am taking this opportunity to refine my algorithm and make some necessary optimizations.

The problem with the SpriteKit physics is that it doesn’t take advantage of tile maps. To make tile maps collide, some complex polygons will have to be generated, or at least a number of static colliders. Although this is possible, performance did not look good when I tried it out.

It seems to me that it would be better to create a custom physics engine that includes only what is needed for the kinds of games I expect to be built on this engine. By doing this, I can make tile collisions work quickly and impose limitations (like only allowing axis-aligned rectangle colliders) to speed up entity-to-entity collisions. Incidentally, other developers have come to similar conclusions.

Besides, the modularity of the ECS engine lends itself to using different kinds of physics engines for different games. If greater flexibility is needed (such as constraints for physics-based games like Cut the Rope), it is not difficult to swap out the custom physics for SpriteKit’s physics.

Here’s the algorithm I’ve come up with for my custom physics system:

  • Move all entities.
  • For each dynamic entity…
    • Detect and resolve collisions with other dynamic entities on the x-axis.
    • Detect collisions caused by resolution. Resolve by treating new colliding objects as static objects.
    • Repeat on the y-axis.
  • For each dynamic entity…
    • Detect and resolve collisions with static entities on the x-axis.
    • Detect collisions caused by resolution. Resolve using collision chaining.
    • Repeat on the y-axis.

I’ve gotten rid of dynamic collision chaining, because it was expensive and didn’t add a lot to the engine. It is unlikely for a game to need one entity to push more than one other entity at a time. Instead of chaining those collisions, it treats them as static and stops movement in that direction completely. What I might eventually do is reintroduce dynamic collision chaining, but have it as an optional setting that can be disabled to improve performance when it isn’t needed.

I haven’t implemented this algorithm in Swift yet; I’ve been working out the kinks by testing it in Javascript. Here’s a demo of what I have so far; you can also take a look at the source code. It seems pretty solid, but every time I think I’ve worked it out, I find another issue.

Once I feel confident with my algorithm and the Javascript implementation, I will write it in Swift and give more details on how I made it work.

Posted by Luke Godfrey

Luke Godfrey is a graduate student at the University of Arkansas, pursuing a PhD in Computer Science. He has created applications on a number of platforms, and is especially interested in mobile and web development.

View more posts from this author

Leave a Reply

Your email address will not be published. Required fields are marked *