Open st-pasha opened 2 years ago
Hello, I find your proposal very interesting. I currently use LoadingBuilder dividing the game into several phases loading the assets at the beginning of each one of them.
On the other hand, there is another question in Flutter regarding the delay that exists when loading the images inside a Widget, such as a Scroll. For this there is the precacheImage() function that has the problem that can cause the system to crash. https://twitter.com/NorbertoMartnAf/status/1295749275243216896
I'm not sure if a dedicated loading screen would be a good solution since it forces the developers to use that screen-based approach only. What about a fully styleable component which can be used (if wanted) on a loading screen (created and navigated to like all other screens with the new routing system) or anywhere else?
For not having tight coupling and therefore possibly having problems passing the loading progress to that new component i would use some event- or state-based approach (event_bus, ValueNotifier) if i had to develop that feature on my own.
@st-pasha I just made a draft implementation ☝🏽 It now works only with Flutter widgets but could be extended to work with widgets too. This is pure stream and subscriber in proxy widget with user-friendly notifier for user-made widget... a bit tricky inside but allows to hide all mess under hood =) Is the approach is ok, I will make PR and some code refactoring of course.
it is unclear how to use the loadingBuilder (or whether it is even possible) to show loading progress when loading internal components, such as a particular level within the game.
In my case loading a new game level means creating and loading new game class instance with new parameters, so loadingBuilder is called automatically as it was at first time
So, the idea here was to specifically make a loader Component, as opposed to a loader widget. We already support loading widget -- via the loadingBuilder
parameter -- though it doesn't accept progress indicator right now.
There are several reasons why we would want to have the LoaderComponent
instead of (or in addition to) a loading widget:
In my case loading a new game level means creating and loading new game class instance with new parameters, so loadingBuilder is called automatically as it was at first time
This would not work in general: it requires everything before the loading screen to not be a Game
, which may be applicable in some limited cases, but not in general. Ideally, we would want the solutions included in core Flame to be as general as possible.
I just add here my own experience with loading progress with heavy calculations. In general you can't implement this feature and to keep backward compatibility because onLoad function going to become more and more blocking while amount of it's operations grows. No matter if you use sync API or something async like streams - widget's tree just do not rebuilds.
The thing that helps to solve the problem is moving initialization logic from onLoad
to something like update
. And dividing you loading process to small chunks that lasts no longer than 16ms. After every loading operation you check Stopwatch
timer and execute next operation, if you have enough time. Otherwise you save the progress and allow Flame to complete game's lifecycle, Flutter rebuilds widget's tree then and in new update
cycle you restores the progress and continue loading.
Problem to solve
Often, a game needs some time to load its resources/assets. In this case some kind of a loading screen is necessary.
Currently, the only support from Flame for this functionality comes from the
loadingBuilder
parameter of theGameWidget
. However, this solution may be insufficient for the following reasons:Proposal
How exactly to solve this is TBD. Should this be a specialized
Route
within the Navigator? Or a mixin to a page? Or a page wrapper? Or a child?I'd be interested to hear how people solve this problem right now.