Page 3 of 4

Re: If statement and Goto

Posted: Sun Apr 11, 2021 4:44 am
by Bowlman
Looks like I´m still stuck with how I should go with the structure or the idea of it. All the previous examples seem really clear to me and I wanted to try them out. But I just couldn´t get it. Cant get my head around it. Well, I went to back my old if state == 1 then, if state ==2 then route. But then everything was a mess again. Maybe I just need to staire the example codes and then when the time is right, its just hits me. Right?

If you have more like small program/game code examples that uses this, or other clear ways to use states, or the ideas for it, Id love to check them as well. Maybe a link to some other good examples? And again: I felt like I get it when I read the previous examples, but when I try to use it, I get confused. I don´t know what it is, but I think the examples were good anyway. Once again, thanks for those already.

Re: If statement and Goto

Posted: Sun Apr 11, 2021 9:40 am
by zorg
tomxp411 wrote: Fri Apr 09, 2021 9:29 pm
Yeah, I probably would not use this either. This certainly works, but this example suffers from "magic values", and it adds a level of indirection that doesn't add to readability or reliability. At the very least, if you wanted to use a system like this, you should add some constants for "load", "run", and whatever other game states are present:

-- code snipped --

Of course, at that point, I'd be asking why you have this list of state values to begin with instead of just directly assigning the methods to your State object. Also, why are update and draw are globals instead of methods inside of objects?

So we come back to this...

-- code snipped --

This can also be used to replace the "switch" or "case" statements in other languages, like this:

-- code snipped --

I should note that this is something I'm working on right now, and it's not all done - but I'm trying to move away from if/elseif blocks for my keyboard handler and into a structure like this. In c#, I'd just use a switch/case statement, but Lua doesn't have that - so the above code is where I'm going.
A few typos:
function love.update(dt)
State:load(dt)
end
should be State:update(dt)
keyPressed = {
["up"] = function y=y-1 end,
["down"] = function y=y+1 end,
}
you forgot the ()-s after function

Re: If statement and Goto

Posted: Sun Apr 11, 2021 11:04 am
by pgimeno
I wrote about one way of dealing with states, starting here: https://love2d.org/forums/viewtopic.php ... 26#p194226

Take a look, see if that helps you wrap around your head around it.

Re: If statement and Goto

Posted: Sun Apr 11, 2021 11:33 am
by Bowlman
pgimeno wrote: Sun Apr 11, 2021 11:04 am I wrote about one way of dealing with states, starting here: https://love2d.org/forums/viewtopic.php ... 26#p194226

Take a look, see if that helps you wrap around your head around it.
Thanks. I will take a look.

Re: If statement and Goto

Posted: Sun Apr 11, 2021 11:39 am
by darkfrei
pgimeno wrote: Sun Apr 11, 2021 11:04 am I wrote about one way of dealing with states, starting here: https://love2d.org/forums/viewtopic.php ... 26#p194226

Take a look, see if that helps you wrap around your head around it.
How I can understand which stete is enabled?

Re: If statement and Goto

Posted: Sun Apr 11, 2021 12:13 pm
by darkfrei
Small example: state one has physics, but state two has random directions.

Re: If statement and Goto

Posted: Sun Apr 11, 2021 1:18 pm
by pgimeno
darkfrei wrote: Sun Apr 11, 2021 11:39 am
pgimeno wrote: Sun Apr 11, 2021 11:04 am I wrote about one way of dealing with states, starting here: https://love2d.org/forums/viewtopic.php ... 26#p194226

Take a look, see if that helps you wrap around your head around it.
How I can understand which stete is enabled?
Do you mean for debugging? You can add a 'name' field.

Re: If statement and Goto

Posted: Sun Apr 11, 2021 2:06 pm
by darkfrei
pgimeno wrote: Sun Apr 11, 2021 1:18 pm Do you mean for debugging? You can add a 'name' field.
First I think in the old style, on key pressing check the state and do the code.

But you are right, I can use the state as a "key pressed" event holder and the code will be done.

Re: If statement and Goto

Posted: Tue Apr 13, 2021 2:59 pm
by milon
Here's a sample game state system I just whipped up. I've not done this before, so I don't promise it's correct, but I think it's solid. The only thing I don't like about is all the string repetition. It would be better to define the strings in one table and then set player.string to that. (Which would make translations much easier too, I think.)

Code: Select all

gameState = {}
gameState.game = {}
gameState.menu = {}
gameState.quit = {}
currentState = gameState.game

player = {}
player.string = "Standing still"

function love.load()
end

function love.draw()
    currentState.draw()
    love.graphics.print("Crappy example of state machine! Valid inputs are:\nLEFT, RIGHT, UP, DOWN, SPACE, ESC, Q", 10, 400)
end
function love.keypressed(key, scancode, isrepeat)
    currentState.keypressed(key, scancode, isrepeat)
end
function love.keyreleased(key, scancode)
    currentState.keyreleased(key, scancode)
end

function gameState.game.draw(key)
    love.graphics.rectangle("fill", 100, 100, 50, 50)
    love.graphics.print(player.string, 100, 200)
end
function gameState.game.keypressed(key)
    if key == "left" or key == "right" or key == "up" or key == "down" then
        player.string = "Walking " .. key
    elseif key == "space" then
        player.string = "Nothing here!"
    elseif key == "escape" then
        currentState = gameState.menu
        player.string = "Awaiting input"
    elseif key == "q" or key == "Q" then
        currentState = gameState.quit
    end
end
function gameState.game.keyreleased(key, scancode)
    player.string = "Standing still"
end

function gameState.menu.draw(key)
    love.graphics.print("Menu!", 100, 10)
    love.graphics.rectangle("line", 90, 30, 150, 150)
    love.graphics.print(player.string, 100, 50)
end
function gameState.menu.keypressed(key)
    if key == "left" or key == "right" or key == "up" or key == "down" then
        player.string = "Navigate menu " .. key
    elseif key == "space" then
        player.string = "Select item"
    elseif key == "escape" then
        currentState = gameState.game
        player.string = "Standing still"
    elseif key == "q" or key == "Q" then
        currentState = gameState.quit
    end
end
function gameState.menu.keyreleased(key, scancode)
    player.string = "Awaiting input"
end

function gameState.quit.draw(key)
    love.graphics.print("Really quit?\nPress Q again to quit", 100, 10)
end
function gameState.quit.keypressed(key)
    if key == "q" then
        love.event.quit()
    else
        currentState = gameState.game
        player.string = "Standing still"
    end
end
function gameState.quit.keyreleased(key, scancode)
end
darkfrei, you asked how you know what state the game is in. Ideally you shouldn't need to worry about that (except for debugging, of course). As long as your states and associated actions are well-defined, the game should run just fine regardless of state.

Re: If statement and Goto

Posted: Sun Apr 18, 2021 12:05 pm
by darkfrei
milon wrote: Tue Apr 13, 2021 2:59 pm darkfrei, you asked how you know what state the game is in. Ideally you shouldn't need to worry about that (except for debugging, of course). As long as your states and associated actions are well-defined, the game should run just fine regardless of state.
If I have three states: LevelOne, LevelTwo and Pause, then I need to return from pause to first and second level, isn't that? Or Menu with submenues.

Shorted main code:

Code: Select all

gameState = {}
gameState.game = require ('game')
gameState.menu = require ('menu')
gameState.quit = require ('quit')

currentState = gameState.game

player = {}
player.string = "Standing still"

function love.load()
end

function love.draw()
    currentState.draw()
    love.graphics.print("Crappy example of state machine! Valid inputs are:\nLEFT, RIGHT, UP, DOWN, SPACE, ESC, Q", 10, 400)
end

function love.keypressed(key, scancode, isrepeat)
    currentState.keypressed(key, scancode, isrepeat)
end

function love.keyreleased(key, scancode)
    currentState.keyreleased(key, scancode)
end