Search code examples
androidluasdkcoronasdkscene

Using scores between scenes Corona SDK


I have two scenes: the game.lua file and a restart.lua file. Once the game.lua file ends it transfers to the restart screen. On the restart screen I have 'your current score:' and 'your highscore:' along with the values. However, the values don't update themselves after each subsequent restart. The highscore won't update until I restart the app and the current score won't reset to zero until I restart the app.

So for example: i)Say my current highscore is 21. I play the game once and achieve a new highscore: 23. My current score goes to 23 but my highscore is still 21 (until I restart the app).

ii)I play again(without restarting the app) and get a score of 5. The restart screen still shows 23 as my current score.

So basically once I play the game once, all scores are stuck.

In the app I am using the ego module to save highscore(as that would have to be permanent) and have my current score set as global.

Here is the code in my game scene:

    highscore = loadFile("score.txt")--the ego module loads this file for me

    score = 0--kept global to use in restart screen
    local scoreText = display.newText(score,W,0)--create text
    sceneGroup:insert(scoreText)



    local function checkForFile()
        if highscore == "empty" then
            highscore = 0--gives highscore number if file is empty
            saveFile("score.txt", highscore)--saves new highscore
        end
    end 
    checkForFile()

    local function onObjectTouch(event)
        if(event.phase == "began") then
            score = score+1--increment score on touch
            scoreText.text = score

            if score>tonumber(highscore) then
            saveFile("score.txt",score)--if new highscore, save score as            highscore
        end

            vertical = -150--set ball's velocity
            ball:setLinearVelocity(0,vertical)
            print(ball.x .. " " .. event.x)
        end
    end

    Runtime:addEventListener("touch", onObjectTouch)

And here is the code in my restart scene

------------highScore Text----------------

myscore = loadFile("score.txt")--load highscore file

local highscoretext = display.newText( "Your high score:"..myscore, 0, 0, native.systemFontBold, 20 )
highscoretext:setFillColor(1.00, .502, .165)
--center the title
highscoretext.x, highscoretext.y = display.contentWidth/2, 200
--insert into scenegroup
sceneGroup:insert( highscoretext )  



--------------yourscore----------------
local yourscoretext = display.newText( "Your score:"..score, 0, 0, native.systemFontBold, 20 )
yourscoretext:setFillColor(1.00, .502, .165)
--center the title
yourscoretext.x, yourscoretext.y = display.contentWidth/2, 230
--insert into scenegroup
sceneGroup:insert( yourscoretext ) 

Solution

  • Your code seems a little bit confusing because you are using score, highscore and myscore but lets try and fix this. I will explain the three methods briefly but we will only try out two of them:

      1. Global Score and High Score variables
      1. Game.lua file
      1. Pass paremeters between the scenes

    1. Global Score and High Score variables

    This is the method that you are using now and I would not recommend to use global variables if you don't need to so let's skip this method and check out the other two.


    2. Game.lua file

    In this method we will use a designated game.lua file that will store all the data. Please read this blog post from Corona on how Modular Classes works in Lua: https://coronalabs.com/blog/2011/09/29/tutorial-modular-classes-in-corona/

    We will not use meta tables in this example but we'll create a game.lua file that we can call from any other lua or scene file in our Corona project. This will enable us to save the Score and High Score in only one place and also be able to save and load the High Score very easily. So let's create the game.lua file:

    local game = {}
    
    -- File path to the score file 
    local score_file_path = system.pathForFile( "score.txt", system.DocumentsDirectory )
    local current_score = 0
    local high_score = 0
    
    -----------------------------
    -- PRIVATE FUNCTIONS
    -----------------------------
    local function setHighScore()
        if current_score > high_score then
            high_score = current_score
        end
    end
    
    local function saveHighScore()
        -- Open the file handle
        local file, errorString = io.open( score_file_path, "w" )
    
        if not file then
            -- Error occurred; output the cause
            print( "File error: " .. errorString )
        else
            -- Write data to file
            file:write( high_score )
            -- Close the file handle
            io.close( file )
            print("High score saved!")
        end
    
        file = nil
    end
    
    local function loadHighScore()
        -- Open the file handle
        local file, errorString = io.open( score_file_path, "r" )
    
        if not file then
            -- Error occurred; output the cause
            print( "File error: " .. errorString )
        else
            -- Read data from file
            local contents = file:read( "*a" )
            -- Set game.high_score as the content of the file
            high_score = tonumber( contents )
            print( "Loaded High Score: ", high_score )
            -- Close the file handle
            io.close( file )
        end
    
        file = nil
    end
    
    -----------------------------
    -- PUBLIC FUNCTIONS
    -----------------------------
    function game.new()
    end
    
    -- *** NOTE ***
    -- save() and load() doesn't check if the file exists!
    function game.save()
        saveHighScore()
    end
    
    function game.load()
        loadHighScore()
    end
    
    function game.setScore( val )
        current_score = val
        setHighScore()
    end
    
    function game.addToScore( val )
        current_score = current_score + val 
        print("Current score", current_score)
        setHighScore()
    end
    
    function game.returnScore()
        return current_score
    end
    
    function game.returnHighScore()
        return high_score
    end
    
    return game
    

    In your scene file call game.lua like this (at the top of the scene):

    local game = require( "game" )
    

    and you'll be able to call the different game methods when needed like this:

    game.load()
    print("Current Score: ", game.returnScore())
    print("High Score: ", game.returnHighScore())
    game.setScore( game.returnHighScore() + 5 )
    game.save()
    

    The code snippet above:

    • Loads the High Score from the file
    • Print out the Current Score
    • Print out the High Score
    • Sets the Current Score to the current High Score + 5
    • Saves the High Score back to the file

    Because we set the Current Score to High Score + 5 we will see that change when we restart the Corona Simulator.


    3. Pass paremeters between the scenes

    When you are switching scene using composer.gotoScene you can also add parameters like this:

    local options =
    {
        effect = "fade",
        time = 400,
        params =
        {
            score = 125
        }
    }
    
    composer.gotoScene( "my_scene", options )
    

    and access them like this in the called scene:

    function scene:create( event )
        local sceneGroup = self.view
        print("scene:create(): Score: ", event.params.score )
    end
    
    
    -- "scene:show()"
    function scene:show( event )
        local sceneGroup = self.view
        local phase = event.phase
    
        print("scene:show(): Score: ", event.params.score )
    end
    

    Documentation about this method: https://coronalabs.com/blog/2012/04/27/scene-overlays-and-parameter-passing/