Advertisement

How to Blow Stuff Up With the Corona SDK Physics Engine: Part 1

by

Overview

Everyone loves a good physics game, but let's face it: it's much more fun when you're blowing stuff up! This tutorial will show you how to use the Corona physics engine to create explosions in your game.

Setup

As a bit of housekeeping, let's start by creating a build.settings file with the following code:

settings =
{
	orientation =
	{
		default = "landscapeRight",
		supported =
		{
			"landscapeLeft", "landscapeRight"
		}
	}
}

The details behind all of the options for this file are beyond the scope of this tutorial. The above settings will force the orientation of the mobile device into landscape or horizontal mode. Since we only have one set of graphics, forcing a landscape orientation will keep things simpler.

Physics

Next, we'll start by setting up our physics engine in our main.lua file:

local physics = require("physics")
physics.start()
display.setStatusBar( display.HiddenStatusBar )

Easy right? Corona is awesome! In this section, we've also included a line to hide the status bar. This allows us to take over the entire screen of the mobile device without any native components.

Graphics

Now that we have the basics done, let's add a nice looking background and center its position relative to the center of the mobile device:

local background = display.newImage( "bricks.png", 0, 0, true )
background.x = display.contentWidth / 2
background.y = display.contentHeight / 2

In the above code we're adding a background image to the stage with the display.newImage method. It's initial position in the top, left corner is 0,0 as stated by the 2nd and 3rd parameters. By default, Corona will position images with an anchor point in its exact center. We use the x,y methods on the background object to position the anchor point of the image in the exact center of the screen.

Before we add any dynamic objects to the screen, let's add a floor for them to sit on:

local floor = display.newImage( "floor.png", 0, 280, true )
physics.addBody( floor, "static", { friction=0.5 } )

We add an image just like we did for the background, positioning it in the bottom of the screen. The floor object is then added to the stage as a "static" physics body. "Static" in this case means the object will interact with other physics objects on the screen but will not be affected by gravity or any inertial forces from moving objects.

Dynamic Objects

Our next step will be to set up a bunch of precariously stacked crates that are just waiting to get rocked:

local crates = {}

for i = 1, 5 do
	for j = 1, 5 do
		crates[i] = display.newImage( "crate.png", 140 + (i*50), 220 - (j*50) )
		physics.addBody( crates[i], { density=0.2, friction=0.1, bounce=0.5 } )
	end
end

The above code might look complex at first but it is actually very simple. We have two nested loops that we cycle through to create a set of crates 5 wide and 5 tall by incrementing the x and y values. Each of these crates is added to the stage as a "dynamic" body. "Dynamic", although not specified in the code, is the default type for all physics bodies. We've added a few parameters to determine the behavior of the object when forces are acted upon it. The density value for each crate will be important later on when we determine the force of our explosion. The denser the objects, the greater the force needed to move them. Wanna try something fun? Increase the bounce value to 1.0 and watch what happens to the crates.

Setting the Bomb

Phew! Ready for the fun part? Let's blow these things up. The principle behind creating explosions is to determine an explosion epicenter and blast radius and affect all objects that fall within it. For this example, the epicenter of the explosion will be determined by where we touch the screen. Let's start by adding that behavior:

local circle = ""

local function setBomb ( event )
	if(event.phase == "began") then
		circle = display.newCircle( event.x, event.y, 80 )
                circle.myName = “circle”
		circle:setFillColor(0,0,0, 0)
		physics.addBody( circle, "static", {isSensor = true} )
		circle.collision = onLocalCollision
		circle:addEventListener( "collision", circle )
	end
		if(event.phase == "ended") then
		circle:removeSelf()
	end
end

background:addEventListener("touch",setBomb)

Here we've defined a method called setBomb that generates an invisible circle with a radius of 80. The circle is positioned where the user has touched the screen. The physics body we are adding has a special parameter called isSensor set to true. Sensor objects are present in the physics engine but are not affected by gravity nor do they affect other objects. We are using a sensor object in this case simply to detect which crates are contacting it. Contact will be determined by listening for collision events between the crates and our sensor. Any crate that collides with our sensor is inside the blast radius and thus will be affected by the force of the explosion.

Kaboom!

The following method will be executed upon the detection of any object's collision with the sensor we created in the above code.

* As a point of information, the following method must be defined in the code prior to the above setBomb method. For flow reasons, however, we have placed it later in the tutorial.

local function onLocalCollision( self, event )
	if ( event.phase == "began" and self.myName == "circle" ) then
		local forcex = event.other.x-self.x
		local forcey = event.other.y-self.y-20
		if(forcex < 0) then
			forcex = 0-(80 + forcex)-12
		else
			forcex = 80 - forcex+12
		end
		event.other:applyForce( forcex, forcey, self.x, self.y )
	end
end

The basic idea behind this method is to apply a force to any object that has collided with our sensor circle. We've created two variables called forcex and forcey. We use the distance from the center of the crate to the center of our sensor circle to determine the strength of the force we will apply. By doing this, we create a poor man's way of diminishing the force of the explosion the further the object is from the epicenter of the blast. All of these numbers are highly dependent on the physics properties of the objects we are blowing up.

* Note: Forces as numerical values are much higher than the density, friction, and bounce properties of objects. Feel free to play around with these values to get some interesting results!

Conclusion

And there we have it. This tutorial should provide an excellent starting point to creating all kinds of cool games involving explosions. Take some time to experiment with the properties and values of all the variables in this exercise.

In Part II of this tutorial we'll add some extra bells and whistles to the explosion framework to make it even more destructive!

Leave some comments and let me know what you think about Part I.

Advertisement