Codea bug?

Hey. I’m making a space shooter game, the below script works fully, except for when it goes to draw the “Play Again?” text near the end of this code. Some times it appears in the right position, other times it goes offset. It seriously works and doesn’t work at times! Why?

ship_pos = vec2(WIDTH * .5,40)
enemies = {}
bullets = {}
asteroids = {}
framebullet = 0
frameenemy = 0
current_rate = 30
asteroidframe = 0
score = 0
lives = 3
txt = nil
txtframe = 0
roundtime = 0
reduce = false
vel = 3
stop = false
canmove = false
canclr = true
endtext = nil
paused = false
button_coordinates = vec2(WIDTH * .38,HEIGHT * .3)
ship_img = 1

function touched(t)
    if t.state == BEGAN then
        canmove = true
        if vec2(CurrentTouch.x,CurrentTouch.y):dist(vec2(WIDTH * .95,HEIGHT * .95)) < 24 and not stop then
            paused = not paused
        end
    elseif t.state == ENDED then
        canmove = false
        ship_img = 1
    end
end
function draw()
    if canmove then
        if CurrentTouch.x < WIDTH * .5 and not stop and not paused and ship_pos.x > WIDTH * .01 then
            ship_pos.x = ship_pos.x - 4
            ship_img = 2
        elseif not stop and not paused and  ship_pos.x < WIDTH * .95 then
            ship_pos.x = ship_pos.x + 4
            ship_img = 3
        else
            ship_img = 1
        end
    end
    if not paused then
        roundtime = roundtime + 1
        framebullet = framebullet + 1
        frameenemy = frameenemy + 1
        asteroidframe = asteroidframe + 1
    end
    background(0,0,0)
    smooth()
    sprite("Project:space",WIDTH * .5,HEIGHT * .5,WIDTH,HEIGHT)
    if not stop and not paused and asteroidframe > 15 then
        table.insert(asteroids,{vec2(math.random(math.floor(WIDTH)),HEIGHT * 1.3),math.random(3,math.floor(vel) + 3)})
        asteroidframe = 0
    end
    if not stop then
        for i,v in pairs(asteroids) do
            if not paused then
                v[1].y = v[1].y - v[2]
            end
            if v[1].y < HEIGHT * .003 then
                table.remove(asteroids,i)
            else
                sprite("Project:asteroid",v[1].x,v[1].y,43,43)
            end
        end
    end
    if not stop then
        sprite("Project:ship"..ship_img,ship_pos.x,ship_pos.y,60,60)
    end
    if framebullet > 45 and not stop and not paused then
        framebullet = 0
        sound(SOUND_HIT, 49062)
        local projectile = vec2(ship_pos.x,ship_pos.y + 5)
        table.insert(bullets,projectile)
    end
    if frameenemy > current_rate and not stop and not paused then
        frameenemy = 0
        local newenemy = vec2(math.random(math.floor(WIDTH * .9)),HEIGHT * 1.3)
        table.insert(enemies,newenemy)
    end
    for i,v in pairs(bullets) do
        if v.y + 4 > HEIGHT and not stop then
            table.remove(bullets,i)
        end
        if not stop and not paused then
            v.y = v.y + 4
        end
        if not stop then
            fill(255, 255, 255, 255)
            ellipse(v.x,v.y,16,16)
        end
    end
    for i,v in pairs(enemies) do
        if v.y < HEIGHT * .004 and not stop then
            table.remove(enemies,i)
        end
        if not stop and not paused then
            v.y = v.y - vel
        end
        if not stop then
            sprite("Project:enemy",v.x,v.y,45,45)
        end
        if ship_pos:dist(v) < 36 and not stop then
            table.remove(enemies,i)
            txt = "You lost a life! You have "..lives-tonumber("1").." more."
        end
        for ii,v2 in pairs(bullets) do
            if v2:dist(v) < 22 and not stop then
                sound(SOUND_EXPLODE, 49037)
                score = score + 50
                table.remove(enemies,i)
                table.remove(bullets,ii)
            end
        end
    end
    if not stop then
        font("Optima-ExtraBlack")
        fontSize(30)
        fill(255, 255, 255, 255)
        text("Score: "..score,WIDTH * .8,HEIGHT * .95)
        text("Lives: "..lives,WIDTH * .8,HEIGHT * .9)
    end
    if txt and txtframe <= 70 and not stop then
        if reduce == false then
            reduce = true
            lives = lives - 1
        end
        txtframe = txtframe + 1
        fill(255, 0, 0, 255)
        text(txt,WIDTH * .5,HEIGHT * .5)
    end
    if txtframe >= 70 and not stop then
        txtframe = 0
        reduce = false
        txt = nil
    end
    if lives <= 0 then
        stop = true
        fill(255, 255, 255, 255)
        text("Game over! You scored "..score.." points.",WIDTH * .5,HEIGHT * .5)
        fill(127, 127, 127, 255)
        strokeWidth(4)
        stroke(186, 186, 186, 255)
        rect(button_coordinates.x,button_coordinates.y,250,48)
        fill(255, 255, 255, 255)
        text("Play Again?",WIDTH * .54,HEIGHT * .32)
        if vec2(CurrentTouch.x,CurrentTouch.y):dist(vec2(WIDTH * .54,HEIGHT * .32)) < 80 then
            restart()
        end
    end
    if roundtime > 89 and not stop then
        roundtime = 0
        if current_rate > 2 then
            vel = vel + .12
            current_rate = current_rate - 1
        end
        
    end
    if paused then
        fill(255, 255, 255, 255)
        text("Paused",WIDTH * .5,HEIGHT * .5)
    end
    if not stop then
        sprite("Project:pause",WIDTH * .95,HEIGHT * .95,50,50)
    end
end

@Coder1500 Put all of your variables at the start of the code in function setup(). Also when you post code, put 3~'s on a line before and after the code. I added them for you.

Thanks but the code still won’t work right. When it creates the Play Again button at the bottom of this code, it positions it wrong. :confused: Bug?

@coder1500 Did you do what @dave1707 told you to? Because that fixes the problem for me.

Generally speaking it’s a bad idea to refer to WIDTH or HEIGHT (or other graphics related stuff such as shaders) outside of any function, because at compile time the graphics-related stuff hasn’t initiated yet. That’s why on first run, the button_coordinates variable is wrong, but after restart() it is correct. If you put all the variable definitions inside function setup(), button_coordinates is correct every time.

Also, try to keep discussions of the same project in the same thread, this is the second thread you’ve started with this code. eg:

https://codea.io/talk/discussion/7162/absolutely-crazy-problem#latest

while you’ve got me in a bad mood, try to come up with thread titles that actually specify the problem you’re having, rather than just “crazy problem” or “Codea bug?”

Oh, and say thank you when people fix your problems, or no-one will ever help you again.

Sorry :(, I did put all variables in the setup function and it still isn’t positioning the text right. And it also shifted the rectangle over too I think. Thanks for the replies though.

Could you be more specific about what isn’t right about the text positioning?

When the variables are in setup, I see the text inside the rectangle, presumably this is correct?

Before, on the first run through, the rectangle would be shifted over to the right, so that text was half in/ half out, but this would be corrected on restart.

Is it different for you?

@Coder1500 Are you running in portrait mode or landscape mode. You’re multiplying WIDTH by a certain value to position the rectangle and the text. The default for textMode is CENTER. The default for rectMode is CORNER. Because the WIDTH size is different in portrait and landscape, the text and the rect are correct only in one of the modes . But you should still use the setup() function in all your code.

PS. If you’re going to place text in a rectangle and you don’t specify portrait or landscape at the beginning of the code, then you should make sure rectMode and textMode use the same settings.