How To Make a Game Like Doodle Jump with Corona Tutorial Part 1

This is a blog post by iOS Tutorial Team member Jacob Gundersen, an indie game developer who runs the Indie Ambitions blog. Check out his latest app – Factor Samurai! I’m willing to bet that when you woke this morning your first thought was “I wish there was a way to create a doodle jump […] By Jake Gundersen.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 5 of this article. Click here to view the first page.

Adding the Player

Now that we have all the clouds included, we can introduce our player. Drag the char_jump2 sprite onto the bottom screen above one of the clouds. Give him the following properties:

Properties for the player in LevelHelper

The player is going to collide with cloud platforms, monsters, and with the level ending shape, so he needs a mask bit value of 5 (1 and 4).

Finally, we need to save our level and generate the code. Choose File-Save and name the file ‘level1’, the necessary extension will be added automatically. Also, choose File->Generate Code->Corona and that will create the LevelHelperLoader.lua file. This file needs to be regenerated every time we add a new TAG.

Place all these files in the same directory as your main.lua.

Loading the Level

Let’s get started with the code and we’ll return to the level design in a minute. Delete your current line of code in main.lua and replace it with the following:

physics = require("physics")
physics.start()

display.setStatusBar( display.HiddenStatusBar )

The main.lua file will execute from top to bottom. These first three lines will be executed first when we start the Corona Simulator. Let’s go over these line by line:

  1. Imports the physics engine code and assigns the engine to the object called physics.
  2. Starts the physics engine with the default gravity values. Corona uses the Box2D physics engine, so if you’ve used Box2D before most of the calls to physics will be familiar to you.
  3. Hides the status bar.

Now that are file is started and we have the physics running we are going to load the level we created with LevelHelper.

Let’s try this out. Add a new function to load the level as follows:

require("LevelHelperLoader")

local function loadLevel()
	localGroup = display.newGroup()
	loader = LevelHelperLoader:initWithContentOfFile("level1.plhs")	
	loader:instantiateObjectsInGroup(physics, localGroup)

	worldHeight = loader:getWorldBoundariesRect().size.height
	localGroup.y = -worldHeight + 480
	
	player = newPlayer()
end

The first line loads the LevelHelperLoader class (generated earlier from LevelHelper or in your resources folder), which is similar to #import in Objective-C.

The next line creates a function, which in Lua is done with the function keyword. Variables and functions in Lua are global in scope by default, if we want to limit the scope to the current function we would include the local keyword.

Corona calls its visual objects (sprites, drawn objects, layers) ‘display objects.’ Each of our sprites, background clouds, player, our platform clouds, etc, are display objects.

Our first line in the function creates a new display group, which in Corona functions much like a CCLayer in Cocos2D. We’re going to add all our level contents to this display group.

The second line creates the loader object and populates it with the contents of our level. We haven’t yet actually created the these objects yet, but we are ready to in the next line.

In Corona we only need a single call to LevelHelper that will create all our display objects and create the associated physics bodies. Corona physics bodies are automatically combined with the their sprites, this makes creating physics based games really easy.

The instantiateObjectsInGroup() call takes two parameters, our physics engine object and the display group to load all the display objects into. Once we’ve loaded the level into the display group, it will be visible on our screen.

Corona automatically adds any display object created to the screen. There is a parent display group that contains any instantiated display object.

Our display objects are now on screen and part of the display group called localGroup. However, localGroup is currently at y position 0, Corona’s coordinate system starts at the top left of the screen and increments towards the bottom, which means we’ll see the very top section of our level, or very end of the level.

We need to move the display group upwards, which we do in the next two lines. First we get the world size, which we set up in LevelHelper, then we set the localgroup.y to the negative world size, sliding it all the way up, minus one screen height.

Finally we create and initialize the player, and assign it to the player variable with the newPlayer() function call. We haven’t written this yet, so add this right above loadLevel:

local function newPlayer()
	local p = loader:spriteWithUniqueName("char_jump2")	
	return p
end

This just gets the sprite with the unique name “char_jump2” that we added to the level we created with LevelHelper, similar to how we did this in the How To Use SpriteHelper and LevelHelper Tutorial with Cocos2D.

One thing to note is that this sprite already has a physics body associated with it. So later on, we’ll have access to those calls that get and set physics properties.

Now that we have these two functions in place, let’s use them! Add the following line of code right after the function definition:

loadLevel()

And that’s it! Save main.lua, and place it a directory along with LevelHelperLoader.lua, cloudSprites.png, cloudSprites-hd.png, cloudSprites.pshs, and level1.plhs. Then load main.lua in the Corona Simulator.

You should then see some clouds and your character fall down off the screen:

The character falling down our basic level

Congratulations, you have written your first Corona program complete with character and platforms!

Lets move on and make the character jump off the clouds!

Adding Collisions and Jumping

To add jumping, modify the newPlayer function to add a collision handler like so:

local function newPlayer()
	local p = loader:spriteWithUniqueName("char_jump2")
	
	local function pCollision(self, event)
		object = event.other				
		if event.phase == "began" then
			vx, vy = self:getLinearVelocity()
			if vy > 0 then
				if object.tag == LevelHelper_TAG.CLOUD then
					self:setLinearVelocity(0, -350)
				end
			end
		end
	end
	p.collision = pCollision
	p:addEventListener("collision", p)
	return p
end

The second line creates our collision callback function. The second parameter contains information about the collision event (full details here).

Self is the player object, and other is an event type. Event.other is the object that the self collided with, and so we’ll want to use that later, we store it in the object variable.

Next, we also want the jump to fire only once. Collisions can be noisy and fire multiple times, we only want a single jump action per cloud collision, so we are only going to be testing for this on the ‘began’ phase.

Then we test to see if we should jump. We get the linear velocity of the self, or player, and we test that it’s greater than 0, because we only want to jump on our way back down, not as we float up through the cloud.

Finally, we are going to look at what we collided with. We want to jump only off white clouds, so we need to check the tag property of the object we collided with.

If all these conditions are met, we will set linear velocity of the self to -350 or up with a speed of 350. We use setLinearVelocity (instead of applyLinearImpulse) here because no matter how much momentum we have gained falling down, we want the jump to be the same height back up.

Finally, we are going to set the function we just created to be the collision callback for our new p, or player, object. The next two lines accomplish this. With collision callbacks, we have to set the .collision property and add an event listener to the object.

Go ahead and open the project once again in the Corona Simulator. Your player should now be boucing off the white clouds!

Our hero bouncing on the clouds

I generally keep the Corona Simulator open between builds, and use the key binding Command-R to reload the project after saving the file. Corona will also detect that the main.lua has been updated and prompt you for a relaunch.

Jake Gundersen

Contributors

Jake Gundersen

Author

Over 300 content creators. Join our team.