network image loader with preloader (using coroutine)

Hi,

here’s an example of how to use a coroutine to update the preloader whilst loading a number of images across the network

[lua]display.setStatusBar( display.HiddenStatusBar )

– Load the relevant LuaSocket modules
local http = require(“socket.http”)
local ltn12 = require(“ltn12”)

local imgpath = “http://developer.anscamobile.com/sites/default/files/

local imgs = {

“graphics-OV.png”,
“hardware-OV_1.png”,
“interface_overview.png”,
“media_OV.png”,
“network-OverView.png”,
“openfeint_OV.png”,
“physics_overview.png”,
“platform-specific_overview.png”

}

local preloaderScale = 0
local imagesLoaded=0

– setup preloader graphics
local preloader = display.newGroup()

local preloaderbg = display.newRect(50,20,100,10)
preloaderbg:setFillColor(100,0,0)

local preloaderfg = display.newRect(50,20,100,10)
preloaderfg:setFillColor(255,0,0)
preloaderfg:setReferencePoint(display.TopLeftReferencePoint)

preloader:insert(preloaderbg)
preloader:insert(preloaderfg)

preloader.x=60
preloader.y=220

– create co-routine
loader = coroutine.create(function()

repeat

– Create local file for saving data
local path = system.pathForFile( imgs[imagesLoaded+1], system.DocumentsDirectory )
myFile = io.open( path, “w+b” )

print("loading image: "…imgs[imagesLoaded+1])

– Request remote file and save data to local file
http.request{
url = imgpath…imgs[imagesLoaded+1],
sink = ltn12.sink.file(myFile),
}

– Display local file
–testImage = display.newImage(imgs[imagesLoaded+1],system.DocumentsDirectory,0,imagesLoaded*30);

imagesLoaded=imagesLoaded+1
print(“images loaded=”…imagesLoaded)

– pass control back to update function
coroutine.yield()

until(imagesLoaded>#imgs)
end
)
function init()

local testimage

– display the preloaded images
for i=1, #imgs, 1 do
testImage = display.newImage(imgs[i],system.DocumentsDirectory,50,25+(i-1)*50);
testImage.yScale=0.5
end

end

function loading(event)

– call the coroutine
coroutine.resume(loader)

preloaderScale = imagesLoaded * (1/#imgs)

if(preloaderScale >= 1) then
print("-- FINISHED --")
Runtime:removeEventListener(“enterFrame”,loading)
preloader:removeSelf()
init()
end

if(preloaderScale==0) then
preloaderfg.isVisible=false
else
preloaderfg.isVisible=true
preloaderfg.xScale = preloaderScale
end

end

Runtime:addEventListener(“enterFrame”, loading)[/lua] [import]uid: 6645 topic_id: 3636 reply_id: 303636[/import]

how is this working on an actual device?? Would it work better if you fetched fractions of each file during the event?? This code seems to be blocking the enterframe event once for each whole image. I would expect the app to behave very choppy and stutter while this code is running…what are you observing?? [import]uid: 6175 topic_id: 3636 reply_id: 11267[/import]

well yes it was just an example

i wasnt suggesting in this case doing anything else whilst the image is loading… this would be just like a preloader before anything started, but at least the user had some constant feedback rather than nothing happening at all

if you can use the socket to partial load the image in chunks, even better. i wouldn’t know how but please share any findings

thanks
j [import]uid: 6645 topic_id: 3636 reply_id: 11361[/import]

@jmp909,

Thanks for sharing this. It is an interesting idea and I think it has some interesting applications.

i.e. You could use it instead to update a HUD while doing a long set of calculations, or loading/building a level. The trick would be to keep the frame-by-frame chunks shorter than a frame period.

-Ed

PS - For some reason I thought co-routines (under Corona) did not work on devices though. Now I have to double-check. [import]uid: 110228 topic_id: 3636 reply_id: 133028[/import]

@jmp909,

Thanks for sharing this. It is an interesting idea and I think it has some interesting applications.

i.e. You could use it instead to update a HUD while doing a long set of calculations, or loading/building a level. The trick would be to keep the frame-by-frame chunks shorter than a frame period.

-Ed

PS - For some reason I thought co-routines (under Corona) did not work on devices though. Now I have to double-check. [import]uid: 110228 topic_id: 3636 reply_id: 133028[/import]