Corona Game Engine: when & how to apply collision events
By: Luka Leopoldović
Tags: Game Development, Development, Mobile, Lua, Corona

You’ve probably played lots of mobile games that implemented physical properties and behaviour in certain game aspects. For instance, jumping off the platforms in Doodle Jump or demolishing wood piles in Angry Birds.

But, have you ever wondered what’s behind all those interactions and how does the Doodler know when he can pass through a platform, and when to bounce up from it? How can that wood pile collapse so realistically when an Angry Bird hits it? It’s actually not that hard. They all get by with a little help from collision events.

Since most of my games are made with the Corona Game Engine, I’ll use Corona Collision (Physics) implementation and the Lua programming language to describe and code the examples related to the topic. Nevertheless, similar principles can easily be applied with other game engines as well, since many physics engines work much alike. Corona, in general, does such a wonderful job with the docs, so you may see a couple of references to the documentation in this text, since there was just no point in reinventing the wheel. :)

So, let’s dive into it!

General overview

First of all, it is important to highlight that every game engine uses a physics engine in the background to deal with physics. Corona, in particular, deals with physics by using the Box2D physics engine. This enables you to implement functionalities from the world of physics by simply assigning the physical properties to objects in the game and handling their interactions with proper methods.

Collision events are one of those. They enable you to detect and handle collisions between physical objects. Imagine playing a simple game where the character collects falling objects, catching the good ones and avoiding the bad ones. To detect when the character had interacted with a falling object, you would simply do a check in the collision event you had previously assigned to the character and to the falling objects.

This check can be as basic as:

Since collision events are physical interaction detectors, it is assumed you had previously added physics bodies to objects you want to be able to interact with. This definition is simple, but it’s a must if you want your objects to correspond to physical interactions.

For instance, you could say:

As you can see, there are several definitions included here: the type of body (dynamic bodies move under simulation according to the forces like gravity or reactionary collision forces, and they accept the application of velocity, static bodies will not respond to the forces like gravity and they will act like they have infinite mass, kinematic bodies move under simulation only according to their velocity etc. — you can learn more about it on coronalabs.com) and the physical properties which will take action in various physical interactions. For instance, if our character was a ball hitting the ground, it would bounce off pretty high since much of its velocity would return after the collision (bounce = 0.8). If our character was a man climbing a hill and we don’t want him to lean backwards and fall down while climbing it, we could freeze its rotation around a specific axis etc.

This all may sound like it takes a lot of specialized knowledge to implement, but it really doesn’t. A lot of simple games can easily be created with just the basic understanding of physics, since the engine handles most of the things for you.

Collisions in specific

As I said before, collision events enable you to detect and handle collision between physical objects. There are several types of collisions possible to define with Corona:

pre-collision

collision

post-collision

There’s also a sub-case of each collision event, defining it as:

local collision

global collision

Which one you choose depends on what you plan to do.

Let’s start with global vs. local collision. Local collisions are best utilized in one-to-many collision scenarios, while global collisions are best utilized in many-to-many collision scenarios — you can get the specifics on coronalabs.com. So, our character, catching the good falling objects and avoiding the bad ones would perfectly fit with a local collision event. If your game had multiple characters, consider using a global collision event, which is defined as a global runtime, detecting collisions between all physics objects in the game.

Local collision events are described with self and event params, representing the object itself and, among else, other Corona display objects involved in the collision. Corona display objects possess a really cool feature — they behave like Lua tables, meaning that various data, like names, identifiers or categories can easily be added to them. This particularly comes to use while dealing with collision. An identifier can be added to every good and bad object (e.g. “good”, “bad”) and by comparing those identifiers inside the collision event, it is very easy to find out which one did the player just collect. If it is a good one, you could award player with score points. If not, you could reduce his life points.

This scenario can easily be built using regular collision. That means you are able to detect physical contacts between objects which are assigned a physics body. This event consists of began and ended phases, so you could perform actions on initial and broken contact moments. For instance, imagine you’re building a space game like Little Galaxy and you have defined your planet’s gravity fields using the physics joints technique. With began and ended phases of the collision event, you could find out when a satellite has entered and left the planet’s gravity field and then perform certain actions. Let’s return to our character catching the obstacles and see how this looks in action.

First of all, I’ll create some global constants for dealing with different screen sizes. This approach may vary from developer to developer. This one is related to content size defined in config.lua and I have personally found this method to be most suitable for my use.

I will also create global enumeration, which I will use later as an identifier for falling objects:

Furthermore, I will implement the necessary library, start the physics and “turn off gravity”:

Next, I am going to create our character. For the sake of example, it (as well as the falling objects) is going be represented with a simple circle:

The character has the Y anchor property set as 1. This means its Y axis reference point is set to its lowest point. Consequently, when it is positioned to the center of the screen, the circle bottom will be placed there. This will be very important in later “Doodle Jump” (post-collision) example.

As mentioned before, all objects that should participate in physical interactions, must be assigned a physics body:

Notice that I have defined the character as a sensor. This means other physical object won’t be able to physically interact with the character (no bounce, no friction etc.) but we’re still going to be able to detect collisions. This principle is often applied when we don’t want objects colliding and flying around the screen due to following physical behaviour, but simply detect when they have interacted and do something based on the interaction itself (e.g., increase or decrease score).

Now, let’s create a function for generating falling objects:

This function will be called with timer, generating an object every 2 seconds and animating it from the top to the bottom of the screen. As you can see, every obstacle is identified with a previously defined enumeration and, for visual differentiation, every good falling object will be colored green, while the bad ones will be colored red.

Now, you may wonder why do I set falling objects as sensors as well? In a worked out game scenario, you may want to use the accelerometer to lean your character left and right to collect/avoid falling objects and randomly generate the position where a falling object will start its journey to the bottom of the screen. If you narrow the time interval necessary for the object to generate as the player progresses through the game, it is likely that some obstacles will be generated very close to each other.

If they were not set as sensors, they would collide and behave very unnaturally, since transitions (not gravity!) are used for moving the objects from the top to the bottom of the screen. This way, especially if their falling speeds differ, they may freely pass through each other and you can still detect character collisions with these objects, since both are defined as physics bodies.

Now’s the time to define our collision event in the form of a function:

This event must be joined and tied to our character in order to have any effect:

Our listener now “listens” for any physical interactions our character gets involved with. Once it interacts with a falling object, a simple check is done to see if user collected a good or a bad object. For every good object collected, user is awarded with 10 points. On the other hand, if he collects a bad object, his points are reduced by 10. When that’s done, the falling object will be removed, and the character will be nicely animated to visually show a collision has occurred.

Let’s preview the results!

Object-catching game in action

As you can see, this was all easily accomplished since there is a physics engine in the background dealing with all the complex stuff for you. You can download the full code here.

Now, let’s see how pre-collision can be easily applied to accomplish some interesting behaviour. Maybe the best example to show this would be to create a Doodle Jump-like platform game with a bouncing character. Believe it or not, this essential game functionality isn’t any harder to implement than the previous “object-catching” one. We’ll start the same by first defining the UI elements and giving them a physics body.

This time, these are going to be a player and a set of hard-coded platforms:

Again, notice the platforms are given an identifier and this time, they are defined as static bodies, while the character is still a dynamic one. The reason behind this is gravity:

In order for platforms not to collapse and fall down, they must be defined as static bodies, meaning they will not respond to forces like gravity. Our player, on the other hand, must be pulled down every time he jumps. Notice that the Y anchor point of our character is again set to its lowest point. This will be used in pre-collision event, checking if the character position (his feet) are above or below the platform he’s about to collide with.

If his feet are below, disable the contact. If his feet are above, give him a little push into the air:

Pre-collision is a bit noisy and it can fire multiple times per contact. To give our character only one push into the air per contact, we can get his linear velocity, and based on the velocity sign (Y direction) determine if the character is falling down and approaching the platform. Since our character’s initial velocity is 0, we need to give him a little push at the start and he is good to go!

Platform jump game in action

The next step would be creating a function for randomly generating platforms and moving them downwards as the character jumps up. Since that is not the topic, I’ll leave that for another blog. I just want to mention that these particular mechanics can be accomplished by using a variety of approaches. For the sake of the example, I have chosen this one. Don’t be scared to experiment! You can download the full demo code here.

The last, but not least is a post-collision event. It’s the only collision event where the collision force and friction are reported (again, more info on coronalabs.com). What this means for you as a game developer? Based on these values, you could, for instance, determine the strength and the quantity of certain events.

If you’re making a pinball game, you could play the sound of the bat hitting the ball proportional to the event force. If you are building an ice-hockey game and use particles to display ice chopping when a paddle hits the puck, you could emit more particles with a stronger hit.

For this example, I’ll create a ball hitting our character’s circle.

The ball is placed vertically below the character. Now, I’ll apply some force to it, directing it towards the character, but with random X and Y force values, so you could see the differences in the final result (behaviour) after the ball was steered slightly different and hit the character at a different point.

Post-collision event can be defined like this:

And the final result looks like this:

Post-collision game in action

The character is moving pretty realistically after the hit, right? All we did was set a few properties to the objects and the physics world itself. It’s because all mechanics behind this event are handled for you by the physics engine. Full code can be found here.

Conclusion

As you can see, collision manipulation is pretty handy. Since the physics engine does most of the stuff for you in the background, many basic (but very effective) things can easily be accomplished with just the basic understanding of physics and, of course, the game engine you’re working with.

Collision events can and should be paired with various other events, leaving you with endless possibilities, limited only by performance and your imagination.

__________

We’re available for partnerships and open for new projects. If you have an idea you’d like to discuss, share it with our team!