Page 1 of 2

Making a progression bar

Posted: Wed Jan 06, 2021 10:58 pm
by Gunroar:Cannon()
How do I draw a progression bar that draws the progress of something that takes long to do(like loading a map) so that a player won't think the game has frozen? Do I use coroutines or what? I don't know so pls help...

Re: Making a progression bar

Posted: Thu Jan 07, 2021 9:11 am
by darkfrei
Do you load all data in one load/update tick?

Re: Making a progression bar

Posted: Thu Jan 07, 2021 9:53 am
by Gunroar:Cannon()
yes

Re: Making a progression bar

Posted: Fri Jan 08, 2021 1:33 pm
by darkfrei
Gunroar:Cannon() wrote: Thu Jan 07, 2021 9:53 am
darkfrei wrote: Thu Jan 07, 2021 9:11 am Do you load all data in one load/update tick?
yes
So, you are need to load in multiple ticks.

Re: Making a progression bar

Posted: Fri Jan 08, 2021 10:12 pm
by Gunroar:Cannon()
Hmm, so draw as I go along? But can't I use coroutines or something?
PS: I noticed you added an avatar, nice.

Re: Making a progression bar

Posted: Fri Jan 08, 2021 11:21 pm
by dezoitodemaio
Just load a few objects at every update() instead of loading the whole thing.

Or create a corountine that loads the map and do a resume()/yield() after loading some amount of objects, do that untill everything is loaded.

Re: Making a progression bar

Posted: Sat Jan 09, 2021 4:28 am
by RNavega
I think you can do this using Data objects, more specifically FileData, created by reading a file from disk with love.filesystem.newFileData.

FileData is a subclass of Data, so you can know the amount of bytes that the loaded file data represents. You can also calculate the total bytes from all assets that you're trying to load at a given moment while debugging your game (just remove that code for the release version, obviously). Then you know how many bytes you're trying to load at that moment, and how much each loaded asset represents of that total = a percentage for a progress bar.

You can create images from a FileData (FileData > ImageData > love.graphics.newImage overload that takes ImageData), and also audio (FileData > love.audio.newSource overload that takes a FileData), possibly others.

The only thing is how to asynchronously (i.e non-blockingly) load the FileData objects from files on disk. Lua coroutines are blocking (the ones that say they aren't, just yield() control back when there's no work to do). The only way is using the love.thread module, loading FileData objects in a thread, pushing them into a Channel and then popping from that Channel back on the main thread so that you can retrieve the FileData and use them to update the progress bar and read them into other LÖVE objects (images, audio etc).
So you can keep drawing animated graphics and updating the program while loading files in the background, on another thread.

Re: Making a progression bar

Posted: Sat Jan 09, 2021 4:05 pm
by pgimeno
Just make sure you don't load any GL images in another thread! You can load them into ImageData in the thread, then in the main thread, convert them all to Image at once.

Re: Making a progression bar

Posted: Mon Jan 11, 2021 11:06 am
by Gunroar:Cannon()
Can't I call the loading method in a coroutine and have value for progression of the loading that love.draw uses to draw the bar?

Re: Making a progression bar

Posted: Mon Jan 11, 2021 1:43 pm
by pgimeno
Yes you can do that; you'd then need to yield after every asset is loaded.

You can also update the screen with love.graphics.present(), without using the update and draw callbacks. In that case you need to be careful to always call love.graphics.clear() to clear the screen before you draw the progress bar, though.