high score class

I’ve seen several questions posted about how to handle high scores for games. Here’s something I started awhile back, but just got around to completing. Anytime your game ends and you want to save the score, this asks for your initials (1-3 characters), then updates the score and shows the 10 high scores in descending order. It then waits for a double tap before restarting the game. There are 2 starting options. One option shows the high score list before starting the game. The other starts the game without showing the high scores first. There is also an option to clear the high score list. That’s just a matter of uncommenting a line of code, starting the game, stopping the game, and re-commenting the line. I tried to find all the bugs, but if you find any let me know and I’ll update the code for others. I didn’t try to write this to cover all the different things everyone might want, so if it doesn’t do what you want (colors, font, font size, etc. ), you can change it to fit your needs. This is just basic code, nothing fancy. The scores are saved in LocalData and read back in anytime you reload the game. I also included a fake game to demo the highScore routine and to show how you might implement this with an existing game. The fake game just increments the score until you slide the sprite over the center dot (not much of a challenge). That should give you an easy ways to see how the highScore routine works.


displayMode(FULLSCREEN)

function setup()    
    --highScore:clear()    -- uncomment to clear high score list
    
    -- start the game before showing the highscore list
    --hs=highScore(0)       -- create an instance of highscore
    --gameOver=false
    
    -- show the highscore list before starting the game
    hs=highScore(1)        -- create an instance of highscore
    gameOver=true

    score=0
    if isKeyboardShowing() then
        hideKeyboard()
    end
end

function draw()
    background(40, 40, 50)
    textMode(CENTER)
    fill(255)    
    if gameOver then
        if hs.scoreDone then    -- done updating the score
            hs.scoreDone=false   -- set to false   
            score=0            -- reset score for next game
            gameOver=false    -- allow next game to start
        else
            hs:scoreRoutine(score)    -- update current score
        end
    else
        playGame()    -- play the game
    end
end

function playGame()    -- just a fake game to demo highscore
    text("SCORE  "..score,WIDTH/2,HEIGHT-50)
    text("Last High Score"..hs.currHS,WIDTH/2,HEIGHT-75)
    text("Slide sprite over dot to demo highscore.",WIDTH/2,HEIGHT/2+100)
    if not gameOver then
        score=score+50
        ellipse(WIDTH/2,HEIGHT/2,30)
        sprite("Planet Cute:Character Boy",CurrentTouch.x,CurrentTouch.y)
        v1=vec2(CurrentTouch.x,CurrentTouch.y)
        d=v1:dist(vec2(WIDTH/2,HEIGHT/2))
        if d<30 then
            gameOver=true
        end
    end 
end

function touched(t)
    hs:touched(t)    -- call the highscore touched routine
end

function keyboard(k)
    hs:keyboard(k)    -- call the highscore keyboard routine
end



highScore = class()

function highScore:init(type)    -- initialize variables
    self.tab={}
    self.name="Put Your Game Name Here"
    self.count=0 
    self.score=0
    self.str=""    
    if type==1 then
        -- 1st time, don't ask for initials, then show highscore
        self.getInitials=false
        self.readS=true
        self.shown=true
    else 
        -- 1st time, ask for initials, then show highscore       
        self.getInitials=true
        self.readS=false
        self.showS=false
    end    
    self.currHS=""
    self.scoreDone=false
    self:scoreRoutine(0)
end

function highScore:scoreRoutine(score)    -- run routines
    if self.getInitials then
        if self.score==0 then
            self.score=score
        end
        self:initials()
    end
    if self.readS then
        self:readScore()
    end
    if self.showS then
        self:showScore()
    end
end

function highScore:clear()    -- clear highscores
    clearLocalData()
end

function highScore:touched(t)
    if t.state==BEGAN and t.tapCount==2 and -- start next game
            not self.scoreDone and self.score==0 then
        self.getInitials=true
        self.readS=false
        self.showS=false
        self.str=""
        self.count=0
        self.scoreDone=true
    end
end

function highScore:initials()    -- initials prompt
    pushStyle()
    fontSize(25)
    fill(23, 198, 133, 255)
    text("Current score   "..self.score,WIDTH/2,HEIGHT-50)
    text("Enter your initials (max 3)",WIDTH/2,HEIGHT-100)
    text("then press return",WIDTH/2,HEIGHT-130)
    text("GAME OVER",WIDTH/2,HEIGHT-300)
    rectMode(CENTER)
    stroke(255)
    strokeWidth(3)
    noFill()
    rect(WIDTH/2,HEIGHT-200,100,50)
    fill(255)
    text(self.str,WIDTH/2,HEIGHT-200)
    if not isKeyboardShowing() then
        showKeyboard()
        self.count=0
        self.str=""
    end 
    popStyle()
end

function highScore:keyboard(k)    -- get initials
    if k==RETURN then
        if self.str~="" and string.sub(self.str,1,1)~=" " then
            self.str=self.str .. "   "
            self.str=string.sub(self.str,1,3)
            self:update()
            self.str=""
            self.count=0
            self.readS=true
            self.getInitials=false
            hideKeyboard()
        else
            self.str=""
            self.count=0
        end
        return
    end
    self.count=self.count+1
    if k==BACKSPACE then
        self.str=string.sub(self.str,1,string.len(self.str)-1)
        self.count=string.len(self.str)
    elseif self.count<4 then
        self.str=self.str..k
    end
    self.str=string.upper(self.str)
end

function highScore:readScore()    -- read existing highscores
    self.tab={}
    local t=listLocalData()
    if #t==0 then    -- no scores, create empty list
        for z=1,10 do
            local str=string.format("...%02d",z)
            saveLocalData(str,0)
        end
        t=listLocalData()
    end
    for a,b in ipairs(t) do
        local v=readLocalData(b)
        self.str=string.format("%6d - %s",v,b)
        table.insert(self.tab,self.str)
    end
    self.str=""
    table.sort(self.tab,function(a,b) return a>b end) -- sort high to low
    local off=string.find(self.tab[1],"-")
    self.currHS=string.sub(self.tab[1],1,off-2)
    self.showS=true
end

function highScore:showScore()    -- show scores
    pushStyle()
    background(31, 57, 62, 255)
    fontSize(40)
    font("Courier-Bold")
    fill(245, 255, 0, 255)
    text(self.name,WIDTH/2,HEIGHT-100)
    fill(255, 127, 0, 255)
    text("High Scores",WIDTH/2,HEIGHT-180)
    fontSize(25)
    for a,b in ipairs(self.tab) do
        if a>10 then    -- remove lowest scores
            local off=string.find(b,"-")
            local init=string.sub(b,off+2,string.len(b))
            saveLocalData(init,nil)
        else
            fill(24, 134, 246, 255)
            self.str=string.format("%s  %2d",string.sub(b,1,string.len(b)-2),a)
            text(self.str,WIDTH/2,HEIGHT-200-a*25)
        end
    end
    fill(0, 255, 0, 255)
    text("Double tap screen to start game.",WIDTH/2,HEIGHT-600)
    popStyle()
end

function highScore:update()    -- update highscore list
    for z=1,10 do
        local str=string.format("%s%02d",self.str,z)
        local scr=readLocalData(str)
        if scr==nil then
            saveLocalData(str,self.score)
            break
        end
        if self.score>=scr then
            saveLocalData(str,self.score)
            self.score=scr
        end
    end
    self.score=0
end

How would you insert that into your own code

@abrown18 Read the comments in setup(), draw(), touched(), and keyboard(). I can’t tell you how to put this in your code because I don’t know what you code looks like. All I can say is when your game ends, you would call the scoreRoutine(score) with the score you want to save. The draw() function has 2 areas, updating the score or playing the game. Reading the comments should give you what you need. If you still have questions, just ask.