alert() help

The alert that pops up when state = GAME_DEAD flashes and wont stop, Its probably a simple fix, i just cant see it.

Code:




supportedOrientations(LANDSCAPE_ANY)
displayMode(FULLSCREEN)

function setup()
    parameter.watch("Lives")
    parameter.text("Console","",callBack)
    Lives = 3
    GAME_PLAYING = 0
    GAME_DEAD = 1
    GAME_PAUSED = 2
    state = GAME_DEAD
    objectTable = {}
    lastGenerated = ElapsedTime
    interval = .12
    num = 5  
    table.insert(objectTable,Objects(math.random(1,WIDTH-1),math.random(1,4),num))
    pColor = color(0, 0, 0, 255)
    paddle = Paddle(WIDTH/2,5,80,15,pColor)

end

function draw()
    spriteMode(CENTER)
    sprite("SpaceCute:Background",WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
    pushStyle()    
    fill(0, 0, 0, 255)
    textMode(CENTER)
    textAlign(CENTER)
    font("Copperplate-Light")
    fontSize(30)
    text("Tap Twice To Begin.", 500,250)
    text("Version 1.0.0",500,750)
    text("Made By: Austin W./CodeaNoob",500,30)
    text("Made Entirely in Codea!",500,60)
    fontSize(50)
    text("Tilt Island!", 500, 600)
    fontSize(40)
    text("Tilt the device to dodge the falling objects!", 500, 500)
    if state == GAME_PLAYING then
        spriteMode(CENTER)
        sprite("SpaceCute:Background",WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
        pushStyle()
        randomObjectGenerate()   
        popStyle()       
        score = ElapsedTime 
        fill(255)
        font("Futura-CondensedExtraBold")
        fontSize(30)
        textMode(CORNER)
        score = ElapsedTime - start
        fill(255, 255, 255, 255)
        text("Score: "..string.format("%.1f",score),10,HEIGHT-50)
        text("Lives: "..Lives,900,HEIGHT-50)
    end
    if state==GAME_OVER then
        fill(255)
        text("Score: "..string.format("%.1f",score),WIDTH/2,400)
        alert("Nice job getting "..score.."!","Nice!")
    end
    
    drawPaddle()
end

function randomObjectGenerate()
    for k,v in pairs(objectTable) do 
        v:draw()    
    end
    if ElapsedTime - lastGenerated > interval then
        lastGenerated = ElapsedTime
        num = num + 1
        table.insert(objectTable,Objects(math.random(1,WIDTH-1),math.random(1,4),num))  
    end
    for k,v in pairs(objectTable) do 
        if paddle:collide(v.a.x,v.a.y) and v.a.info.id > 0 then
            sound(SOUND_HIT, 46295)
            v.a.info.id=0
            Lives=Lives-1
            if Lives<1 then
                state=GAME_OVER
            end
        end
        if v.a.y < 0 or (v.a.x > WIDTH or v.a.x< 0) or v.a.info.id == 0 then
            table.remove(objectTable,k)
            v.a:destroy()
            v.a = nil
            v=nil
       end
    end
end

function drawPaddle()
    paddle:draw()
end

function touched(touch)
    if touch.tapCount == 2 and touch.state == ENDED then
        state = GAME_PLAYING
        if touch.tapCount == 2 and touch.state == ENDED then
            start = ElapsedTime
            Lives=3
        end
       if touch.tapCount == 2 and touch.state == ENDED and state == GAME_DEAD then
        alert("Score: "..score,"Score")
    end
end
end

--The Paddle Tab

Paddle = class()

function Paddle:init(posx,posy,pWidth,pHeight,pColor)
    self.pWidth = pWidth
    self.pHeight = pHeight
    self.posx = posx
    self.posy = posy
    pos = vec2(posx,posy)
    size = vec2(pWidth,pHeight)
    self.pColor = pColor
end

function Paddle:draw()
    checkGrav()
    fill(pColor)   
    rect(pos.x,pos.y,self.pWidth,self.pHeight)
end

function Paddle:collide(x,y)
    if x>pos.x and x<pos.x+self.pWidth and y>self.posy and y<self.posy+self.pHeight*2 then
        return true
    end
    return false
end

--This Function checks the Gravity
function checkGrav()
    if pos.x >= 0 and pos.x <= WIDTH - size.x then
        if Gravity.x > 0 then
            pos.x = pos.x + (20 * Gravity.x)
        end  
        if Gravity.x < 0 then
            pos.x = pos.x - (-20 * Gravity.x)
        end    
    end 
    if pos.x < 0 then
        pos.x = 0
    end
    if pos.x > WIDTH - size.x then
        pos.x = WIDTH - size.x
    end
end

--The Object Tab

Objects = class()

function Objects:init(x,cat,id)
    self.a = physics.body(CIRCLE,20)
    self.a.x = x
    self.a.y = HEIGHT
    self.a.gravityScale = 1
    self.a.restitution = 0.0
    self.a.interpolate = true
    self.asleepingAllowed = true
    self.flag = true
    self.category = cat
    self.a.info = {}
    self.a.info.id = id
end

function Objects:draw()
    pushMatrix()
    translate(self.a.x, self.a.y)
    if self.category == 1 then
        sprite("Planet Cute:Rock",0,0,50,88)
    elseif self.category == 2 then
        sprite("Small World:Rock",0,0,50,51)
    elseif self.category == 3 then
        sprite("Planet Cute:Brown Block",0,0,50,80)
    elseif self.category == 4 then
        sprite("Planet Cute:Plain Block",0,0,50,85)         
    end
    popMatrix()
end  
 
function Objects:touched(t)
    if t.tapCount == 1 and t.state == ENDED then
        print("Hit!")
end
end


  



-- add this function anywhere in your code

function showHighScore()
    pushStyle()
    fill(255)
    fontSize(40)
    font("Courier")
    hs=score
    for x=1,10 do
        str=string.format("TiltIsland%02d",x)
        sc=readLocalData(str)
        if sc==nil then
            saveLocalData(str,0)
            if hs>0 then
                saveLocalData(str,hs)
                hs=0
            end
        elseif hs==tonumber(sc) then
                break
        elseif hs>tonumber(sc) then
                saveLocalData(str,hs)
                hs=tonumber(sc)
        end
    end    
    for x=1,10 do
        str=string.format("TiltIsland%02d",x)
        sc=readLocalData(str) 
        str=string.format("%2d) %5.1f",x,sc)
        text(str,WIDTH-200,500-x*40)
    end
    popStyle()
end
function callBack()
    if Console == "Dumbwaytodie" then
        close()
        end
    if Console == "Lives" then
        Lives = math.huge
        end
        if Console == "Easy" then
            interval = 1
            end
            if Console == "Regular" then
                interval = .16
                end
                if Console == "Hard" then
                    interval = .1
                    end
                    if Console == "help" then
                        print("Lives = Infinite Lives")
                        print("Easy = Easy difficulty")
end
end

I’ve not used the alert so this is speculation: you are calling alert in every draw cycle once you are in GAME_DEAD state. I suspect that you should call it once when the game state changes and then not again.

I would consider having a function change_state that got called when you wanted to change state. This could run some tear-down and build-up code that was needed when changing state:

function change_state(new_state)
    if new_state == state then
        return
    end
    tear_down(state)
    state = new_state
    build_up(state)
end

where tear_down and build_up do something to clean up and initialise stuff depending on their state. Obviously, this can get more complicated.

I think your problem is the GAME_OVER state, and the code in draw() that pops up an alert. It is going to keep doing this each time Codea draws, 60 times a second. You can avoid this by (say) creating a new variable Notify = false when you set state to GAME_OVER, and then in draw, after putting the score on the screen, you only put up an alert if it is false (and if it is false, you show the alert, then set Notify=true so it won’t happen again)

By the way, your code in the touched function is very repetitive. You do the same check for number of touches and state three times. This is like saying

if X then  
    state = ...  
    if X then  
        lives = ...  
        if X and Y then ....

all you need to write is

if X then
    state = ...  
    lives = ...  
    if Y then ....

@CodeaNoob as @Ignatz says your issue comes from your state variable.

At the start you define possible states, but GAME_OVER isn’t one of them. GAME_DEAD is.
When you assign state to GAME_OVER you are actually assigning it to nil because GAME_OVER isn’t defined as a constant.

Defining

GAME_OVER=3

and adjusting the code around line 60 so alert is only called once will give you a quick fix

    if state==GAME_OVER then
        fill(255)
        text("Score: "..string.format("%.1f",score),WIDTH/2,400)
        alert("Nice job getting "..score.."!","Nice!")
        state=GAME_DEAD
    end

For clarity I would suggest more descriptive names. Maybe change GAME_DEAD to MENU

Also, as @Ignatz says your touch function could do with tidying up.

The following if statement will never be true because you set state to GAME_PLAYING just before.

       if touch.tapCount == 2 and touch.state == ENDED and state == GAME_DEAD then

You might be able to see this better by removing the extra redundant tests in the if statements

function touched(touch)
    if touch.tapCount == 2 and touch.state == ENDED then
        state = GAME_PLAYING
        start = ElapsedTime
        Lives=3
        if state == GAME_DEAD then
            alert("Score: "..score,"Score")
        end
    end
end