Page 1 of 1

How to implement a pause in my game

Posted: Sat Dec 17, 2022 5:17 pm
by jogi
Hi , i'm still a noob in Love2D trying to create my first game and i was wondering how could i implement a pause function in my game. Basically i just want the frame rate update to freeze when i press "p" (so a classic pause game) and it's just not very clear to me how could i reach this goal, i assume that it's very simple but still i'm struggling with the logic of creationg the boolean to freeze the update. Maybe someone can give me an example on how can i do it in this code?

function love.load()

Player:load()
Ball:load()
AI:load()
Background:load()





Score = {player = 0, ai = 0}
font = love.graphics.newFont("font/digifont.otf" , 30)

sounds = {}

sounds.music = love.audio.newSource("sfx/chords.wav", "stream")
sounds.music:setLooping(true)

sounds.music:play()



end

function love.update(dt)


Player:update(dt)
Ball:update(dt)
AI:update(dt)
Background:update(dt)

end


function love.draw()
Background:draw()
Player:draw()
Ball:draw()
AI:draw()
drawScore()



end

function drawScore()
love.graphics.setFont(font)
love.graphics.print("Player: "..Score.player, 50, 50)
love.graphics.print("Ai: "..Score.ai, 1000, 50)

end


function checkCollision(a,b)
if a.x + a.width > b.x and a.x < b.x + b. width and a.y + a.height > b.y and a.y < b.y + b.height then
return true

else
return false
end

end

Re: How to implement a pause in my game

Posted: Sat Dec 17, 2022 5:51 pm
by BrotSagtMist
Love calls update and draw each frame, it does not actually care if they even exist nor when you create them.
So the typical pause screen is created by simply deleting or replacing the two. (this is also a way to do title screens and the like.)
Just create your base function using a different name and then set/unset the name to update:

Code: Select all

Update=function() 
  ... 
end
love.update=Update
function love.keypressed(k)
 if k="p" then
 love.update=love.update and nil or Update
 end
end
This does not actual freeze love and still uses cpu tho. For that you need to have the pause function a loop of its own, maybe with love.event.wait in it.

Re: How to implement a pause in my game

Posted: Sat Dec 17, 2022 11:00 pm
by knorke
What is a pause?
A pause is the absence of updates. So stop calling any update-functions, for example by early returning from love.update()

Code: Select all

local isPaused = false
function love.keypressed(key, unicode)
  if (key=="p") then isPaused = not isPaused end
return

function love.update(dt)
  if isPaused then return end

  Player:update(dt)
  Ball:update(dt)
  AI:update(dt)
  Background:update(dt)
return

Re: How to implement a pause in my game

Posted: Sun Dec 18, 2022 8:54 am
by pgimeno
BrotSagtMist wrote: Sat Dec 17, 2022 5:51 pm This does not actual freeze love and still uses cpu tho. For that you need to have the pause function a loop of its own, maybe with love.event.wait in it.
If you "freeze love" then the window won't be refreshed; placing another window on top of it, or going out of fullscreen mode momentarily, will cause the window contents to be lost. That's usually not desirable.

So, you have to either keep drawing everything, or draw to a canvas and then keep drawing the canvas every frame. The latter is the approach I used for T2R.


@knorke
knorke wrote: Sat Dec 17, 2022 11:00 pm

Code: Select all

function love.keypressed(key, unicode)
I guess you meant `scancode` rather than `unicode` :) Otherwise I agree with your solution. BrotSagMist's approach of using love.update as a pause indicator was too much of a hack.

Re: How to implement a pause in my game

Posted: Sun Dec 18, 2022 3:04 pm
by BrotSagtMist
But i like hacky! And the other solution does an unnecessary if check every frame.
If you "freeze love" then the window won't be refreshed; placing another window on top of it, or going out of fullscreen mode momentarily, will cause the window contents to be lost. That's usually not desirable.
Nono, not necessary. Thats why i said to use love.event.wait. Its actually able to catch events like placing a window on top which can be used to call draw again on demand. So pause here would be a simple loop:

Code: Select all

function pause()
 repeat 
  local e,n=love.event.wait()  
  if e=="keypressed" and n=="p" then love.timer.step() return end
  love.graphics.present()
 until nil
end
love.keypressed=function(k)
 if k=="p" then pause() end
end
But apparently event.wait() causes some cpu of its own (is this a bug?), so its neither ideal.
Edit: apparently you can just recall present() again. Also the quit event needs to be handled.
Edit: And mouse movements should be ignored, window resize can be handled and music needs to be dealt with too.
If done proper any method of pausing can actually blow up pretty unsimple. ¯\_(ツ)_/¯

Re: How to implement a pause in my game

Posted: Sun Dec 18, 2022 7:37 pm
by pgimeno
Doesn't work for me. If I move the window partially out of the visible area and then back, for example, the window isn't refreshed properly.

Re: How to implement a pause in my game

Posted: Sun Dec 18, 2022 7:58 pm
by BrotSagtMist
Guess you picture is deleted after present then, adding love.draw _should_ make it work.
How lovely that stuff behaves so predictable :D
Thanks for the info.

Re: How to implement a pause in my game

Posted: Mon Dec 19, 2022 1:11 pm
by zorg
Might be OS-dependent how the backbuffer's treated, whether it gets saved, or if there's no consideration whatsoever and you'll get pixel garbage.