colldet-featA question that occasionally comes up in the forums is “how can I tell when object A touches object B?” In programming terms, this is known as a “collision”.

Corona SDK has a robust collision detection engine that can accomplish many things. It’s even event-driven, which means you can sense when collisions have began and ended. This system reports when the collision happens and which two objects are involved in the collision. The only “catch” is that it’s based on Corona’s physics engine. That means every moving object needs to be a physics-based object under the control of this physics engine. While the physics engine is a lean, mean, calculating machine, it’s still extra math and processing behind that scenes that you typically don’t need if you’re not using physics for other purposes — for example, if you simply want to know if object A is occupying the same screen space as object B.

Detection Methods

There are multiple ways to detect collisions without using physics. These methods are similar to those used by the physics engine, but you won’t deal with gravity, density, bounce, friction, etc. Some of these methods include:

  1. Point Inside a Rectangle
  2. Separating Axis Theorem
  3. Overlapping Circles
  4. Overlapping Rectangles

“Point Inside a Rectangle” can be complex if the rectangles have any rotation applied to them. Similarly, the “Separating Axis Theorem” is fairly math-intensive and won’t be covered in this tutorial. You can read about it here if you’re curious.

NOTE: Before considering non-physics collision detection, remember that if your objects are not basic rectangles or circles, the physics engine is likely the best choice to handle your collisions. Using it, you can define complex polygon-based shapes from multiple parts that represent the actual shape of your objects better than these methods will. Essentially, the non-physics methods in this tutorial follow the “close enough” methodology. If you need precise collisions, the physics engine is the logical choice.

Overlapping Circles

In an “Asteroids” type game, the ship — even though it might appear triangular — can be represented by a circle: either a circle that encloses the entire ship, or a circle that spans a slightly smaller area around the center of the ship. The asteroids flying around can also be roughly represented by circles. During fast gameplay, the player will not really notice exact shape-precise collision detection.

Some very simple calculations can tell you if any two circles of an arbitrary sizes are overlapping:

Here, you pass in two display objects. Since a circle is still a “rectangular image” from a display object standpoint, we’ll use the contentWidth to determine the size of the circles. If the two circles are closer than the distance of their centers, they are touching.

Overlapping Rectangles

This code was originally located in the the Corona Labs Code Share:

This function uses the built-in contentBounds of each rectangle to see if they have overlapped. This works great for tiles and cards since they are visually rectangular. It uses a set of if statement checks to see if any corner of one rectangle is inside the bounds of the other rectangle. For graphics that have some transparency around them, note that this will include the transparent areas. Both functions will return true if the objects/points are colliding with the other object.

Checking for Collisions

Now that you have a couple different ways to determine if two items have collided, how do you actually use them? Unlike physics-based collisions, these are not listener events where the system tells you exactly when they collide. Instead, you must check periodically in your own code. The two primary ways are:

  1. While touch-dragging an object around the screen.
  2. Checking each frame/cycle using an enterFrame Runtime listener (“game loop” method).

Touch and Drag

You’ve probably seen this touch-drag code before:

Now, for collision detection, you’ll add a check inside the phase moved or ended/cancelled conditional blocks, depending on when you need to check for the collision.

For simplicity, let’s use an example of dragging a card to a “drop zone,” potentially represented in your user interface by some outline graphic.

Now, you can request collision detection inside the standard drag handler. In this case, since you only care if the object is “dropped” in the right place, use the ended/cancelled phase:

With this code, if you drag the card and drop it outside the drop zone, it will transition back to its original location. If the card touches the hot spot, then it will snap the target into place!

Let’s look at another example. This time you will spawn a bunch of coins and then touch-drag myPlayer to pick them up. Instead of doing the collision check in the ended/cancelled phase, you’ll check in the moved phase so that the collision report will occur immediately when myPlayer crosses over a coin:

Runtime Detection (Game Loop)

These collision techniques also work well in enterFrame listeners where you can check for things that are transitioning around that the user isn’t directly in control of.

For this to work, your objects need to be in an array to loop through. Using the same coins above, let’s apply some transitions to move them to the bottom of the screen and then remove those coins that hit our player. For additional effect, if the coin hits our player, we’ll turn it blue.

This concludes the tutorial on non-physics collision detection. As you can see, this is a convenient method when you’re building an app where you require basic collision detection, but the physics engine — as powerful as it can be — is overkill for the required tasks.

View post: 

Tutorial: Non-Physics Collision Detection