[Solved] Draw before update?

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.
Post Reply
cloudfrog
Prole
Posts: 8
Joined: Mon Feb 21, 2022 8:31 am

[Solved] Draw before update?

Post by cloudfrog »

Got myself in a pickle here. Go easy, I'm still wearing my noob badge :)

I have a few game "states" that I'm using ("INTRO", "MENU", "GAME"). I am aware of state machines and such, but for this project I am not using any external libs other then to recursively print tables for troubleshooting.

For each, i have something.lua, each having an update and draw function. For example.

Code: Select all

function Menu:update(speedAdjustment)
...
end
Now, in main.lua, I'm doing something like this for update and draw:

Code: Select all

function love.update(dt)
    if Settings.GlobalStates.activeScene == 'GAME' then
        Input:update(dt * Settings.gameSpeed)
        Ball:update(dt * Settings.gameSpeed)
    elseif Settings.GlobalStates.activeScene == 'INTRO' then
        Intro:update(dt)
    elseif Settings.GlobalStates.activeScene == 'MENU' then
        Menu:update(dt)
    end
end
I want to point out that each scene works fine when I bypass the if logic and just force the scene i want.
However, when I transition I am running into trouble. Here's what happens,

Intro:update runs as expected until there is nothing left to do. It then transitions:

Code: Select all

-- in Intro:update
Settings.GlobalStates.activeScene = 'MENU'
Great, on the next iteration we'll go to the MENU. However, we end up hitting Menu:draw before Menu:update runs. Fail. light blue screen of death.

I tried to make a "toggle switch" to bypass that first run.

Code: Select all

function Menu:draw()
    -- (updateHasRun) and true or return
    if (updateHasRun ~= true) then 
        print('nah dont do it')
        return
    end

    menuState.drawAction()
end
So, my return of course is only breaking me out of my if rather then the function making the check useless. Yup, I get it; my bad. But now what? Any thoughts here how to break out of draw(), or other ideas? I could throw my menuState.drawAction() in an else and call it a day, but i feel this is getting more and more hacky by the second.
Last edited by cloudfrog on Tue Mar 15, 2022 1:05 am, edited 1 time in total.
MrFariator
Party member
Posts: 548
Joined: Wed Oct 05, 2016 11:53 am

Re: Draw before update?

Post by MrFariator »

I suppose the simplest thing to do that doesn't involve you adding a bunch of if statements to your draw functions is to do something along the lines of:

Code: Select all

-- in Intro:update when we want to change scene
Settings.GlobalStates.nextScene = 'MENU'

Code: Select all

function love.update(dt)
    -- switch the scene to update before anything else is run in love.update
    if Settings.GlobalStates.nextScene then
        Settings.GlobalStates.activeScene = Settings.GlobalStates.nextScene
        Settings.GlobalStates.nextScene = nil
    end
    -- rest of love.update
end
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Draw before update?

Post by ReFreezed »

My advice is the same as MrFariator's. Since the timing of when things happen often is important it's also often a good idea to defer/queue a thing to happen at a later point, and this scene transition situation is a good example.

A bonus to having Settings.GlobalStates.nextScene is that you could theoretically have multiple places in the code that want to change to different scenes, but only the last one wins (and you don't get frantic changes of Settings.GlobalStates.activeScene during the frame, which may or may not cause instability in any code that happen to check its value).

Another example of a situation you probably wanna use the same strategy is when switching from a music track to another (like when going from one level to another). Before starting the new music you probably want to fade out the old music (as a hard cut isn't very pleasant), and anything sound related of course has to happen over time (i.e. not immediately).
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
cloudfrog
Prole
Posts: 8
Joined: Mon Feb 21, 2022 8:31 am

Re: Draw before update?

Post by cloudfrog »

My draw is only one line of code so it was simple to 'if' the problem away short term. I'm going to go back and implement next state. That looks and feels right for the project.

Thank you both for the simple and effective solution.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Semrush [Bot] and 3 guests