Screen Question

I’m making a project with many different screens in it, but how do I make those screens?

@Wallisch_pls There have been many examples of multiple screens posted. You can probably find one that fits your needs by searching the forum. If you can’t find what you’re looking for, ask again. Here’s one for starters.

https://twolivesleft.com/Codea/Talk/discussion/3519/how-can-you-have-multiple-screens/p1

What I do is create a variable called “scene” and make an if statement in the draw function that’s “if scene == 1 then…(What to do for this scene)… elseif scene == 2 then…(What to do for this scene)…end” etc. I think that’s the simplest way. Now when you want to change your screen you just do “scene = (The scene #)”.

@EpicPotato If you have a lot of scenes, the if statement can get pretty big. There are other ways that will eliminate the if statement. In the first draw example, set func to the function you want to call. That’s what I do in the above example. In the second draw example, create a table of the functions you want, then set the table offset to that function. You only have one statement in draw that you have to work with, but it calls as many functions as you want.


function draw()
     func()
end

---------------------

function setup()
    sc=1
    scene={scn1,scn2,scn3,scn4}
end

function draw()
    scene[sc]()
end

function scn1()
    print("scn1")
end

function scn2()
    print("scn1")
end

@dave1707 Your way would get even bigger, what with creating each function, the ends, and the spaces in between. I always use the if scene == 1 then blah elseif scene == 2 then blah...end method. It’s short and easy. If it gets too big, I can always just make a separate class. Such as in 10Life, I use all the menus in the draw function, and for game rendering, because it’s a bit bigger, it has its own tab and class, and then I can just say elseif gameState == 2 then game:draw() elseif gameState == 3 then...

@SkyTheCoder When you do “If scene == 1 then blah”, what is “blah”. Is it a function, or a bunch of lines of code. If it’s a function, then that’s no different then my calling a function. If it’s a bunch of lines of code, they should be in a function or your if statement is going to be a mess as it gets bigger. While your if statement in draw() gets bigger to compare different scenes to call different functions, my one line of code in draw() stays one line of code. My scn1() and scn2() are just examples. They would be replaced by the actual functions you would call, mainly your “blah”. If the program isn’t very big, then an if statement would work. But if it’s a full blown game with major functions doing menus, initialize, game levels, end game, high score, etc, then an if statement might get too large or confusing.

When it gets big and messy, you might consider putting your different actions into function tables, as I’ve demonstrated below for drawing. Each state could go in a separate tab, to keep things clean.

This approach can also be used for multi-level games, or tutorials with many levels.

--you have a table for each different state, such as this one for starting up
startMenu={}

--It has a setup and draw function, eg
function startMenu.setup()
    --code to set up menu
end

function startMenu.draw()
    --code to draw start menu
end

function startMenu.touched(touch)
    --code to deal with touches
end

--and you'd have a similar table for playing, losing and winning, etc
--so when the state changes to (say) Playing, you say
state=Playing
state.setup() --set it up

--and then drawing, touching etc is simple

function draw()
    state.draw()
end

function touched(touch)
    --run the touched function of the current state, if there is one
    if state.touched then state.touched(touch) end
end

@dave1707 “blah” is a bunch of lines of code. Yes, it makes draw bigger. If you use functions though, it takes up even more lines of code overall. It’s not that messy, as I said it can be used for menus only which is just a bunch of text() calls, nice and compact, and for the big stuff have a separate class. To tell where everything is, you can just put comments after the ifs.

Check out my draw function from 10Life 2 (coming soon):

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(255)

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    font("Copperplate-Light")
    fontSize(48)
    fill(0)
    
    if gameState == 1 then
        fontSize(72)
        text("10LIFE 2", WIDTH / 2, 3 * (HEIGHT / 4))
        fontSize(24)
        fill(stateData[1][1])
        text("START", WIDTH / 2, HEIGHT / 2)
        fill(stateData[1][2])
        if inCodea then
            text("EXIT", WIDTH / 2, HEIGHT / 4)
        end
    elseif gameState == 2 then
        game:draw()
    elseif gameState == 3 then
        fontSize(72)
        text("YOU DIED", WIDTH / 2, 7 * (HEIGHT / 8))
        text("KILLS: " .. tostring(game.kills), WIDTH / 2, 6 * (HEIGHT / 8))
        text("SCORE: " .. tostring(game.score), WIDTH / 2, 5 * (HEIGHT / 8))
        fontSize(24)
        fill(stateData[3][1])
        text("RETRY", WIDTH / 2, HEIGHT / 2)
        if inCodea then
            fill(stateData[3][2])
            text("EXIT", WIDTH / 2, HEIGHT / 4)
        end
    elseif gameState == 4 then
        fontSize(72)
        text("TIME'S UP", WIDTH / 2, 7 * (HEIGHT / 8))
        text("KILLS: " .. tostring(game.kills), WIDTH / 2, 6 * (HEIGHT / 8))
        text("SCORE: " .. tostring(game.score), WIDTH / 2, 5 * (HEIGHT / 8))
        fontSize(24)
        fill(stateData[3][1])
        text("RETRY", WIDTH / 2, HEIGHT / 2)
        if inCodea then
            fill(stateData[3][2])
            text("EXIT", WIDTH / 2, HEIGHT / 4)
        end
    end
end

Not messy at all. If it gets too big, I can add extra lines in between to make it look nice.

Personally, I feel it is messy to not have a space after a comma, or after a =, or to have no indents in setup() or an if statement.

@SkyTheCoder Here’s your code the way I suggested above. Where you would set gameState equal to 1,2,3,etc, I would set func() equal to gameState1, gameState2, etc. If each gameState was 100 lines of code or more, which it could be in a real game, your draw() function would be large and messy and you would probable make each gameState a function, which I already did. I agree that indents makes code easier to read, but spaces/no spaces in lines of code is the programmers choice. In a real game, the user doesn’t see the code, the programmer does. So it’s what’s comfortable for them. I’m not going to code so it’s easier for you to read, just as you’re not going to code to make it easier for me to read. I’m not saying do it my way, I’m saying, here’s another example of how to do it. It’s up to the reader to use it or use something else. It’s their choice.


function draw()
    background(255)
    strokeWidth(5)
    font("Copperplate-Light")
    fontSize(48)
    fill(0)
    func()
end

function gameState1()
    fontSize(72)
    text("10LIFE 2", WIDTH / 2, 3 * (HEIGHT / 4))
    fontSize(24)
    fill(stateData[1][1])
    text("START", WIDTH / 2, HEIGHT / 2)
    fill(stateData[1][2])
    if inCodea then
        text("EXIT", WIDTH / 2, HEIGHT / 4)
    end
end

function gameState2()
    game:draw()
end

function gameState3()
    fontSize(72)
    text("YOU DIED", WIDTH / 2, 7 * (HEIGHT / 8))
    text("KILLS: " .. tostring(game.kills), WIDTH / 2, 6 * (HEIGHT / 8))
    text("SCORE: " .. tostring(game.score), WIDTH / 2, 5 * (HEIGHT / 8))
    fontSize(24)
    fill(stateData[3][1])
    text("RETRY", WIDTH / 2, HEIGHT / 2)
    if inCodea then
        fill(stateData[3][2])
        text("EXIT", WIDTH / 2, HEIGHT / 4)
    end
end

function gameState4()
    fontSize(72)
    text("TIME'S UP", WIDTH / 2, 7 * (HEIGHT / 8))
    text("KILLS: " .. tostring(game.kills), WIDTH / 2, 6 * (HEIGHT / 8))
    text("SCORE: " .. tostring(game.score), WIDTH / 2, 5 * (HEIGHT / 8))
    fontSize(24)
    fill(stateData[3][1])
    text("RETRY", WIDTH / 2, HEIGHT / 2)
    if inCodea then
        fill(stateData[3][2])
        text("EXIT", WIDTH / 2, HEIGHT / 4)
    end
end

@dave1707 I’m not concerned about my draw function being “messy,” just the overall lines of code. And your way has more. Also, I have OCD, so things like no spaces in between stuff makes me cringe. If it’s a project I downloaded, I almost always have to fix it, if it’s small enough.

@dave1707 thanks for this alternative approach. I was an if statement type person but hadn’t given it too much thought. I think I’ll try it next time as I don’t have @SkyTheCoder’s discipline with indents and spaces.

Also @SkyTheCoder if you are really just concerned about the overall lines of code then why not put it all in one big line?..

Of course I’m just ribbing you but the semi-serious point is that less lines does not necessarily mean better.

@SkyTheCoder - your all-in-one approach is fine while your projects are small, but when your draw function gets to be hundreds of lines long, it makes sense to break it into a set of functions that handle different states. It makes testing and maintenance far easier.

So both approaches have their place.