Help with score..

Hello,
I’m a beginner with using lua and codea. The code shown below is a game that I made(with random images so you can view it) and I am having trouble with the score. As you will see, as the star passes through the little “people” the score counts a point 60 times per second, not just once as I would like it to. The intention of the game is to create the different “people” to be worth different amounts (so some would add to the score and some take away from score), but I do not want the score to go crazy when doing so. Is there a way of doing this? My attempt to fix this was to make a new function so that it would not be in the draw function. Any suggestions would be much appreciated!

– Final Project

function setup()  
    B={}
    displayMode=(FULLSCREEN)
    fish=readImage("SpaceCute:Star")
    fishx=200
    fishy=350
    fishspeed=0
    fishw=100
    fishh=60
    
    jellyfish=readImage("Planet Cute:Character Cat Girl")
    dolphin=readImage("Planet Cute:Character Horn Girl")
    crab=readImage("Planet Cute:Character Princess Girl")
    octopus=readImage("Planet Cute:Character Pink Girl")
    
    gamestate="start"
    fishFrequency=1
    collision=1
    timer=0
    score=1
    NewFish()
    One()
    Two()
    Three()
    Four()
end
function NewFish()
    b={}--a table to hold information about pipes
    b.w=150
    b.h=150
    b.x=750
    b.r=75--"radius"
    b.y=math.random(100,700)
    b.s=5--speed pixels per second
    b.g=100
    b.rsc=math.random(1,4)--randomly decides which sea creature comes on screen
    table.insert(B,b)--add to our table of balloons  
end

function draw()
    
if gamestate=="start" then
    background(0, 36, 255, 255)
    fill(246, 245, 245, 255)
    font("AmericanTypewriter")
    fontSize(45)
    text ("Tap to start Game!", WIDTH/2,HEIGHT/2)
    fontSize(20)
    text("Directions: GET the octopus and dolphin, AVOID the jellyfish and crab!", WIDTH/2,HEIGHT/2-100)
end
if gamestate=="play" then   
    background(0, 135, 255, 255)--background
    sprite(fish,fishx,fishy,fishw)--draw the fish
    fishy=fishy+fishspeed
    fishspeed=fishspeed-.15
    
    fill(166, 167, 120, 255)
    rect(0,0,WIDTH,25)--bottom of ocean rectangle
    
    pushStyle()
    timer=timer+DeltaTime
    if timer>1/fishFrequency then
        NewFish()--run through this function
        timer=0--reset timer 
    end
    popStyle()
    pushStyle()
    for i,b in pairs(B) do--make everything run through the table
        b.x=b.x-b.s
        if b.x-b.w/2<=-b.w then
            table.remove(B,i)--remove when off screen
        end
        if b.rsc==1 then--determines what sea creature comes on screen based on roll
        sprite(jellyfish,b.x,b.y,b.w,b.h)
            elseif b.rsc==2 then
                sprite(dolphin,b.x,b.y,b.w,b.h) 
                    elseif b.rsc==3 then
                    sprite(crab,b.x,b.y,b.w,b.h)
                        elseif b.rsc==4 then
                        sprite(octopus,b.x,b.y,b.w,b.h)
        end
        
        if fishx+(fishw/2)>=b.x-(b.w/2) and --collision detection
            fishx-(fishw/2)<=b.x+(b.w/2) and 
            fishy-(fishh/2)<=b.y+(b.h/2) and 
            fishy+(fishh/2)>=b.y-(b.h/2) and
            b.rsc==1 then
            One()
        end
        if fishx+(fishw/2)>=b.x-(b.w/2) and --collision detection
            fishx-(fishw/2)<=b.x+(b.w/2) and 
            fishy-(fishh/2)<=b.y+(b.h/2) and 
            fishy+(fishh/2)>=b.y-(b.h/2) and
            b.rsc==2 then
            Two()
        end
        if fishx+(fishw/2)>=b.x-(b.w/2) and --collision detection
            fishx-(fishw/2)<=b.x+(b.w/2) and 
            fishy-(fishh/2)<=b.y+(b.h/2) and 
            fishy+(fishh/2)>=b.y-(b.h/2) and
            b.rsc==3 then
            Three()
        end
        if fishx+(fishw/2)>=b.x-(b.w/2) and --collision detection
            fishx-(fishw/2)<=b.x+(b.w/2) and 
            fishy-(fishh/2)<=b.y+(b.h/2) and 
            fishy+(fishh/2)>=b.y-(b.h/2) and
            b.rsc==4 then
            Four()
        end
        if fishy-fishh<=0 or fishy+fishh>=HEIGHT then--game is over if the fish touches the sides of screen
            gamestate="dead"
        end
    end
        font("AmericanTypewriter")
        fill(243, 242, 243, 255)
        fontSize(50)
        text(score, WIDTH/2,HEIGHT/2+275)
end
        if gamestate=="dead" then
                fishspeed=0
                b.s=0
                fishFrequency=0
                timer=0
                background(0, 119, 255, 255)
                fill(235, 235, 236, 255)
                font("AmericanTypewriter-CondensedBold")
                fontSize(45)
                text("You Died! You got "..score.." points.", WIDTH/2,HEIGHT/2)
                text("Try Again", WIDTH/2,HEIGHT/2-100)      
        end  
end

function One()
    score=score-1
end
function Two()
    score=score+3
end
function Three()
    score=score-5
end
function Four()
    score=score+2
end
function touched(touch)
    if touch.state==BEGAN then
        fishspeed=5--if the screen is touched then the fish moves up(instead of down)at a speed of 5 
        
    if gamestate=="start" and touch.state==BEGAN then
        gamestate="play"
        end
    end    
end

@zzwecker Your score functions One, Two, Three, and Four are called in the draw function. Since draw() runs at 60 times per second, and you’re checking for a collision in draw(), as long as a collision is happening, your score goes up. You should only add to the score when the collision starts, not continuously.

@dave1707 How should I modify my code so that the score is only counting once? The functions One, Two, Three, and Four were my attempt to solve this issue, but clearly unsuccessful. Thanks for your help.

@zzwecker - Use a table for your creatures

creatures={
        {img=jellyfish,score=0},  
        {img=dolphin,score=5},
        {img=crab,score=0},
        {img=octopus,score=10}
        }

Then in draw

        local c=creatures[b.rsc] --just to make code easier to read
        sprite(c,b.x,b.y,b.w,b.h) --the reason for the table of creatures

        if  not b.collided and --don't continue if we already hit this one 
            fishx+(fishw/2)>=b.x-(b.w/2) and --collision detection
            fishx-(fishw/2)<=b.x+(b.w/2) and 
            fishy-(fishh/2)<=b.y+(b.h/2) and 
            fishy+(fishh/2)>=b.y-(b.h/2) then
                b.collided=true --only count the score once 
                if c.score==0 then 
                    --bad creature, die
                else
                    --good creature, add to score
                   score=score+c.score
                end
        end

This is what I tried, and it is not working. Is it nested in the correct place? Thanks for the help, it is much appreciated.

function setup()  
    B={}
    displayMode=(FULLSCREEN)
    fish=readImage("Dropbox:fish-735506_960_720")
    fishx=200
    fishy=350
    fishspeed=0
    fishw=100
    fishh=60
    
    jellyfish=readImage("Dropbox:jellyfish-clip-art-jellyfish-1969px")
    dolphin=readImage("Dropbox:qTBAk88Ec")
    crab=readImage("Dropbox:rTLxka5kc")
    octopus=readImage("Dropbox:BiaEkxri8")
    
    gamestate="start"
    fishFrequency=1
    collision=1
    timer=0
    score=1
    NewFish()
    creatures={
        {img=jellyfish,score=0},  
        {img=dolphin,score=5},
        {img=crab,score=0},
        {img=octopus,score=10}
        }
end
function NewFish()
    b={}--a table to hold information about pipes
    b.w=150
a
    b.rsc=math.random(1,4)--randomly decides which sea creature comes on screen
    table.insert(B,b)--add to our table of balloons  
end

function draw()
    
if gamestate=="start" then
    background(0, 36, 255, 255)
    fill(246, 245, 245, 255)
    font("AmericanTypewriter")
    fontSize(45)
    text ("Tap to start Game!", WIDTH/2,HEIGHT/2)
    fontSize(20)
    text("Directions: GET the octopus and dolphin, AVOID the jellyfish and crab!", WIDTH/2,HEIGHT/2-100)
end
if gamestate=="play" then   
    timer=timer+DeltaTime
    if timer>1/fishFrequency then
        NewFish()--run through this function
        timer=0--reset timer 
    end
    popStyle()
    pushStyle()
    for i,b in pairs(B) do--make everything run through the table
        b.x=b.x-b.s
        if b.x-b.w/2<=-b.w then
            table.remove(B,i)--remove when off screen
        end
    if b.rsc==1 then--determines what sea creature comes on screen based on roll
        sprite(jellyfish,b.x,b.y,b.w,b.h)
            elseif b.rsc==2 then
                sprite(dolphin,b.x,b.y,b.w,b.h) 
                    elseif b.rsc==3 then
                    sprite(crab,b.x,b.y,b.w,b.h)
                        elseif b.rsc==4 then
                        sprite(octopus,b.x,b.y,b.w,b.h)
        end
        local c=creatures[b.rsc] --just to make code easier to read
        sprite(c,b.x,b.y,b.w,b.h) --the reason for the table of creatures
        if  not b.collided and --don't continue if we already hit this one 
            fishx+(fishw/2)>=b.x-(b.w/2) and --collision detection
            fishx-(fishw/2)<=b.x+(b.w/2) and 
            fishy-(fishh/2)<=b.y+(b.h/2) and 
            fishy+(fishh/2)>=b.y-(b.h/2) then
                b.collided=true --only count the score once 
                if c.score==0 then 
                    --bad creature, die
                else
                    --good creature, add to score
                   score=score+c.score
                end
        end 
    end
        font("AmericanTypewriter")
        fill(243, 242, 243, 255)
        fontSize(50)
        text(score, WIDTH/2,HEIGHT/2+275)
end
        if gamestate=="dead" then
                fishspeed=0
                b.s=0
                fishFrequency=0
                timer=0
                background(0, 119, 255, 255)
                fill(235, 235, 236, 255)
                font("AmericanTypewriter-CondensedBold")
                fontSize(45)
                text("You Died! You got "..score.." points.", WIDTH/2,HEIGHT/2)
                text("Try Again", WIDTH/2,HEIGHT/2-100)      
        end  
end

function touched(touch)
    if touch.state==BEGAN then
        fishspeed=5--if the screen is touched then the fish moves up(instead of down)at a speed of 5 
        
    if gamestate=="start" and touch.state==BEGAN then
        gamestate="play"
        end
    end    
end

@zzwecker I reworked your code a little. You can try it and look it over to see what I changed. There’s still things that need fixing to make it work better when the game ends.

displayMode(FULLSCREEN)

function setup()  
    parameter.watch("gamestate")
    fish=readImage("SpaceCute:Star")
    jellyfish=readImage("Planet Cute:Character Boy")
    dolphin=readImage("Planet Cute:Character Horn Girl")
    crab=readImage("Planet Cute:Character Boy")
    octopus=readImage("Planet Cute:Character Pink Girl")
    creatures={jellyfish,dolphin,crab,octopus}
    setup1()
end

function setup1()
    B={}
    fishx=200
    fishy=350
    fishspeed=0
    fishw=100
    fishh=60
    gamestate="start"
    fishFrequency=1
    collision=1
    timer=0
    score=0   
    NewFish()
end

function NewFish()
    b={}    --a table to hold information about pipes
    b.w=150
    b.h=150
    b.x=750
    b.r=75  --"radius"
    b.y=math.random(100,700)
    b.s=5   --speed pixels per second
    b.g=100
    b.col=false
    b.rsc=math.random(1,4)  --randomly decides which sea creature comes on screen
    table.insert(B,b)   --add to our table of balloons  
end

function draw()
    if gamestate=="start" then
        background(0, 36, 255, 255)
        fill(246, 245, 245, 255)
        font("AmericanTypewriter")
        fontSize(45)
        text ("Tap to start Game!", WIDTH/2,HEIGHT/2)
        fontSize(20)
        text("Directions: GET the octopus and dolphin, AVOID the jellyfish and crab!", WIDTH/2,HEIGHT/2-100)
    end    
    if gamestate=="play" then   
        background(0, 135, 255, 255)--background
        sprite(fish,fishx,fishy,fishw)--draw the fish
        fishy=fishy+fishspeed
        fishspeed=fishspeed-.15        
        fill(166, 167, 120, 255)
        rect(0,0,WIDTH,25)--bottom of ocean rectangle        
        pushStyle()
        timer=timer+DeltaTime
        if timer>1/fishFrequency then
            NewFish()   --run through this function
            timer=0     --reset timer 
        end
        popStyle()
        pushStyle()
        for i,b in pairs(B) do--make everything run through the table
            b.x=b.x-b.s
            if b.x-b.w/2<=-b.w then
                table.remove(B,i)--remove when off screen
            end   
            --determines what sea creature comes on screen based on roll
            sprite(creatures[b.rsc],b.x,b.y,b.w,b.h)
            --collision detection
            if fishx+fishw/2>=b.x-b.w/2 and 
                    fishx-fishw/2<=b.x+b.w/2 and 
                    fishy-fishh/2<=b.y+b.h/2 and 
                    fishy+fishh/2>=b.y-b.h/2 then
                if not b.col then
                    b.col=true
                    if b.rsc==1 then
                        score=score-1
                    elseif b.rsc==2 then
                        score=score+3
                    elseif b.rsc==3 then
                        score=score-5
                    else
                        score=score+2
                    end
                end
            else
                b.col=false
            end  
            --game is over if the fish touches the sides of screen
            if fishy-fishh<=0 or fishy+fishh>=HEIGHT then
                gamestate="dead"
            end
        end
        font("AmericanTypewriter")
        fill(243, 242, 243, 255)
        fontSize(50)
        text(score, WIDTH/2,HEIGHT/2+275)
    end
    if gamestate=="dead" then
        fishspeed=0
        b.s=0
        fishFrequency=0
        timer=0
        background(0, 119, 255, 255)
        fill(235, 235, 236, 255)
        font("AmericanTypewriter-CondensedBold")
        fontSize(45)
        text("You Died! You got "..score.." points.", WIDTH/2,HEIGHT/2)
        text("Try Again", WIDTH/2,HEIGHT/2-100)      
    end  
end

function touched(touch)
    if touch.state==BEGAN then
        fishspeed=5
        --if the screen is touched then the fish moves up at a speed of 5 
        if gamestate=="start" then
            gamestate="play"
        end
        if gamestate=="dead" then
            setup1()    -- restart game
        end
    end    
end

Thank you! The help is MUCH appreciated!