If statement and Goto

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
grump
Party member
Posts: 721
Joined: Sat Jul 22, 2017 7:43 pm

Re: If statement and Goto

Post by grump »

Xii wrote: Wed Apr 07, 2021 7:09 pm
pgimeno wrote: Wed Apr 07, 2021 4:09 pm it's not how it was designed to be used.
Citation needed.
The fact that calling love.load() without arguments is against spec would be one reason.

The actual point here is, in my opinion, that manually calling love.load does not magically reset state. It is misleading to suggest that calling love.load solves any problem of that kind. You can call it if you want, but it doesn't help with anything that was discussed in this thread.
User avatar
pgimeno
Party member
Posts: 2610
Joined: Sun Oct 18, 2015 2:58 pm

Re: If statement and Goto

Post by pgimeno »

Xii wrote: Wed Apr 07, 2021 7:09 pm Citation needed.
You just need to look at the function name. It's not even love.start, which would be a good name if the intention was "something that is used to start".

The first example in the wiki even highlights this intended usage.

Furthermore, it is just common sense that every event is designed to be called by the framework. The love. prefix is a hint.
User avatar
Xii
Citizen
Posts: 90
Joined: Thu Aug 13, 2020 9:09 pm
Contact:

Re: If statement and Goto

Post by Xii »

You are correct. love.event.quit("restart") is the correct way to restart the whole app, not love.load()
Bowlman
Prole
Posts: 9
Joined: Sun Apr 04, 2021 7:51 pm

Re: If statement and Goto

Post by Bowlman »

RNavega wrote: Wed Apr 07, 2021 11:43 am How much have you read on software programming patterns? Specifically the state pattern, it's very cool: https://gameprogrammingpatterns.com/state.html

As I understand it, you're encapsulating logic into separate objects, and at one given moment only one of those objects is controlling the game (both in update and in drawing).
So a menu screen is one game state, a level is another game state etc. Each state has the code to switch to other states, that's how you can go from the menu screen to the first level.

To implement states you need to decide on a common interface, a format that you decided to use for all state objects. Say, all state objects should have a 'load' attribute that points to a function that both loads assets (art, audio) that the state will need, and replaces the current update function and the drawing function with the ones from the state so it can take over handling the game.

With Lua this is done easily since you can store a function in a variable, and execute that function without knowing what it is, something like...

Code: Select all

currentState.load()
So if you want to restart a level, make this (re)loading as a separate state, like "loadLevel1State", and transition to that state. Inside the update code of that state you can reset all variables you want, load assets (if not already loaded) and transition to the next state, "playLevel1State" that runs the level.
So this "loadLevel1State" just runs for a single frame since it does simple things, and switches to the play level state right then without any user action needed.

It's in the "playLevel1State" that things happen and the game runs. Within the "playLevel1State" update function you need to run the game and react to user input, like if the player hits escape, transition back to the menu state (or rather, the menu 'loading' state that loads its assets if needed and resets variables, and then transitions to the menu playing state).
Thanks. This was exactly what I was looking for. I tried to search about states, but didnt find much. Just that its kinda the logic to go with. I need to take closer look to that link. Looks like its been explained clearly. I still need to get my head around and try to start thinking a bit differently. Maybe a bit straight forward as well.

Im been working with my first little try-out out project. I try to make small memory game. I thought I could just wrap around few hours of code and get the basic commands, but its been like four days. I have working prototype and everything I wanted is there at the moment. But the whole code and the struckture is a mess. Maybe I should start over and try to make it with the whole basic idea in mind. I dont really mind that its been days. Its been cool to learn new things and learn new way to think programing. Thanks for the advices. I think now Im again one step closer to "get it". Thanks.
RNavega
Citizen
Posts: 75
Joined: Sun Aug 16, 2020 1:28 pm

Re: If statement and Goto

Post by RNavega »

Ok, good luck. If you plan on having any screen transition effects then you don't need to make a full state just for them, you can do them from within a preexisting state and undo in the next.

For example, say you want this: user hits PLAY on the menu, screen fades to black, then fades in into level 1 (or its loading screen). To make this I'd use this flow:
  • In love.load() initialize the 'currentState' global to be the menu state.
  • Menu state:
    • Keep polling for input.
    • Draw menu elements based on input, cursor position etc.
    • If the player hits play, start a screen-fade-out effect so we hide the screen. While still in this same state, we observe this effect so that once it finishes (the screen is black), transition to the load-level-1 state below.
    Load level 1 state:
    • Load the "loading screen" graphics, if not loaded already.
    • Keep drawing the (possibly animated?) loading screen graphics, like a progress bar, throbber etc.
    • Fade in the screen so we can see these things (it was faded out by the previous state).
    • Load the rest of the assets for level 1.
    • Once loading is finished, start a screen-fade-out effect to hide the screen. Once it finishes (the screen is black), transition to the play-level-1 state.
    Play level 1 state:
    • Fade in the screen so we can see things (it was faded out by the previous state).
    • Game loop updating all actors, props and level.

You know, thinking of things like a theater script.
I'd love to know how other people would do the above as well, what would you change (or if it's an entirely different way).
milon
Party member
Posts: 123
Joined: Thu Jan 18, 2018 9:14 pm

Re: If statement and Goto

Post by milon »

RNavega wrote: Wed Apr 07, 2021 11:43 am How much have you read on software programming patterns? Specifically the state pattern, it's very cool: https://gameprogrammingpatterns.com/state.html
...
Ooh, another big thanks for this! I've also been trying to wrap my head around states. Much appreciated!!

EDIT: Now that I've read up more on state machines, here's my thoughts about states for loading levels:
RNavega wrote: Thu Apr 08, 2021 11:55 am Ok, good luck. If you plan on having any screen transition effects then you don't need to make a full state just for them, you can do them from within a preexisting state and undo in the next.

For example, say you want this: user hits PLAY on the menu, screen fades to black, then fades in into level 1 (or its loading screen). To make this I'd use this flow:

- snip -

You know, thinking of things like a theater script.
I'd love to know how other people would do the above as well, what would you change (or if it's an entirely different way).
I'd prefer to define a single Loading state and give it a variable that tells it what to load. That way you only need 1 state per level, rather than 2 in your example. I would also direct the loading state to handle the fading transitions, unless there are other non-loading fade screens.
Last edited by milon on Thu Apr 08, 2021 7:35 pm, edited 1 time in total.
User avatar
tomxp411
Prole
Posts: 13
Joined: Thu Apr 08, 2021 5:41 pm

Re: If statement and Goto

Post by tomxp411 »

Bowlman wrote: Thu Apr 08, 2021 11:02 am Im been working with my first little try-out out project. I try to make small memory game. I thought I could just wrap around few hours of code and get the basic commands, but its been like four days. I have working prototype and everything I wanted is there at the moment. But the whole code and the struckture is a mess. Maybe I should start over and try to make it with the whole basic idea in mind. I dont really mind that its been days. Its been cool to learn new things and learn new way to think programing. Thanks for the advices. I think now Im again one step closer to "get it". Thanks.
If you have been working in languages where GOTO is a thing, you probably don't have much experienced with structured programming... so now is definitely the time to learn to use code blocks and for, while, and if/else commands to control your program flow.

Unlike BASIC, which practically invented the term "Spaghetti code", the program flow within a function in Lua always goes from the top down, except for loops. This is an important concept to wrap your brain around, because it fundamentally changes how you code. When I started programming in C after learning on BASIC, it took a long time to undo the bad habits learned in BASIC and assembly language.

Also, you can use object oriented programming in some fun ways to drastically change a program's behavior at runtime. Switching out two objects, both with a "draw" command, can quickly change how your game behaves.

So one way you can switch states is something like this: you can create multiple objects, each with its own :draw() method. For example:

game:draw() draws the playing field
game:mousePressed() handles the mouse events during the game play

menu:draw() displays the menu
menu:mousepressed() handles mouse events when the menu is displayed

so in love.load(), you might set up something like this:
mode = game

and then in love.draw() you would call
mode:draw()


So now "mode" is just an alias for "game", and any time you call mode:draw(), it's actually calling game:draw().

But somewhere deep in your game loop, you're going to have a function named game:gameOver(), and in there...
mode = menu

Now when you call mode:draw(), you're actually drawing the main menu, rather than the game screen.

And if you pass your other event handlers through, they will do the same thing. For example:

function love:keypressed(k,s,r)
mode:keypressed(k,s,r)
end

So you don't need an IF block or a GOTO to dramatically change how the game runs. You just assign mode to change the game's state.
Bowlman
Prole
Posts: 9
Joined: Sun Apr 04, 2021 7:51 pm

Re: If statement and Goto

Post by Bowlman »

tomxp411 wrote: Thu Apr 08, 2021 6:05 pm
Bowlman wrote: Thu Apr 08, 2021 11:02 am Im been working with my first little try-out out project. I try to make small memory game. I thought I could just wrap around few hours of code and get the basic commands, but its been like four days. I have working prototype and everything I wanted is there at the moment. But the whole code and the struckture is a mess. Maybe I should start over and try to make it with the whole basic idea in mind. I dont really mind that its been days. Its been cool to learn new things and learn new way to think programing. Thanks for the advices. I think now Im again one step closer to "get it". Thanks.
If you have been working in languages where GOTO is a thing, you probably don't have much experienced with structured programming... so now is definitely the time to learn to use code blocks and for, while, and if/else commands to control your program flow.

Unlike BASIC, which practically invented the term "Spaghetti code", the program flow within a function in Lua always goes from the top down, except for loops. This is an important concept to wrap your brain around, because it fundamentally changes how you code. When I started programming in C after learning on BASIC, it took a long time to undo the bad habits learned in BASIC and assembly language.

Also, you can use object oriented programming in some fun ways to drastically change a program's behavior at runtime. Switching out two objects, both with a "draw" command, can quickly change how your game behaves.

So one way you can switch states is something like this: you can create multiple objects, each with its own :draw() method. For example:

game:draw() draws the playing field
game:mousePressed() handles the mouse events during the game play

menu:draw() displays the menu
menu:mousepressed() handles mouse events when the menu is displayed

so in love.load(), you might set up something like this:
mode = game

and then in love.draw() you would call
mode:draw()


So now "mode" is just an alias for "game", and any time you call mode:draw(), it's actually calling game:draw().

But somewhere deep in your game loop, you're going to have a function named game:gameOver(), and in there...
mode = menu

Now when you call mode:draw(), you're actually drawing the main menu, rather than the game screen.

And if you pass your other event handlers through, they will do the same thing. For example:

function love:keypressed(k,s,r)
mode:keypressed(k,s,r)
end

So you don't need an IF block or a GOTO to dramatically change how the game runs. You just assign mode to change the game's state.
Yeah, thats pretty much me. And as I said earlier. I felt like I get it when I read it, but when I tried to put it to use and think how to use it, I feel again that I didnt get it. But I guess you dont just get everything in one or two days. After years and years of getting used to other things. I think I get the idea here (again). And with your example, it looks easier to do things like that and not with ifs and with flags. I need to put those in use and try if I can make it work and start to understand it. Thanks.
User avatar
darkfrei
Party member
Posts: 217
Joined: Sat Feb 08, 2020 11:09 pm

Re: If statement and Goto

Post by darkfrei »

I've never used such state functions:

Code: Select all

function love.load()
	state = "load"
end

Code: Select all

function love.update(dt)
	update[state](dt)
end

Code: Select all

function love.draw()
	draw[state]()
end
User avatar
tomxp411
Prole
Posts: 13
Joined: Thu Apr 08, 2021 5:41 pm

Re: If statement and Goto

Post by tomxp411 »

darkfrei wrote: Fri Apr 09, 2021 11:03 am I've never used such state functions:

Code: Select all

function love.load()
	state = "load"
end

Code: Select all

function love.update(dt)
	update[state](dt)
end

Code: Select all

function love.draw()
	draw[state]()
end
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: Select all

States = {load="load", run="run"}
States.state = States.load
Then your game loop looks like:

Code: Select all

function love.load()
  State= States.load
end
function love.update(dt)
  update[State](dt)
end
function love.draw()
  draw[State]()
end
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: Select all

States = {load=LoadState, run=RunState}

function love.load()
  State = States.load
end

function love.update(dt)
  State:update(dt)
end
function love.draw()
  State:draw()
end
This can also be used to replace the "switch" or "case" statements in other languages, like this:

Code: Select all

keyPressed = {
  ["up"] = function y=y-1 end,
  ["down"] = function y=y+1 end,
}

function love.keypressed( key, scancode, isrepeat )
  if keyPressed[key] ~= nil then 
    keyPressed[key]
  end
end function 
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.
Last edited by tomxp411 on Mon Apr 12, 2021 7:23 am, edited 1 time in total.
Post Reply

Who is online

Users browsing this forum: bigy123 and 26 guests