How do I destroy sprite sheets? And what about the timer in destroy function?

I love Spriteloq. It's a great tool. Makes it so simple to convert SWF animations to sprite sheets and use them in my game.

I use director class (awesome class), and I wondered how I may remove sprite sheets that are generated with loq_sprite when scene changes. So, I'm really happy about the destroy function that comes with loq_sprite API. But how do I use SpriteFactory:dispose() function? The way I use it gives me runtime error. I'm sure I'm not getting the syntax right, and I tried looking for a sample code, but I couldn't find any.

Here is how all of of my game levels require loq_sprite.lua locally and create animated objects using loq_sprite:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
--forward referenced near the top of the module
local loqsprite = require("loq_sprite");
local mySpriteFactory;
local numLoop;
local spin = {};
local bounce = {};
local game1Group;
 
--create spin object (placed way down in the module)
mySpriteFactory = loqsprite.newFactory("sheet_spin");
for numLoop=1,4 do
        spin[numLoop] = spriteFactory:newSpriteGroup();
        game1Group:insert(spin[numLoop]);
        spin[numLoop]:play();
end
 
--create bounce object (placed way down in the module)
mySpriteFactory = loqsprite.newFactory("sheet_bounce");
for numLoop=1,4 do
        bounce[numLoop] = spriteFactory:newSpriteGroup();
        game1Group:insert(bounce[numLoop]);
        bounce[numLoop]:play();
end

Hi ask,

Double check your spritesheet. It might have been exported with an older version of Spriteloq. In the recent releases, the spritesheet metadata has a destroy function that the Spriteloq API calls to dispose of the sheet. I suspect you'll have to import and reexport your spritesheet and everything will work out. Try that first before altering the code.

If you want to alter the code feel free, but beware it maybe altered in the future to take care of bugs or new features.

-don

Another heads up, you created two spritesheet factories but only disposed of one with the dispose call because you lost a reference to the first one. Also did you know you can load multiple sheets in one factory? And then the sprites of your factory can switch between sprites of either sheet? Also lua doesn't require semicolons unless you have more than one statement on a line.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
--forward referenced near the top of the module
local loqsprite = require("loq_sprite");
local mySpriteFactory
local mySpriteFactory2
local numLoop;
local spin = {};
local bounce = {};
local game1Group;
 
--create spin object (placed way down in the module)
mySpriteFactory = loqsprite.newFactory("sheet_spin");
for numLoop=1,4 do
        spin[numLoop] = spriteFactory:newSpriteGroup();
        game1Group:insert(spin[numLoop]);
        spin[numLoop]:play();
end
 
--create bounce object (placed way down in the module)
mySpriteFactory2 = loqsprite.newFactory("sheet_bounce");
for numLoop=1,4 do
        bounce[numLoop] = spriteFactory:newSpriteGroup();
        game1Group:insert(bounce[numLoop]);
        bounce[numLoop]:play();
end
 
mySpriteFactory:dispose()
mySpriteFactory2:dispose()

Oh I forgot to answer the second part of your question: What about the timer? The timer is unrelated to your destroy issue. That error is complaining that destroy is nil. In other words the destroy function doesn't exist, which clues me into the spritesheet not having that function.

The timer is there to clean up that other issue with Corona as noted in the code. If you call removeSelf on a SpriteGroup and later on call dispose on the SpriteFactory Corona complains that there's an attempt to remove a sprite that has already been removed if you call the Corona API's spritesheet dispose().

To get around the issue I discovered the timer.performWithDelay trick. It basically fires off that function on the next timer cycle (1 millisecond) so the above mentioned error doesn't occur.

After I re-exported the SWF files with the latest version of Spriteloq, it worked like a charm!

Thank you, Don!

Awesome! Looking forward to seeing what you do with Spriteloq!

About creating two separate spritesheet factories (rather than re-using the same spritesheet factory for each new spritesheet being created) -- thank you so much for the pointer.

I'll definitely change my code to create separate factory for each sprite sheet. The animated object appeared perfectly fine and worked the way I wanted them to work without changing the factory name that I thought that's how .newFactory function was meant to be used. I'm glad my misconception is being corrected.

About the unrequire, thanks also for this pointer. I thought by simply localizing the required external module (like loq_sprite), it would be garbage collected when I'm done with the module (like the game module). It sounds like loq_util is another class that I won't ever be able to live without.

Thanks again!

Hi again,

Just to clarify, you can add multiple sprite sheets to one SpriteFactory. For instance in a game you might have background elements in one sheet and character elements for your player and objects in their respective sheets.

So with three sprite sheets like:
sheet_background.png, sheet_background.lua
sheet_player.png, sheet_player.lua
sheet_objects.png, sheet_objects.lua

You can create one SpriteFactory:

1
2
3
4
5
6
7
8
9
10
11
-- This is in a level module: call it level_01.lua
 
local sf = require('loq_sprite').newFactory('sheet_background', 'sheet_player', 'sheet_objects')
 
-- create your sprites
local background = sf:newSpriteGroup('background')
local player = sf:newSpriteGroup('player idle')
local box = sf:newSpriteGroup('box')
 
-- then elsewhere in the code you can
sf:dispose()  -- cleans up all three sprite sheets

Now that I got a hang of it, adding multiple sprite sheets to one SpriteFactory works wonderfully. And it's so easy to manage. Awesome tool!

Thanks, Don!!!

Hi, Don!

You use "unrequire" but I think this command doen't exist, isn't it?

Of course it exists. I don't just imagine these things. :) http://www.loqheart.com/spriteloq/apidocs/files/loq_util-lua.html#unrequire

http://www.loqheart.com/spriteloq/apidocs/files/loq_util-lua.html#Unloading_modules_from_application_memory_with_unrequire

If you try to unrequire and you're not seeing the function you should redownload the Spriteloq API.

Hi, Don,

Ok. I don't use the Spriteloq API, but I want it to reload a .lua. I try with unrequire but it doesn't work, so I use package.loaded[myLuaFile]=nil

Don, I just made a good use of unrequire("myLuaFile") of loq_util API -- and it's awesome.

I now have 7 levels , and before I used unrequire function, as I play tested from level 1 through level 7 of my game, the memory climbed up to 10M (while texture memory is under control, thanks to director class).

After I implemented unrequire, playing from level 1 through level 7 still keeps the memory under 400KB.

Cheers!

Cool. I spoke to Walter and Jonathan about unrequire at the hackathon. Hopefully they can make it a standard part of the Corona API and educate the users about it.

Woops, I meant 1MB (not 10MB), which got reduced to 400KB. 10MB down to 400KB would've been insanely huge difference, eh? 1MB down to 400KB is still awesome in my book. Cheers.

views:2184 update:2011/10/12 9:17:43
corona forums © 2003-2011