loading screen

Monkey Forums/Monkey Programming/loading screen

frank(Posted 2013) [#1]
Sorry if this has been asked many times, but I see that by far most Monkey games lack loading screens; is there a standard way to get those in? It seems very annoying to just show a black screen until everything is loaded?

Maybe it's easy and I just couldn't find it in the forum?


Xaron(Posted 2013) [#2]
I have a small routine, which displays a loading screen for at least 3 seconds (or till the loading is finished - whichever takes longer!), loads everything and switches to the game then.

Let me look for that...

edit: so that's my function for it:




frank(Posted 2013) [#3]
Thanks very much!


C10B(Posted 2013) [#4]
On iOS you provide an image of the right size at compile time, and this automatically works as a loading screen. Very handy.


Playniax(Posted 2013) [#5]
Ignition has a very nice loader system :)


ondesic(Posted 2013) [#6]
Xaron,

Where do you place this code? Where do you call it?


Xaron(Posted 2013) [#7]
I just put it into OnRender:

  Method OnRender:Int()
    Cls()
    Select gGameState
      Case GAME_STATE_LOAD
        LoadScreen()
      Case GAME_STATE_GAME
        GameMain()
    End Select
    Return 0
  End Method



Midimaster(Posted 2013) [#8]
Thats no good practice!!!

This moment I'm struggling around with the same problem. If you work on HTML5 or Windows target it may work, but on Android you have to put all your loadings into OnCreate(). Putting loadings into OnCreate() and OnRender may interrupt the Smartphone for a too long time!!!

But if you do it right, the first call of OnRender() or OnUpdate() appears after all datas are loaded. This may last upto 10sec. So the only way to do it correct is async loading!!!

In OnCreate() you load your title image conservative. For all other loadings you use Async loading. The app will reach OnUpdate() and OnRender() very fast. In OnUpdate you can check, if all files are already loaded and set a flag%. In OnRender() you can display only the title image and RETURN immediately until the flag% is not set.

This sample is a simulation. It worksalso without the sounds!!!

Strict
Import mojo

Class Game Extends App

	Field Timer%, SoundServer:MySound
	
	Method OnCreate%()
		SetUpdateRate 15
		SoundServer=MySound.Create()

		Return 0
	End	

	Method OnUpdate%()
		If KeyHit(KEY_ESCAPE) Then Error ""
		UpdateAsyncEvents
		Return 0
	End	

	Method OnRender%()
		If Timer=0
			Timer=Millisecs()
		Endif
		If SoundServer.LoadNr=SoundServer.LAST_SOUND_NUMMER
			Timer=Millisecs()
			'PlaySound SoundServer.Klavier[41] 
		Elseif SoundServer.LoadNr>SoundServer.LAST_SOUND_NUMMER
			Cls 0,255,0
		Else
			Cls 255,5,5
		Endif
		Scale 4,4
		
		DrawText Timer,0,0
		Return 0
	End	
	
End




Function Main%()
	New Game
	Return 0
End




Class MySound Implements IOnLoadSoundComplete

	Const LAST_SOUND_NUMMER%=42
	Global LoadNr%
	
	Global Klavier:Sound[LAST_SOUND_NUMMER+1]

	Method OnLoadSoundComplete:Void ( sound:Sound, path:String, source:IAsyncEventSource )
		Print "loaded=" + path
		Klavier[LoadNr]=sound
		LoadNr=LoadNr+1
		If LoadNr<=LAST_SOUND_NUMMER

		' time comsumption simulation
			Local z%=Millisecs()+200
			Repeat
			Until z<Millisecs()
		' time comsuption end

		If LoadNr<=LAST_SOUND_NUMMER

			LoadNext 
		Endif
			
	End

	Function Create:MySound()
		Local loc:MySound=New MySound
		loc.LoadNext
		Return loc
	End
	
	
	Method LoadNext:Void()
		LoadSoundAsync  "PianoW" + LoadNr + ".ogg", Self
	End
End




Xaron(Posted 2013) [#9]
Well async loading is something new I haven't tested yet. Beside that I never came across any problems on any Android device with my apps.

But thanks for notifying, I'll look into that!


ondesic(Posted 2013) [#10]
I am struggling to understand this async loading. It seems like a lot is involved. I was looking in the banana folder for a simple example or a good explaination in the docs. I just want a splash screen until the other resourses load.


Midimaster(Posted 2013) [#11]
The sample is as short as it can be!

I can explain it:
Class Game Extends App

	Field ..., SoundServer:MySound
	
	Method OnCreate%()
		...
		SoundServer=MySound.Create()
....

You need an object to receive messages from the system, that a loading job has finished. Therefore you define any of your classes as the "responsible" class. In My sample it took the MySound class. Because this instance will receive messages again and again, you should care about, that the instance "lives" long. The main class Game contains one instance of this class. A local instance f.e. in OnCreate() would not be sufficient.




Class MySound Implements IOnLoadSoundComplete

	Const LAST_SOUND_NUMMER%=42
	Global LoadNr%
	
	Global Klavier:Sound[LAST_SOUND_NUMMER+1]
.....

The Class MySound is responsible for the async loading. I implement the system interface IOnLoadSoundComplete. I have to load 42 sounds, which I will store in Klavier:Sound[]. A counter LoadNr% will check, how many are already loaded.




Class MySound Implements IOnLoadSoundComplete
....
	Function Create:MySound()
		Local loc:MySound=New MySound
		loc.LoadNext
		Return loc
	End
	
	
	Method LoadNext:Void()
		LoadSoundAsync  "PianoW" + LoadNr + ".ogg", Self
	End

The Game.OnCreate() will call the Function MySound.Create(). This function will kick off the first loading job and return the "receiver" object later known as Soundserver .
The loading Method LoadNext() looks as harmless as the old fashioned LoadSound(). But! Additional it has to inform the system about which receiver object will be responsibe for this job ( Self respectively loc respectively Soundserver).




Class Game Extends App
...

	Method OnUpdate%()
		....
		UpdateAsyncEvents

Next step is: The OnUpdate() needs to continously call the UpdateAsyncEvents(). This system function watches the progress of any async jobs. If there is a job finished the UpdateAsyncEvents will call a method of the object the job is associated with.




Class MySound Implements IOnLoadSoundComplete
...
	Method OnLoadSoundComplete:Void ( sound:Sound, path:String, source:IAsyncEventSource )
		Print "loaded=" + path
		Klavier[LoadNr]=sound
		LoadNr=LoadNr+1
		If LoadNr<=LAST_SOUND_NUMMER
			LoadNext 
		Endif

This is the "call back" function. The system will call it, whenever a async sound loading job has finished. The OnLoadSoundComplete() Method is a method of your Soundserver instance. You exactly have to use this name.

The method receives the sound. If no file was found, sound would be NULL. And the method recieves also the formally path, if you want to control which loading job this is.

At the end the method kicks off the next loading job.

Ready



[/code]

[code]


[/code]

[code]



ondesic(Posted 2013) [#12]
Thank you Midimaster. I am beginning to grasp it. My last question would be. How do I apply this to a splash screen where I only need one image to display while the others are loading in the background?


ondesic(Posted 2013) [#13]
Any more help would be greatly appreciated.


dave.h(Posted 2013) [#14]
@ondesic

hi mate if you want i have a very simple to understand demo of a splashscreen that should work on all platforms.It comes with the artwork and has comments in.If you want it i will send it to you by email .my email is

froggytheustus@...

slightly different from the above example as it is only used to show a splashscreen for 4 seconds or until all the data is loaded.It is much smaller so might be easier to follow.Ive tested it on flash,html5,android and ios so far and had no probs.


Midimaster(Posted 2013) [#15]
well the splash-screen is alread in this sample! It is the red colored period:

Method OnRender%()
.....
	If SoundServer.LoadNr=SoundServer.LAST_SOUND_NUMMER
		' the moment, when the last sound has arrived
	Elseif SoundServer.LoadNr>SoundServer.LAST_SOUND_NUMMER
		Cls 0,255,0
		' all sounds are loaded
		' show game contents here
	Else
		Cls 255,5,5
		' the loading is not finished
		' draw your splashscreen here
	Endif
	Return 0
End



dave.h(Posted 2013) [#16]
@ondesic

i sent it but im not sure it gone through.If you didnt get it just let me know and i will resend


Xaron(Posted 2013) [#17]
That async stuff looks pretty good and thanks for that example Midimaster, I'll rewrite all my loading routines even though I had never problems on any device.


Midimaster(Posted 2013) [#18]
I'm a beginner in this stuff. This is also my first attempt to load asynchronous.

As I see the file name is also returned in the call back function, it could be possible, that we are allowed to init all loading tasks at the same moment. Then we will wait for the callbacks and differ the returning data by the filenames. This perhaps could be much faster than my sample.