This is the second installment in our Corona SDK Hundreds game tutorial. In today’s tutorial, we’ll add to our interface and the game interaction. Read on!
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 lastX = titleBg.x transition.to(titleBg, {time = 300, y = (display.contentHeight * 0.5) - (titleBg.height + 20), x = (display.contentWidth * 0.5) - (titleBg.width * 0.5) - 10}) 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, x = lastX}); 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: Game Background
This code places the game background image in the stage.
-- Game Background display.remove(bg) gameBg = display.newImage('gameBg.png')
Step 6: 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 7: Circles
This part creates five circles in the screen at a random position, the i variable is used to multiply a constant that will define the circles color making it lighter each time. A textfield is also created and both are held within a group to move them together.
-- Circles circles = display.newGroup() local color = 0 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 cg = display.newCircle(rx, ry, 21) local label = display.newText('0',cg.x-4.2, cg.y-12.2, native.systemFontBold, 13) cg.fillColor = color + (i*40) cg:setFillColor(cg.fillColor) local c = display.newGroup(cg, label) c.pressed = false c.name = 'c' c.radius = 21
Step 8: Circle Physics
Here we add physics to our new circle.
-- Circle Physics physics.addBody(c, 'dynamic', {radius = 21, bounce = 1}) c:setLinearVelocity(100, 100) circles:insert(c) end
Step 9: 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 10: Score TextField
Now we add the score textfields.
-- Score TextField score = display.newText('0', 257, 4, native.systemFont, 15) score:setTextColor(150, 150, 150) local total = display.newText(' / 100', 267, 4, native.systemFont, 15) total:setTextColor(150, 150, 150) gameListeners('add') end
Step 11: Game Listeners
This function adds the necessary listeners to start the game logic.
function gameListeners(action) if(action == 'add') then for i = 1, 5 do circles[i]:addEventListener('touch', onTouch) circles[i]:addEventListener('collision', onCollision) end else for i = 1, 5 do circles[i]:removeEventListener('touch', onTouch) circles[i]:removeEventListener('collision', onCollision) end end end
Step 12: Increase Score
This code runs when the circle is touched.
First we increase the score.
function onTouch(e) if(e.phase == 'began') then e.target.pressed = true -- Increase Counter score.text = tostring(tonumber(score.text) + 2)
Step 13: Increase Size
Then the size of the circle. The circle will grow when the finger is no longer on it.
-- Increase size e.target.radius = e.target.radius + 2
Step 14: Change Color
Changes the color from black/gray to red.
-- Change Color e.target[1]:setFillColor(224, 11, 0)
Step 15: Update Circle
We recreate the circle and its properties when the touch event has ended.
if(e.phase == 'ended') then e.target.pressed = false -- Update physics local number = tostring(tonumber(e.target[2].text)+2) local r = e.target.radius local cg = display.newCircle(e.target.x, e.target.y, r) local label = display.newText(number ,cg.x-4.2, cg.y-12.2, native.systemFontBold, 13) cg:setFillColor(e.target[1].fillColor) cg.fillColor = e.target[1].fillColor local c = display.newGroup(cg, label) c.pressed = false c.name = 'c' c.radius = r circles:remove(e.target) physics.addBody(c, 'dynamic', {radius = r, bounce = 1}) c:setLinearVelocity(100, 100) c:addEventListener('touch', onTouch) c:addEventListener('collision', onCollision) circles:insert(c) -- Move Textfield when number is 2 digit if(tonumber(number) > 9) then label.x = label.x - 5 end
Step 16: Level Complete
Here we check if the score has reached 100 points and call a win alert if true.
-- Check if score has reached 100 if(tonumber(score.text) >= 100) then local bg = display.newImage('gameBg.png') transition.from(bg, {time = 500, alpha = 0, onComplete = alert('win')}) end end end
Step 17: Collisions
The game is lost when a pressed circle collides with another one. The listeners are removed and a lost alert is called.
function onCollision(e) if(e.target.pressed and e.other.name == 'c') then -- Wait 0.1 seconds to stop physics timer.performWithDelay(100, function() physics.stop() end, 1) local r = e.target.radius local c = display.newCircle(e.target.x, e.target.y, r) c:setFillColor(224, 11, 0) gameListeners('rmv') transition.to(c, {time = 700, xScale = 25, yScale = 25, onComplete = alert('lost')}) end end
Step 18: Alert
The alert function displays a message according to the type of alert called.
function alert(action) if(action == 'win') then local alertView = display.newImage('won.png', 10, display.contentHeight * 0.5 - 41) transition.from(alertView, {time = 300, y = -82, delay = 500}) else local alertView = display.newImage('lost.png', 10, display.contentHeight * 0.5 - 41) transition.from(alertView, {time = 300, y = -82, delay = 500}) end end
Step 19: 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 20: 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 21: 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 512×512 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 22: 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 23: 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!