tech/game

21/07/13 TicTacToe - SOUND EFFECTS

tech-lover 2021. 7. 14. 01:48

https://youtu.be/NAy5IxhHbnU

https://docs.coronalabs.com/guide/media/audioSystem/index.html

 

Solar2D Documentation — Developer Guides | Graphics/Audio/Animation

Sound As stated earlier, the audio.loadSound() function loads an entire sound into memory. It should be used for shorter audio files that may be used repeatedly throughout the app. While you can load each sound into a local handle, it's often better to org

docs.coronalabs.com

 

- overlay.lua

```

local composer = require( "composer" )

 

local scene = composer.newScene()

 

print("scene-overlay")

 

-- -----------------------------------------------------------------------------------

-- Code outside of the scene event functions below will only be executed ONCE unless

-- the scene is removed entirely (not recycled) via "composer.removeScene()"

-- -----------------------------------------------------------------------------------

 

local btnPlay

local btnReview

 

local grpBg

local grpMain

local grpUI

 

local overlayBg

 

local sfxTap

 

-- -----------------------------------------------------------------------------------

-- Scene event functions

-- -----------------------------------------------------------------------------------

 

-- create()

function scene:create( event )

 

    local sceneGroup = self.view

    -- Code here runs when the scene is first created but has not yet appeared on screen

 

    print("overlay scene: create")

 

    grpBg = display.newGroup()

    sceneGroup:insert(grpBg)

    grpMain = display.newGroup()

    sceneGroup:insert(grpMain)

    grpUI = display.newGroup()

    sceneGroup:insert(grpUI)

 

    overlayBg = display.newRect( grpBg, 

    display.contentCenterX, display.contentCenterY, 7681024)

    overlayBg:setFillColor(0,0,0)

    overlayBg.alpha = 0.7



    --btnPlay = display.newImageRect( grpUI, "images/restart.png", 150, 150)

    btnPlay = display.newText( grpUI, "Restart"150150)

    btnPlay.x = display.contentCenterX

    btnPlay.y = display.contentCenterY - 30

    btnPlay.id = "Button Restart"

 

    --btnHelp = display.newImageRect( grpUI, "images/buttonHelp.png", 50, 50 )

    btnReview = display.newText( grpUI, "Review"5050 )

    btnReview.x = display.contentCenterX

    btnReview.y = display.contentCenterY + 300

    btnReview.id = "Button Review"

 

    sfxTap = audio.loadSound( "audio-tictactoe/tapSound.mp3" )

 

end

 

 

-- show()

function scene:show( event )

 

    local sceneGroup = self.view

    local phase = event.phase

 

    if ( phase == "will" ) then

        -- Code here runs when the scene is still off screen (but is about to come on screen)

        print("overlay scene: show-will")

    elseif ( phase == "did" ) then

        -- Code here runs when the scene is entirely on screen

        print("overlay scene: show-did")

 

        local function onBtnPlayTouch(event)

            print("onBtnPlayTouch")

 

            if (event.phase == "began"then

                print( "Touch event began on: " .. event.target.id )

 

                -- set touch focus

                display.getCurrentStage():setFocus( event.target )

 

                btnPlay.xScale = 0.95

                btnPlay.yScale = 0.95

 

                audio.play( sfxTap )

 

            elseif ( event.phase == "ended" ) then

 

                print( "Touch event ended on: " .. event.target.id )

 

                btnPlay.xScale = 1

                btnPlay.yScale = 1

 

                -- unset touch focus

                display.getCurrentStage():setFocus( nil )

 

                composer.gotoScene( "scenes-tictactoe.cutscene", { time=1000, effect="crossFade" })

 

            end

 

            return true

        

        end

        btnPlay:addEventListener("touch", onBtnPlayTouch)

 

        local function onBtnReviewTouch(event)

            print("onBtnReviewTouch")

 

            if ( event.phase == "began" ) then

                print( "Touch event began on: " .. event.target.id )

 

                -- set touch focus

                display.getCurrentStage():setFocus( event.target )

 

                btnReview.xScale = 0.9

                btnReview.yScale = 0.9

 

                overlayBg.isVisible = false

                btnPlay.isVisible = false

 

                audio.play( sfxTap )

 

            elseif ( event.phase == "ended" ) then

                print( "Touch event ended on: " .. event.target.id )

 

                overlayBg.isVisible = true

                btnPlay.isVisible = true

 

                btnReview.xScale = 1

                btnReview.yScale = 1

 

                -- unset touch focus

                display.getCurrentStage():setFocus( nil )

 

            end

            return true

 

        end

        btnReview:addEventListener("touch", onBtnReviewTouch)            



    end

end

 

 

-- hide()

function scene:hide( event )

 

    local sceneGroup = self.view

    local phase = event.phase

 

    if ( phase == "will" ) then

        -- Code here runs when the scene is on screen (but is about to go off screen)

        print("overlay scene: hide-will")

 

    elseif ( phase == "did" ) then

        -- Code here runs immediately after the scene goes entirely off screen

        print("overlay scene: hide-did")




    end

end

 

 

-- destroy()

function scene:destroy( event )

 

    local sceneGroup = self.view

    -- Code here runs prior to the removal of scene's view

 

    print("overlay scene: destroy")

    

end

 

 

-- -----------------------------------------------------------------------------------

-- Scene event function listeners

-- -----------------------------------------------------------------------------------

scene:addEventListener( "create", scene )

scene:addEventListener( "show", scene )

scene:addEventListener( "hide", scene )

scene:addEventListener( "destroy", scene )

-- -----------------------------------------------------------------------------------

 

return scene

```

 

- tictactoe.lua

```

local composer = require( "composer" )

local scene = composer.newScene()

 

-- -----------------------------------------------------------------------------------

-- Code outside of the scene event functions below will only be executed ONCE unless

-- the scene is removed entirely (not recycled) via "composer.removeScene()"

-- -----------------------------------------------------------------------------------

 

local grpBackground

local grpMain

local grpUI

 

local grpBoardBG

local grpBoardFG



local backgroundImage

local gridSquare

 

local imgLogo

local imgGameTitle

 

local arrayBoard = {}

 

local player1

local player2

local playersTurn = math.random(2)

 

local message

local messageOptions = {

    parent = grpUI,

    text = "Hello World",

    x = display.contentCenterX,

    y = display.contentCenterY-210,

    width = display.contentWidth - 20,

    font = "fonts-tictactoe/BradBunR.ttf",

    fontSize = 40,

    align = "center"

}

local switchMessage = true

 

local sfxSuccess

local sfxButton

 

local optionsZeros = 

{

    text = "O",

    x = display.contentCenterX,

    y = display.contentCenterY,

    -- font = native.systemFont,

    font = "fonts-tictactoe/BradBunR.ttf",

    fontSize = 120,

    align = "center"  -- Alignment parameter

}

 

local optionsCrosses = 

{

    text = "X",

    x = display.contentCenterX,

    y = display.contentCenterY,

    font = "fonts-tictactoe/BradBunR.ttf",

    fontSize = 120,

    align = "center"

}

 

local overlayOptions = {

    isModal = true,

    effect = "fade",

    time = 400,

    text = "xxx"

}

 

-- -----------------------------------------------------------------------------------

-- Scene event functions

-- -----------------------------------------------------------------------------------

 

-- create()

function scene:create( event )

 

    local sceneGroup = self.view

    -- Code here runs when the scene is first created but has not yet appeared on screen

 

    grpBackground = display.newGroup()  

    grpMain = display.newGroup()   

    grpUI = display.newGroup() 

 

    sceneGroup:insert(grpBackground)

    sceneGroup:insert(grpMain)

    sceneGroup:insert(grpUI)

 

    grpBoardBG = display.newGroup() 

    grpBoardFG = display.newGroup() 

    grpMain:insert(grpBoardBG)

    grpBoardBG:insert(grpBoardFG)

 

    grpBoardFG:toBack()

    grpBoardFG:toFront()

 

    backgroundImage = display.newImageRect(grpBackground, "images-tictactoe/background-orange.jpg"7681024)

    backgroundImage.x = display.contentCenterX

    backgroundImage.y = display.contentCenterY

 

    local gridBoarder = display.newRect(grpBoardBG, display.contentCenterX, display.contentCenterY, 300300)

    gridBoarder.alpha = 0.5

    gridBoarder:toBack()

    gridBoarder:setFillColor(1110.1)

    gridBoarder.strokeWidth = 10

    gridBoarder:setStrokeColor(00.50.5)

 

    local imgLogo = display.newImageRect(grpMain, "images-tictactoe/logo.png"

    7070)

    imgLogo.x = display.contentCenterX - 130

    imgLogo.y = display.contentCenterY - 300

    imgLogo:rotate(-10)

    imgLogo:setFillColor(0.50.51)

 

    local imgGameTitle = display.newImageRect(grpMain, "images-tictactoe/game-studio.png"1000/5358/5)

    imgGameTitle.x = display.contentCenterX + 10

    imgGameTitle.y = display.contentCenterY - 300

    imgGameTitle:setFillColor(0.511)

 

    message = display.newText(messageOptions)

 

    player1 = display.newText(messageOptions)

    player1.playerNum = 1

    player1.character = "zeros"

    player1.name = "Player 1"

    player1.isVisible = false

 

    player2 = display.newText(messageOptions)

    player2.playerNum = 2

    player2.character = "crosses"

    player2.name = "Player 2"

    player2.isVisible = false

 

    sfxSuccess = audio.loadSound( "audio-tictactoe/winSound.mp3" )

    sfxButton = audio.loadSound( "audio-tictactoe/buttonSound.mp3" )

 

end

 

 

-- show()

function scene:show( event )

 

    local sceneGroup = self.view

    local phase = event.phase

 

    print("tictactoe : scene show")

 

    if ( phase == "will" ) then

        -- Code here runs when the scene is still off screen (but is about to come on screen)



        local counterSquareNumber = 1

        local function drawSquare(xPosIn, yPosIn)

            print("sqaure")

            gridSquare = display.newRect(grpBoardBG, xPosIn, yPosIn, 100100)

            gridSquare.strokeWidth = 3

            gridSquare:setStrokeColor( 000)

            gridSquare.isVisible = true

            gridSquare:toBack() 

            gridSquare.number = counterSquareNumber

            gridSquare.status = "EMPTY"

            table.insert( arrayBoard, counterSquareNumber, gridSquare)

 

            counterSquareNumber = counterSquareNumber + 1

 

        end



        local function drawRow(xPosIn, yPosIn) 

            print("drawRow()")

 

            local numCols = 3

            local xPos = xPosIn

            local yPos = yPosIn

 

            for count=1, numCols, 1 do

                print("for loop")

 

                drawSquare(xPos, yPos)

                xPos = xPos + 100



            end

 

        end

 

        local function drawGrid(xPosIn, yPosIn)

            print("drawGrid()")

 

            local numRows = 3

            local xPos = xPosIn

            local yPos = yPosIn

 

            for count=1, numRows, 1 do

            

                print("for loop rows")

                drawRow(xPos, yPos)

                yPos = yPos + 100

 

            end

 

        end

 

        -- Starting box coordinates (top left box 1)

        local xPos = display.contentCenterX - 100

        local yPos = display.contentCenterY - 100

        drawGrid(xPos, yPos)

 

        grpBoardBG.y = grpBoardBG.y + 20

 

        message.text = "It's Player " .. playersTurn .. "'s Turn"

 

    elseif ( phase == "did" ) then

        -- Code here runs when the scene is entirely on screen

 

        local function drawZeros(xPosIn, yPosIn)

                

            local charZeros = display.newText( optionsZeros )

            grpBoardFG:insert(charZeros)

            charZeros:setFillColor( 10.20.1 )

            charZeros.isVisible = true

            charZeros:toFront()

            charZeros.x = xPosIn

            charZeros.y = yPosIn -5

        end

    

        local function drawCrosses(xPosIn, yPosIn)

            local charCrosses = display.newText( optionsCrosses )

            grpBoardFG:insert(charCrosses)

            charCrosses:setFillColor( 0.10.51 )

            charCrosses.isVisible = true        

            charCrosses:toFront()

            charCrosses.x = xPosIn

            charCrosses.y = yPosIn -5

        end

 

        local function drawWinningLine(startX, startY, endX, endY)

            print("drawWinningLine")

            local line = display.newLine(grpBoardFG, startX, startY, endX, endY)

            line:setStrokeColor(0000.5)

            line.strokeWidth = 30

            line:toFront()

 

            switchMessage = false  -- for message text change

            audio.play( sfxSuccess )

            message.text = "WINNER!!"

            composer.showOverlay( "scenes-tictactoe.overlay", overlayOptions)

 

            return true

        end

 

        local function checkWinLoseDraw(characterIn)

            print("checkWinLoseDraw: "..tostring(characterIn))

 

            local numEmptySquares = 9

            local result = false

 

            local obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9

 

            for index, object in ipairs (arrayBoard) do

 

                print("["..index.."]"..object.number, object.status)

 

                local function checkStatus(statusIn)

                    if statusIn ~= "EMPTY" then

                        numEmptySquares = numEmptySquares - 1

                        print("numEmptySquares: "..numEmptySquares)

                    else

                        -- do nothing

                    end

                end

 

                if object.number == 1 then obj1 = object checkStatus(object.status)

                elseif object.number == 2 then obj2 = object checkStatus(object.status)

                elseif object.number == 3 then obj3 = object checkStatus(object.status)

                elseif object.number == 4 then obj4 = object checkStatus(object.status)

                elseif object.number == 5 then obj5 = object checkStatus(object.status)

                elseif object.number == 6 then obj6 = object checkStatus(object.status)

                elseif object.number == 7 then obj7 = object checkStatus(object.status)

                elseif object.number == 8 then obj8 = object checkStatus(object.status)

                elseif object.number == 9 then obj9 = object checkStatus(object.status)

                else

                    -- error

                end

            end

 

            -- horizontal pattern 3 x mathing characters

            --H1

            if (characterIn == obj1.status) and (characterIn == obj2.status) and (characterIn == obj3.status) then

                print("winning line H1")

                result = drawWinningLine(obj1.x, obj1.y, obj3.x, obj3.y)

            --H2

            elseif (characterIn == obj4.status) and (characterIn == obj5.status) and (characterIn == obj6.status) then

                print("winning line H1")     

                result = drawWinningLine(obj4.x, obj4.y, obj6.x, obj6.y)

       

            --H3

            elseif (characterIn == obj7.status) and (characterIn == obj8.status) and (characterIn == obj9.status) then

                print("winning line H1")

                result = drawWinningLine(obj7.x, obj7.y, obj9.x, obj9.y)

 

            end            



            -- vertical patterns 3 x matching characters

            --V1

            if (characterIn == obj1.status) and (characterIn == obj4.status) and (characterIn == obj7.status) then

                print("winning line V1")

                result = drawWinningLine(obj1.x, obj1.y, obj7.x, obj7.y)

            --V2                

            elseif (characterIn == obj2.status) and (characterIn == obj5.status) and (characterIn == obj8.status) then

                print("winning line V2")            

                result = drawWinningLine(obj2.x, obj2.y, obj8.x, obj8.y)

            --V2

            elseif (characterIn == obj3.status) and (characterIn == obj6.status) and (characterIn == obj9.status) then

                print("winning line V3")

                result = drawWinningLine(obj3.x, obj3.y, obj9.x, obj9.y)

            end       

 

            -- diagonal patterns 3 x matching characters

            --D1

            if (characterIn == obj1.status) and (characterIn == obj5.status) and (characterIn == obj9.status) then

                print("winning line D1")

                result = drawWinningLine(obj1.x, obj1.y, obj9.x, obj9.y)            

            --D2

            elseif (characterIn == obj3.status) and (characterIn == obj5.status) and (characterIn == obj7.status) then

                print("winning line D2")

                result = drawWinningLine(obj3.x, obj3.y, obj7.x, obj7.y)

            end        

            

            print(result)

            if (result == false) and (numEmptySquares == 0then

                print("DRAW")

 

                switchMessage = false  -- for message text change

                message.text = "Ut Oh, It's a Draw!!"

                composer.showOverlay( "scenes-tictactoe.overlay", overlayOptions)

            end

 

        end

        

        local function whichSquareTapped(event)

            print("square number is: " .. event.target.number)

            print("playersTurn ".. playersTurn)

 

            local xPos = event.target.x

            local yPos = event.target.y

 

            local function updateSquareStatus(inCharacter)

                print("updateSquareStatus")

                local character = tostring(inCharacter)

                for index, object in ipairs (arrayBoard) do

                    if object.number == event.target.number then

                        print("match")

                        print("object.status: "..object.status)

 

                        if object.status == "EMPTY" then

                            object.status = character

                            if character == "zeros" then

                                drawZeros(xPos, yPos)

                                checkWinLoseDraw(character)

                                playersTurn = 2

 

                                if switchMessage == true then

                                    message.text = "It's Player " .. playersTurn .. "'s Turn"

                                else  -- do nothing

                                end

 

                            elseif character == "crosses" then

                                drawCrosses(xPos, yPos)

                                checkWinLoseDraw(character)

                                playersTurn = 1

 

                                if switchMessage == true then

                                    message.text = "It's Player " .. playersTurn .. "'s Turn"                               

                                else  -- do nothing

                                end

                            end

                        elseif object.status ~= "EMPTY" then

                            message.text = "Choose Another"

                        else

                            message.text = "???"

                        end

 

                    else

                        -- print("non match")

                    end

                    print("["..index.."]"..object.number, object.status)

                end

                character = nil

            end



            audio.play( sfxButton )

 

            if playersTurn == player1.playerNum then

                print("player1.playerNum ".. player1.playerNum)

                print("player1.character ".. player1.character)

 

                updateSquareStatus(player1.character)

 

            elseif playersTurn == player2.playerNum then

                print("player2.playerNum ".. player2.playerNum)

                print("player2.character ".. player2.character)

 

                updateSquareStatus(player2.character)

 

            else

                -- error do nothing

            end




        end

 

        for index, value in ipairs(arrayBoard) do

            local objSquare = value

 

            print("[" .. index .. "] " .. objSquare.number)

            objSquare:addEventListener("tap", whichSquareTapped)

 

        end



    end

end

 

 

-- hide()

function scene:hide( event )

 

    local sceneGroup = self.view

    local phase = event.phase

 

    print("tictactoe : scene hide")

 

    if ( phase == "will" ) then

        -- Code here runs when the scene is on screen (but is about to go off screen)

        message.isVisible = false

 

    elseif ( phase == "did" ) then

        -- Code here runs immediately after the scene goes entirely off screen

 

        message = nil

        composer.removeScene( "tictactoe" )

    end

end

 

 

-- destroy()

function scene:destroy( event )

 

    local sceneGroup = self.view

    -- Code here runs prior to the removal of scene's view

 

end

 

 

-- -----------------------------------------------------------------------------------

-- Scene event function listeners

-- -----------------------------------------------------------------------------------

scene:addEventListener( "create", scene )

scene:addEventListener( "show", scene )

scene:addEventListener( "hide", scene )

scene:addEventListener( "destroy", scene )

-- -----------------------------------------------------------------------------------

 

return scene

```