Advertisement

Create a Bubble Popping Game - Adding Interaction

by

This is the second installment in our Corona SDK Bubble Popping game tutorial. In today's tutorial, we'll add to our interface by coding the game interaction. Read on!


Also available in this series:

  1. Create a Bubble Popping Game - Interface Creation
  2. Create a Bubble Popping Game - Adding Interaction

Where We Left Off. . .

Please be sure to check part 1 of the series to fully understand and prepare for this tutorial.


Step 1: Start Button Listeners

This function adds the necesary listeners to the TitleView buttons.

function startButtonListeners(action)
	if(action == 'add') then
		playBtn:addEventListener('tap', showGameView)
		creditsBtn:addEventListener('tap', showCredits)
	else
		playBtn:removeEventListener('tap', showGameView)
		creditsBtn:removeEventListener('tap', showCredits)
	end
end


Step 2: Show Credits

The credits screen is shown when the user taps the about button, a tap listener is added to the credits view to remove it.

function showCredits:tap(e)
	playBtn.isVisible = false
	creditsBtn.isVisible = false
	creditsView = display.newImage('credits.png', 0, display.contentHeight)
	
	lastY = titleBg.y
	transition.to(titleBg, {time = 300, y = (display.contentHeight * 0.5) - (titleBg.height + 30)})
	transition.to(creditsView, {time = 300, y = (display.contentHeight * 0.5) + 35, onComplete = function() creditsView:addEventListener('tap', hideCredits) end})
end

Step 3: Hide Credits

When the credits screen is tapped, it'll be tweened out of the stage and removed.

function hideCredits:tap(e)
	transition.to(creditsView, {time = 300, y = display.contentHeight + 25, onComplete = function() creditsBtn.isVisible = true playBtn.isVisible = true creditsView:removeEventListener('tap', hideCredits) display.remove(creditsView) creditsView = nil end})
	transition.to(titleBg, {time = 300, y = lastY});
end

Step 4: Show Game View

When the Start button is tapped, the title view is tweened and removed revealing the game view. There are many parts involved in this view so we'll split them in the next steps.

function showGameView:tap(e)
	transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners('rmv') display.remove(titleView) titleView = nil end})

Step 5: Walls

Next we add the walls to the stage. They are created using the drawing API.

-- Walls
	
left = display.newLine(0, 240, 0, 720)
right = display.newLine(320, 240, 320, 720)
top = display.newLine(160, 0, 480, 0)
bottom = display.newLine(160, 480, 480, 480)

Step 6: Bubbles

This part creates five bubbles in the screen at a random position.

bubbles = display.newGroup()
	
for i = 1, 5 do
	local rx = 21 + math.floor(math.random() * (display.contentWidth - 42))
	local ry = 21 + math.floor(math.random() * (display.contentHeight - 42))
		
	local b = display.newImage('bubble.png', rx, ry)
	b.name = 'bubble'

Step 7: Bubble Physics

Here we add physics to our new bubble.

-- Bubble Physics
		
	physics.addBody(b, 'dynamic', {radius = 21, bounce = 1})
	b:setLinearVelocity(100, 100)
		
	bubbles:insert(b)
end

Step 8: Wall Physics

And do the same with our walls.

-- Walls Physics
	
physics.addBody(left, 'static')
physics.addBody(right, 'static')
physics.addBody(top, 'static')
physics.addBody(bottom, 'static')

Step 9: TextFields

Now we add the level, popped and required bubbles textfields.

	-- Level TextField
	
	level = display.newImage('level.png', 2, 0)
	
	levelN = display.newText('1', 54, 5, native.systemFont, 15)
	levelN:setTextColor(255, 255, 255)
	
	-- Popped TextField
	
	popped = display.newImage('popped.png', 126, 0)
	
	poppedN = display.newText('0', 187, 5, native.systemFont, 15)
	poppedN:setTextColor(255, 255, 255)
	
	-- Required TextField
	
	required = display.newImage('required.png', 231, 0)
	
	requiredN = display.newText('4', 306, 5, native.systemFont, 15)
	requiredN:setTextColor(255, 255, 255)
	bullets = display.newGroup()
 end

Step 10: Game Listeners

This function adds the necessary listeners to start the game logic.

function gameListeners(action)
	if(action == 'add') then
		bg:addEventListener('tap', createBullets)
	else
		bg:removeEventListener('tap', createBullets)
		Runtime:removeEventListener('enterFrame', update)
	end
end

Step 11: Create Bullets

This code runs when the background is tapped.

First we create the bullet graphics.

function createBullets(e)
	for i = 1, 4 do
		local bullet = display.newImage('bullet.png', e.x, e.y)

Step 12: Set Direction

Then we give it a direction by setting the linear velocity.

-- Set direction
		
		if(i == 1) then bullet.x = bullet.x - 8 physics.addBody(bullet, 'kinematic', {radius = 7}) bullet:setLinearVelocity(-150, 0) end --left
		if(i == 2) then bullet.x = bullet.x + 8 physics.addBody(bullet, 'kinematic', {radius = 7}) bullet:setLinearVelocity(150, 0) end --right
		if(i == 3) then bullet.y = bullet.y - 8 physics.addBody(bullet, 'kinematic', {radius = 7}) bullet:setLinearVelocity(0, -150) end --up
		if(i == 4) then bullet.y = bullet.y + 8 physics.addBody(bullet, 'kinematic', {radius = 7}) bullet:setLinearVelocity(0, 150) end --down
		
		bullet:addEventListener('collision', onCollision)
		bullets:insert(bullet)
		
		bg:removeEventListener('tap', createBullets)
	end
	Runtime:addEventListener('enterFrame', update)
end

Step 13: Collisions

The collisions are handled by the next function. A sound is played, the score increases and removes the bubble of the screen.

function onCollision(e)
	if(e.other.name == 'bubble') then
		audio.play(pop)
		display.remove(e.other)
		poppedN.text = tostring(tonumber(poppedN.text) + 1)
	end
end

Step 14: Remove Offstage Bullets

This code will remove any bullet that is out of sight.

	function update(e)
	-- Check for offstage bullets

	for i = 1, bullets.numChildren do
		if(bullets[i] ~= nil) then
			if(bullets[i].x < 0 or bullets[i].x > 320 or bullets[i].y < 0 or bullets[i].y > 480) then
				display.remove(bullets[i])
			end
		end
	end

Step 15: Level Complete

Here we check if the popped bubbles have reached the required quantity and call a win alert if true.

	-- Check if required bubbles were popped
	
	if(bullets.numChildren == 0 and tonumber(poppedN.text) >= tonumber(requiredN.text)) then
		alert('win')
	elseif(bullets.numChildren == 0 and tonumber(poppedN.text) < tonumber(requiredN.text)) then
		alert('lose')
	end
end

Step 16: Alert

The alert function displays a message according to the type of alert called (level complete or failed).

function alert(action)
	gameListeners('rmv')
	if(action == 'win') then
		local alertView = display.newImage('won.png', 80, display.contentHeight * 0.5 - 41)
		transition.from(alertView, {time = 300, y = -82, delay = 500})
	else
		local alertView = display.newImage('lost.png', 80, display.contentHeight * 0.5 - 41)
		transition.from(alertView, {time = 300, y = -82, delay = 500})
	end
end

Step 17: Call Main Function

In order to start the game, the Main function needs to be called. With the above code in place, we'll do that here:

Main()

Step 18: Loading Screen

The Default.png file is an image that will be displayed right when you start the application while the iOS loads the basic data to show the Main Screen. Add this image to your project source folder, it will be automatically added by the Corona compliler.


Step 19: Icon

Using the graphics you created before you can now create a nice and good looking icon. The icon size for the non-retina iPhone icon is 57x57px, but the retina version is 114x114px and the iTunes store requires a 512x512px version. I suggest creating the 512x512 version first and then scaling down for the other sizes.

It doesn't need to have the rounded corners or the transparent glare, iTunes and the iPhone will do that for you.


Step 20: Testing in Simulator

It's time to do the final test. Open the Corona Simulator, browse to your project folder, and then click open. If everything works as expected, you are ready for the final step!


Step 21: Build

In the Corona Simulator go to File > Build and select your target device. Fill the required data and click build. Wait a few seconds and your app will be ready for device testing and/or submission for distribution!


Conclusion

Experiment with the final result and try to make your custom version of the game!

I hope you liked this tutorial series and find it helpful. Thank you for reading!

Advertisement