Share Your Code

Load Progress Bar

Posted by KenRogoway, Posted on October 12, 2011

GitHub URL: 
https://github.com/KenRogoway/Example---Load-Progress-Bar

This example shows you how to add a progress bar to your loading screen. The progress bar updates after each data chunk is loaded.

You can change the bUseListener value in cSceneLoad.lua to specify if you want the bar updated every frame, or just when each data chunk has been loaded (preferred method).

This example is licensed under the MIT license so you are free to modify it and use it however you like.


Replies

Naomi
User offline. Last seen 23 hours 39 min ago. Offline
Joined: 6 Jun 2011

Cool! Thanks for sharing!

carlos m. icaza
User offline. Last seen 2 years 2 weeks ago. Offline
Alumni
Joined: 22 Jun 2009

v nice !

Danny
User offline. Last seen 14 weeks 11 hours ago. Offline
Staff
Joined: 17 Aug 2011

Nice work :)

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

Thanks for the compliments. Whenever possible I plan on giving back to the Corona community by sharing (hopefully) useful routines.

@RSCdev
User offline. Last seen 1 year 15 weeks ago. Offline
Joined: 6 Sep 2011

Hey KenRogoway,

Thank you very much for this effort of you for the Corona Community that I am in! :)

Congrats for the coding time btw.

Regards,
Rodrigo.

magadistudio
User offline. Last seen 2 days 8 min ago. Offline
Joined: 10 Jul 2011

This is awesome! Thank you for taking the time to create this! It's very helpful! I will be using this on my projects, that's for sure!

Fixdit
User offline. Last seen 47 min 1 sec ago. Offline
Joined: 19 Jan 2011

Great work!
I wonder if you have tried implementing this with SpriteGrabber?: (http://developer.anscamobile.com/code/spritegrabber-spritesheets-two-lines

Thanks in advance,

necrozyablo
User offline. Last seen 2 years 10 weeks ago. Offline
Joined: 16 Nov 2011

Great this is what I was looking for!
One more question. How to use loaded data(sprite)?
How to access loaded data from cSceneGame.lua?

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@necrozyablo,

In cSceneGame.lua add this:

1
2
3
4
cAssetLoader = require( "cAssetLoader" )
 
    print( "cAssetLoader.DataChunk[1].file = ", cAssetLoader.DataChunk[1].file )
    print( "cAssetLoader.DataChunk[1].ptr = ", cAssetLoader.DataChunk[1].ptr )

This gives you direct access to the "ptr" value which is the display object, or sound object for that data element.

javierdamontereyes
User offline. Last seen 3 days 10 hours ago. Offline
Joined: 31 Aug 2011

@KenRogoway

could i use this to preload movieclips?

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@javier,

Yes, you can use this to preload movieclips too.

I have posted version 1.2 of the module here:

http://www.homebrewsoftware.com/Download/CoronaSDK/HomebrewLoadingBar_v1_2.zip

This version also shows how to actually use the data that gets loaded in your scene and includes examples of using images, sounds, and movieclips.

I also changed the code to set "isVisible" to false for images that are preloaded. When you want to display any of those images just make sure to set "isVisible" to true.

javierdamontereyes
User offline. Last seen 3 days 10 hours ago. Offline
Joined: 31 Aug 2011

Great! I'll give it a look. Thank you!

Fixdit
User offline. Last seen 47 min 1 sec ago. Offline
Joined: 19 Jan 2011

Once again, great work on the class. We're heavily utilising the SpriteGrabber extension in our games and wondered how your pre-loader class might be able to support it?

Thanks,

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@Fixdit,

Where can I see the SpriteGrabber stuff? I'll see about adding support for it later today.

Fixdit
User offline. Last seen 47 min 1 sec ago. Offline
Joined: 19 Jan 2011

SpriteGrabber: http://developer.anscamobile.com/code/spritegrabber-spritesheets-two-lines

It's the the best way to create and control sprites in Corona (in our opinion).
Let us know if support for this does make it in, we'd also be happy to assist if you'd like.

Thanks,

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@Fixdit,

I am almost done with the SpriteGrabber integration, but it would be really helpful if SpriteGrabber took one additional (optional) parameter to the grabSheet() function.

1
grabSheet(sheetName, *sheetExtension, *imageDir)

This would allow people to keep their sprite sheet images in sub folders (which is what I do)

Ken

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@Fixdit,

Now with SpriteGrabber support:

http://www.homebrewsoftware.com/Download/CoronaSDK/HomebrewLoadingBar_v1_21.zip

I'd still like SpriteGrabber to add an optional directory parameter so we can organize our image files, but at least you now have a version that works with the current version of SpriteGrabber.

Ken

Fixdit
User offline. Last seen 47 min 1 sec ago. Offline
Joined: 19 Jan 2011

@Magenda appears to actively support SpriteGrabber. It might be worth flagging it up on the comment thread: http://developer.anscamobile.com/code/spritegrabber-spritesheets-two-lines?page=2&destination=#comment-82732

Can't wait to try it the updates out.

Thanks,

necrozyablo
User offline. Last seen 2 years 10 weeks ago. Offline
Joined: 16 Nov 2011

Thanks. Good examples.
But could not make an example out of several scenes?
For example we have a 2 menu scenes And one game scene.
I am interested in how to load data(sound, img, etc) to menu scenes. And then they unload and move to the gaming scene.

I have a strange problem. in menu1:

1
2
local bg_image = cAssetLoader.GetChunkData( 2 ) 
localGroup:insert(bg_image)

in menu 2
1
2
function gotomenu1() director:changeScene("menu1",moveFromLeft ) end
timer.performWithDelay(2000,gotomenu1)

Its gain error:
director.lua:1092: in function 'changeScene'
Director ERROR: Failed to execute new( params ) function on 'index'.

But if I add to menu2

1
2
local bg_image = cAssetLoader.GetChunkData( 2 )
localGroup:insert(bg_image)

All runs without errors.

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@necrozyablo,

You typically get that type of Director error when something isn't loading properly in your module. Without see the code I cannot tell you what the problem might be.

I'll change the sample to have two data sets. Onc data set for one scene, and another data set for a second scene. Then I'll demonstrate how to use the cAssetLoader module to deal with each separately.

Ken

necrozyablo
User offline. Last seen 2 years 10 weeks ago. Offline
Joined: 16 Nov 2011

@KenRogoway in cSceneGame.lua

1
2
3
4
                if ( buttonSound ) then
                        audio.play( buttonSound )
                end --after
director:changeScene("index",moveFromLeft )--add

index.lua

1
2
3
4
5
6
7
8
9
10
11
12
module(..., package.seeall)
 
local localGroup = display.newGroup()
 
print ("Mem index: "..(system.getInfo("textureMemoryUsed")/1000000).." mb")
        
function goto() director:changeScene("cSceneGame" ) end
timer.performWithDelay(2000,goto)
 
function new()
    return localGroup
end

"I'll change the sample to have two data sets. Onc data set for one scene, and another data set for a second scene. Then I'll demonstrate how to use the cAssetLoader module to deal with each separately."
Could you give a link to this sample

Fixdit
User offline. Last seen 47 min 1 sec ago. Offline
Joined: 19 Jan 2011

Implemented and working great.

Thanks for revisiting this.

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@necrozyablo,

I figured out the issue. Not sure yet how to best resolve it.

Basically, what is happening is that director is removing the logoBackground from the group when you switch to a different scene. Ansca has this to say about that:


Remarks:

When an object is removed, the rendering-related resources of the removed object are deleted immediately. What remains of object is simply a plain Lua table with all non-display object properties (the metatable is set to nil and all properties relating to display object are removed). Thus, if there are still references to object in Lua, they will simply be references to a normal Lua table.

This means that you really cannot use the cAssetLoader for display objects if they are going to be added to a display group.

I have a couple of ideas that may work around this, but generally you wouldn't use the loaded for images, just sounds, sprite sheets and movieclips.

If any of my ideas pan out I will post a new version to deal with that issue.

Otherwise, another "solution" is to use the cAssetLoader with a separate set of data for your scene, if you have a lot of items to load in that scene. To facilitate this I can make the cAssetLoader module take an optional parameter in the LoadInit() call that would be a table of your assets; similar to the one used in cAssetLoader.lua.

One last point. The original purpose of this example was not to create a module to load all of your game assets. It was really intended to show people how to update a loading bar during asset loading; hence the name of the topic.

Fixdit
User offline. Last seen 47 min 1 sec ago. Offline
Joined: 19 Jan 2011

Sorry KenRogoway,
What is conclusion of your Remarks? Does this effect how we should use the class?

Thanks,

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@Fixdit,

You can still use this module as-is for sound, sprite sheets, SpriteGrabber, and mediaclips.

Until (and IF) I have a work-around for images, you can't use it for them "as-is". A minor rework would let you use it for any asset type, but you'd have to reload images when re-entering a director scene.

Ken

Fixdit
User offline. Last seen 47 min 1 sec ago. Offline
Joined: 19 Jan 2011

That's clear, thanks Ken.

javierdamontereyes
User offline. Last seen 3 days 10 hours ago. Offline
Joined: 31 Aug 2011

@KenRogoway

sorry to pester you with my amateurism, but..

my movieclips are quite long (im trying to load an animated background )... am i supposed to declare, say, 89 jpgs one by one in cAssetLoader?

or could i first create an imagetable like this

imageTable2 = {}
for i = 00,89 do
table.insert( imageTable2,"sharkanim/sharkanim" .. i .. ".png" )
end

and somehow load it in this manner?

thank you so much for your help...

necrozyablo
User offline. Last seen 2 years 10 weeks ago. Offline
Joined: 16 Nov 2011

Thanks for the explanation
What if instead of director to use storyboard?
it will come to the same problem?

I understand that instead of uploading images directly(FILE_TYPE_IMAGE,FILE_TYPE_IMAGE_RECT), we can put them all in spritesheet(FILE_TYPE_SHEET,FILE_TYPE_SPRITE_GRABBER). And then call them.

Or if only a few images that can be accessed directly directly (image = display.newImageRect( path, x, y)) on each scene?

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@javier,

You can create your data list any way you want, then use the cAssetLoader to load those assets.

I explicitly set each entry in my DataChunk table, but you could dynamically add those entries and it would still work fine.

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@necrozyablo and @Fixdit,

I have totally rewritten the cAssetLoader. It now allows you to have multiple asset loaders. This is useful if you want to use the asset loader to load images for a scene, (which will need to be reloaded if you exit and return to the scene) and Global assets.

If you look at the latest you will see an example of using both Global and scene specific assets, loaded by two different instances of the cAssetLoader.

http://www.homebrewsoftware.com/Download/CoronaSDK/HomebrewLoadingBar_v1_30.zip

NOTE:
What originally started as a fairly straight forward example of using a callback to update a progress bar, has now become a fairly useful general purpose asset loader.

necrozyablo
User offline. Last seen 2 years 10 weeks ago. Offline
Joined: 16 Nov 2011

Oh new code is great. but there are some minor question:

1)Why not see cube?

1
2
3
4
myClip.x = display.contentCenterX*0.5
myClip.y = display.contentCenterY
myClip.isVisible = true
myClip:play()

2)about loading and memory
if change in cAssetLoader:

1
2
3
4
5
print( "nLoadIndex = ", assets.nLoadIndex )
if (assets.nLoadIndex == 1) then --add string
    print ("Mem before load: "..(system.getInfo("textureMemoryUsed")/1000000).." mb") --add string
end --add string
if ( assets.nLoadIndex >= 1 and assets.nLoadIndex <= assets.nLoadCount ) then
and
1
2
3
4
5
            -- Get ready for the next chunk
print ("Mem after load: "..(system.getInfo("textureMemoryUsed")/1000000).." mb") --add string   
            if ( assets.nLoadIndex < assets.nLoadCount ) then
                assets.nLoadIndex = assets.nLoadIndex + 1                       
                timer.performWithDelay( assets.nDelay, loadChunk )

in debug screen we have:
dataList = table: 00EAC818
delay = 500
loadCallback = function: 00ED1050
nLoadIndex = 1
Mem before load: 8.454144 mb
Mem after load: 10.551296 mb
nLoadIndex = 2
Mem after load: 12.648448 mb
nLoadIndex = 3
Mem after load: 14.7456 mb
nLoadIndex = 4
Mem after load: 16.842752 mb
nLoadIndex = 5
Mem after load: 16.842752 mb
nLoadIndex = 6
Mem after load: 16.842752 mb
nLoadIndex = 7
Mem after load: 17.235968 mb
dataList = table: 09CE0860
delay = 33
loadCallback = function: 00E27650
nLoadIndex = 1
Mem before load: 17.235968 mb
Mem after load: 21.430272 mb
nLoadIndex = 2
Mem after load: 16.859136 mb
Mem onTapListener: 16.859136 mb
Mem onTapListener: 16.859136 mb
Mem index: 16.859136 mb
Now in index.lua
dataList = table: 09CE0860
delay = 33
loadCallback = function: 00E27538
nLoadIndex = 1
Mem before load: 8.388608 mb
Mem after load: 12.582912 mb
nLoadIndex = 2
Mem after load: 16.859136 mb

Why when you first boot the elements 1 and 2 hold in memory at 2mb, and 4mb about the secondary?

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

I still need to implement the unload() function so it cleans up memory.

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@necrozyablo,

I've posted version 1.31 that addresses these issues.

http://www.homebrewsoftware.com/Download/CoronaSDK/HomebrewLoadingBar_v1_31.zip

The problem with the movieclip was that it was loaded with the global assets. There isn't any way to take a global image, or movieclip and use it on a per scene basis because when the scene is exited or destroyed it would remove the image data, so you'd no longer have it available to use again.

It would be very handy if Ansca could add a clone() or duplicate() function for display objects. This would allow the asset loader to return a duplicate image so when that was cleaned up the original data would still be there. Sadly that isn't in the list of features Ansca is working on so I doubt we will have a solution for this anytime soon.

Ken

javierdamontereyes
User offline. Last seen 3 days 10 hours ago. Offline
Joined: 31 Aug 2011

@KenRogoway

Hi ken,

how would yo go about dinamically loading the movieclip in assetLoader?
i have tried and tried.
This is one of my attempts:

-- first i made the imagetable under the sheetdata statements:

imageTable = { }
for i = 01,03 do
table.insert( imageTable, "/Images/cube" .. i .. ".png" )
end
firstClip = imageTable

--then, in the MovieClip data table:

MovieClipData =
{
{firstClip},
}

there's probably something very wrong in my logic.. i would really appreciate any suggestion... thank you!

Fixdit
User offline. Last seen 47 min 2 sec ago. Offline
Joined: 19 Jan 2011

@javierdamontereyes

This works for us:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
setOfSprites =
{
        { name="sprite_sheet",  ext=".png" },
        { name="sprite_sheet_2",        ext=".png" },
        { name="sprite_sheet_3",        ext=".png" },
        { name="sprite_sheet_4",        ext=".png" },
}
 
GlobalData = {};
 
for k,v in ipairs(setOfSprites) do
 
GlobalData[k] = { type=AL.FILE_TYPE_SPRITE_GRABBER,data=v, ptr=nil };
 
end

javierdamontereyes
User offline. Last seen 3 days 10 hours ago. Offline
Joined: 31 Aug 2011

@Fixdit

this might get closer.. but really what i want to avoid is having to declare all the pngs one by one ( my movieclips have about 80 frames)... but your code might point me in a good direction... i'll keep trying, thanks :)

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@javierdamontereyes,

Try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
imageTable1 = {}
for i=1,3 do
    imageTable1[i] = string.format( "Images/cube%d.png", i )
end
imageTable2 = {}
for i=1,3 do
    imageTable2[i] = string.format( "Images/box%d.png", i )
end
 
MovieClipData =
{
   imageTable1,
   imageTable2
}

The main different is that there should NOT be a "/" in front of the Image folder.

BTW, there aren't any box images, I just added that to the above sample so you can get a sense of how to do this for multiple movie clips.

necrozyablo
User offline. Last seen 2 years 10 weeks ago. Offline
Joined: 16 Nov 2011

@KenRogoway
What do you think about use:
local params = {all_images_etc}
director:changeScene(params,next_scene)

And then transfer the data between the scenes.
Transfer images between local scenes for which we loaded data. For example the "menu" of 3-4 scenes.
When we pass in a "game" scene then unload it all. When we return to "menu"-> start load again.

KenRogoway
User offline. Last seen 1 year 11 weeks ago. Offline
Joined: 17 Jan 2011

@necrozyablo,

I'm not sure I follow you. But if you want to modify director to support that it seems okay. It's beyond the scope of what this sample was for, but since you have the source to director.lua you can modify it anyway you want.

javierdamontereyes
User offline. Last seen 3 days 10 hours ago. Offline
Joined: 31 Aug 2011

@KenRogoway

It still wont work :( i get this:

Runtime error
bad argument #-1 to '_newImage' (Proxy expected, got nil)
stack traceback:
[C]: ?
[C]: in function '_newImage'
?: in function 'newImage'
...PROGRAMACION\HomebrewLoadingBar_v1_2 2\movieclip.lua:42: in function
'newAnim'

Perhaps i should change the way the movieclip data is called from cSceneGame?

javierdamontereyes
User offline. Last seen 3 days 10 hours ago. Offline
Joined: 31 Aug 2011

@KenRogoway

I haven't managed yet to load the pictures dynamically.
i've resorted to loading them manually one by one,
which is a drag, but works fine...
I'm not sure if i'm doing it incorrectly or if there's something
in the preloader which makes it impossible to load the pics with a "for" loop..

javierdamontereyes
User offline. Last seen 3 days 10 hours ago. Offline
Joined: 31 Aug 2011

@KenRogoway

I haven't managed yet to load the pictures dynamically.
i've resorted to loading them manually one by one,
which is a drag, but works fine...
I'm not sure if i'm doing it incorrectly or if there's something
in the preloader which makes it impossible to load the pics with a "for" loop..

Koichi
User offline. Last seen 1 year 42 weeks ago. Offline
Joined: 26 Nov 2011

I get the same issue loading into newAnim w/ for loop