Advertisement

Build a Match Shapes Game - Adding Interaction

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

This is the second installment in the Corona SDK Match Shapes tutorial. In today’s tutorial, we’ll add to the interface and game interaction by programming the shape matching algorithm. Read on!


Also available in this series:

  1. Build a Match Shapes Game - Interface Creation
  2. Build a Match Shapes 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 necessary 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)

	transition.to(creditsView, {time = 300, y = display.contentHeight - 25, 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})
end

Step 4: Show Game View

When the Play 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: Game Background

This code places the game background image in the stage.

	-- Game Background

gameBg = display.newImage('gameBg.png', 10, 350)

Step 6: Place Holders

The Place Holders are background graphics used to represent where the actual shapes should be dragged to. The next lines create them and place them in the stage.

-- Place holders

sHolder = display.newImage('sHolder.png', 15, 130)
pHolder = display.newImage('pHolder.png', 115, 130)
tHolder = display.newImage('tHolder.png', 215, 130)

Step 7: Instructions

An instructions message will be animated when the game starts. You can change the time it appears by changing the performWithDelay() code.

-- Instructions

ins = display.newImage('instructions.png', 45, 270)
transition.from(ins, {time = 200, alpha = 0.1, onComplete = function() timer.performWithDelay(2000, function() transition.to(ins, {time = 200, alpha = 0.1, onComplete = function() display.remove(ins) ins = nil end}) end) end})

Step 8: Shapes

The shapes that will be used are created in the next few lines of code.

	-- Shapes

	square = display.newImage('square.png', 240, 386)
	pentagon = display.newImage('pentagon.png', 32, 386)
	triangle = display.newImage('triangle.png', 131, 386)

	square.name = 'square'
	pentagon.name = 'pentagon'
	triangle.name = 'triangle'

	gameListeners()
end

Step 9: Game Listeners

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

function gameListeners()
	function gameListeners()
	square:addEventListener('touch', dragShape)
	triangle:addEventListener('touch', dragShape)
	pentagon:addEventListener('touch', dragShape)
end

Step 10: Hit Test Objects

We'll use an excellent and useful function for collision detection without physics. You can find the original example and source at CoronaLabs Code Exchange.

function hitTestObjects(obj1, obj2)
        local left = obj1.contentBounds.xMin <= obj2.contentBounds.xMin and obj1.contentBounds.xMax >= obj2.contentBounds.xMin
        local right = obj1.contentBounds.xMin >= obj2.contentBounds.xMin and obj1.contentBounds.xMin <= obj2.contentBounds.xMax
        local up = obj1.contentBounds.yMin <= obj2.contentBounds.yMin and obj1.contentBounds.yMax >= obj2.contentBounds.yMin
        local down = obj1.contentBounds.yMin >= obj2.contentBounds.yMin and obj1.contentBounds.yMin <= obj2.contentBounds.yMax
        return (left or right) and (up or down)
end

Step 11: Drag Shapes

This is the principal function of this game, it handles the object dragging by checking the object's position and moving it to the event position.

function dragShape(e)
	if(e.phase == 'began') then
		lastX = e.x - e.target.x
		lastY = e.y - e.target.y
	elseif(e.phase == 'moved') then
		e.target.x = e.x - lastX
		e.target.y = e.y - lastY

Step 12: Square Collision

This last function also contains code that checks if the shape is in the correct spot. This is the square part.

elseif(e.target.name == 'square' and e.phase == 'ended' and hitTestObjects(e.target, sHolder)) then
		e.target.x = 60.5
		e.target.y = 175
		e.target:removeEventListener('touch', dragShape)
		correct = correct + 1
		audio.play(correctSnd)

Step 13: Triangle Collision

The same method is used for the triangle. If the correct shape is placed in the correct spot, the shape drag listener is removed.

elseif(e.target.name == 'triangle' and e.phase == 'ended' and hitTestObjects(e.target, tHolder)) then
		e.target.x = 260
		e.target.y = 169
		e.target:removeEventListener('touch', dragShape)
		correct = correct + 1
		audio.play(correctSnd)

Step 14: Pentagon Collision

This is the pentagon part. If the right shape touches the right spot when the touch event ends, the shape aligns to the center of the placeholder.

elseif(e.target.name == 'pentagon' and e.phase == 'ended' and hitTestObjects(e.target, pHolder)) then
		e.target.x = 160
		e.target.y = 172
		e.target:removeEventListener('touch', dragShape)
		correct = correct + 1
		audio.play(correctSnd)
end

Step 15: Check for Completion

Finally, we'll check if the three shapes have been placed correctly, and then play a sound and call an alert if it is correct.

	if(e.phase == 'ended' and correct == 3) then
		audio.stop()
		audio.play(winSnd)
		alert()
	end
end

Step 16: Alert

The alert function creates an alert view, animates it, and ends the game.

function alert()
	alertView = display.newImage('win.png', 95, 270)
	transition.from(alertView, {time = 200, alpha = 0.1})
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 can do that here:

Main()

Step 18: Loading Screen

The Default.png file is an image that is displayed 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 automatically be added by the Corona compiler.


Step 19: Icon

Using the graphics created previously you can now create a nice 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 transparent glare, iTunes and the iPhone will do that for you.


Step 20: Testing in Simulator

It's time for 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 last 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

In this series you learned about object dragging and collision detection without using the physics engine. This may reduce your app memory consumption and increase the performance. You can experiment with the final result and try to make your custom version of the game!

I hope you enjoyed this tutorial series and found it helpful. Thank you for reading!

Advertisement