This is the second installment in our Corona SDK Alphabet Soup Game tutorial. In today's tutorial, we'll add to our interface and start coding the game interaction. Read on!
Step 1: Declare Functions
Declare all functions as local at the start.
local Main = {} local addTitleView = {} local startBtnuttonListeners = {} local showCredits = {} local hideCredits = {} local showGameView = {} local gameListeners = {} local buildSoup = {} local startDraw = {} local hitTestObjects = {} local detectLetters = {} local alert = {}
Step 2: Constructor
Next we'll create the function that will initialize all the game logic:
function Main() addTitleView() end
Step 3: Add Title View
Now we place the TitleView in the stage and call a function that will add the tap listeners to the buttons.
function addTitleView() titleBg = display.newImage('titleBg.png') title = display.newImage('title.png') title.x = display.contentCenterX title.y = 120 startBtn = display.newImage('startBtn.png') startBtn.x = display.contentCenterX startBtn.y = display.contentCenterY + 20 aboutBtn = display.newImage('aboutBtn.png') aboutBtn.x = display.contentCenterX aboutBtn.y = display.contentCenterY + 65 titleView = display.newGroup() titleView:insert(titleBg) titleView:insert(title) titleView:insert(startBtn) titleView:insert(aboutBtn) startButtonListeners('add') end end
Step 4: Start Button Listeners
This function adds the necesary listeners to the TitleView buttons.
function startButtonListeners(action) if(action == 'add') then aboutBtn:addEventListener('tap', showCredits) startBtn:addEventListener('tap', showGameView) else aboutBtn:removeEventListener('tap', showCredits) startBtn:removeEventListener('tap', showGameView) end end
Step 5: 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() aboutBtn.isVisible = false startBtn.isVisible = false about = display.newImage('about.png') about.x = about.width * 0.474 about.y = display.contentHeight + about.height transition.to(about, {time = 300, y = display.contentHeight - about.height/2.4, onComplete = function() about:addEventListener('tap', hideCredits) end}) end
Step 6: Hide Credits
When the credits screen is tapped, it'll be tweened out of the stage and removed.
function hideCredits() transition.to(about, {time = 300, y = display.contentHeight+about.height, onComplete = function() aboutBtn.isVisible = true startBtn.isVisible = true about:removeEventListener('tap', hideCredits) display.remove(about) about = nil end}) end
Step 7: Show Game View
When the Start button is tapped, the title view is tweened and removed revealing the game view.
function showGameView:tap() transition.to(titleView, {time = 300, y = -titleView.height, onComplete = function() display.remove(titleView) titleView = nil buildSoup() gameListeners('add') end}) end
Step 8: Game Listeners
This code adds tap listeners to the game background, and these will be used to draw the selection line and identify the selected letters.
function gameListeners(action) if(action == 'add') then gameBg:addEventListener('touch', startDraw) gameBg:addEventListener('touch', detectLetters) else gameBg:removeEventListener('touch', startDraw) gameBg:removeEventListener('touch', detectLetters) end end
Step 9: Build Soup Function
One of the main functions of the game; this will browse the Map table to create all the textfields and place them in the stage, continue to the next step to see its behavior.
function buildSoup() -- Code... end
Step 10: Create Character TextFields
A double for is used to identify the elements in the Map table, one for the horizontal values and one for the vertical. The code will create a textfield for every value found in the table and then place them in the stage.
for i = 1, 10 do for j = 1, 12 do local tf = display.newText('', 0, 0, 'Arial', 19) tf:setTextColor(102, 102, 102) tf.width = 22 tf.height = 21 tf.x = math.floor(-10 + (31.3 * i)) tf.y = math.floor(-10 + (35 * j))
Step 11: Display Random Letters
The chosen words are already in the table, and the rest of the values are filled by 0's at the moment. The following lines change those 0's to a random letter.
-- Change 0's to Random Letters if(L1Map[j][i] == 0) then L1Map[j][i] = alphabet[math.floor(math.random() * table.maxn(alphabet))+1] end tf.text = L1Map[j][i] tfs:insert(tf) end end
Step 12: Add Words List
This code creates two textfields that will contain the list of values to find and the values already found.
-- Add Words List local wordsString = '' for i = 1, #L1 do wordsString = wordsString .. ' ' .. L1[i] end wordsList = display.newText(wordsString, 5, 430, 'Arial', 14) wordsList:setTextColor(238, 238, 238) currentWords = display.newText('', 5, 455, 'Arial', 14) currentWords:setTextColor(238, 146, 63)
Step 13: Draw Selection Line
A semi transparent line will be used to highlight the letters in the stage, in the next function this line is created and added to the stage.
function startDraw:touch(e) if(e.phase == 'began') then initX = e.x initY = e.y elseif(e.phase == 'ended') then line = display.newLine(initX, initY, e.x, e.y) line.width = 16 line:setColor(255, 142, 42, 60) lines:insert(line) end end
Step 14: Code Review
Here is the full code written in this tutorial alongside comments to help you identify each part:
-- Alphabet Soup Game -- Developed by Carlos Yanez -- Hide Status Bar display.setStatusBar(display.HiddenStatusBar) -- Graphics -- [Background] -- [Game Background] local gameBg = display.newImage('bg.png') -- [Title View] local titleBg local title local startBtn local aboutBtn -- [TitleView Group] local titleView -- [CreditsView] local about -- [Words List Textfield] local wordsList local currentWords -- [Letter Texfields Container] local tfs = display.newGroup() -- [Selection Line] local line local lines = display.newGroup() -- [Alert] local alert -- [Sound] local bell = audio.loadStream('bell.caf') -- Variables local L1 = {'IPHONE', 'ANDROID', 'CORONA', 'MOBILE', 'GAMES'} local L1Map = {{0, 0, 'I', 0, 0, 0, 'G', 0, 0, 0}, {0, 0, 'P', 0, 0, 0, 'A', 0, 0, 0}, {0, 0, 'H', 0, 0, 0, 'M', 0, 0, 0}, {0, 'M', 'O', 'B', 'I', 'L', 'E', 0, 0, 0}, {0, 0, 'N', 0, 0, 0, 'S', 0, 0, 0}, {0, 0, 'E', 0, 0, 0, 0, 0, 0, 0}, {'C', 'O', 'R', 'O', 'N', 'A', 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 'A', 'N', 'D', 'R', 'O', 'I', 'D', 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}} local alphabet = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'} local correct = 0 -- Functions local Main = {} local addTitleView = {} local startBtnuttonListeners = {} local showCredits = {} local hideCredits = {} local showGameView = {} local gameListeners = {} local buildSoup = {} local startDraw = {} local hitTestObjects = {} local detectLetters = {} local alert = {} function Main() addTitleView() end function addTitleView() titleBg = display.newImage('titleBg.png') title = display.newImage('title.png') title.x = display.contentCenterX title.y = 120 startBtn = display.newImage('startBtn.png') startBtn.x = display.contentCenterX startBtn.y = display.contentCenterY + 20 --startBtn.name = 'startBtn' aboutBtn = display.newImage('aboutBtn.png') aboutBtn.x = display.contentCenterX aboutBtn.y = display.contentCenterY + 65 --aboutBtn.name = 'aboutBtn' titleView = display.newGroup() titleView:insert(titleBg) titleView:insert(title) titleView:insert(startBtn) titleView:insert(aboutBtn) startButtonListeners('add') end function startButtonListeners(action) if(action == 'add') then aboutBtn:addEventListener('tap', showCredits) startBtn:addEventListener('tap', showGameView) else aboutBtn:removeEventListener('tap', showCredits) startBtn:removeEventListener('tap', showGameView) end end function showCredits:tap() aboutBtn.isVisible = false startBtn.isVisible = false about = display.newImage('about.png') about.x = about.width * 0.474 about.y = display.contentHeight + about.height transition.to(about, {time = 300, y = display.contentHeight - about.height/2.4, onComplete = function() about:addEventListener('tap', hideCredits) end}) end function hideCredits() transition.to(about, {time = 300, y = display.contentHeight+about.height, onComplete = function() aboutBtn.isVisible = true startBtn.isVisible = true about:removeEventListener('tap', hideCredits) display.remove(about) about = nil end}) end function showGameView:tap() transition.to(titleView, {time = 300, y = -titleView.height, onComplete = function() display.remove(titleView) titleView = nil buildSoup() gameListeners('add') end}) end function gameListeners(action) if(action == 'add') then gameBg:addEventListener('touch', startDraw) gameBg:addEventListener('touch', detectLetters) else gameBg:removeEventListener('touch', startDraw) gameBg:removeEventListener('touch', detectLetters) end end function buildSoup() for i = 1, 10 do for j = 1, 12 do local tf = display.newText('', 0, 0, 'Arial', 19) tf:setTextColor(102, 102, 102) tf.width = 22 tf.height = 21 tf.x = math.floor(-10 + (31.3 * i)) tf.y = math.floor(-10 + (35 * j)) -- Change 0's to Random Letters if(L1Map[j][i] == 0) then L1Map[j][i] = alphabet[math.floor(math.random() * table.maxn(alphabet))+1] end tf.text = L1Map[j][i] tfs:insert(tf) end end -- Add Words List local wordsString = '' for i = 1, #L1 do wordsString = wordsString .. ' ' .. L1[i] end wordsList = display.newText(wordsString, 5, 430, 'Arial', 14) wordsList:setTextColor(238, 238, 238) currentWords = display.newText('', 5, 455, 'Arial', 14) currentWords:setTextColor(238, 146, 63) end function startDraw:touch(e) if(e.phase == 'began') then initX = e.x initY = e.y elseif(e.phase == 'ended') then line = display.newLine(initX, initY, e.x, e.y) line.width = 16 line:setColor(255, 142, 42, 60) lines:insert(line) end end
Next Time...
In the next and final part of the series, we'll handle the letter identification, display the words already found, and the final steps to take prior to release like app testing, creating a start screen, adding an icon and, finally, building the app. Stay tuned for the final part!
Comments