Delete and Recreate Images

Hello.
I’ve been searching the internet on how to delete images and I think I’ve found some good info. What I’m doing with my game is when the game is over a couple buttons appear with options like “next level,” “retry,” and “menu.” My problem is I want to get rid (or kind of hide them with out hogging memory) of the options, play the game, and have them reappear. I have some code of my own that i’ve been working on but I don’t know how to make the options reappear with out doubling the code on each of the buttons.

function touchHandler(e)  
 menuGroup = display.newGroup()  
if(e.phase == "began") then  
n = n - 5  
elseif(e.phase == "ended") then   
  
timer.performWithDelay(2000, spawnApple)  
score = 0  
scoreText.text = score  
score = score + 1  
--the delete function  
display.remove( btn )  
self = nil  
end  
end  
btn:addEventListener("touch", touchHandler)  

And I’m currently just doubling this code in the function will make the options appear. But again I don’t have good code to make the options reappear.

Thank you! [import]uid: 59140 topic_id: 14026 reply_id: 314026[/import]

Why not simply set the isVisible property to false to hide the button, then set it to true when you want it show it again.

 btn.isVisible = false  

and when you want to show it again:

 btn.isVisible = true  

You only have to load the images once, keep them around as long as you need them
[import]uid: 19626 topic_id: 14026 reply_id: 51670[/import]

I think its better to remove and recreate the image than hiding it.you can use object:removeSelf() to remove an object.
[import]uid: 71210 topic_id: 14026 reply_id: 51671[/import]

I’ll give hiding them a shot and see what it does to the memory. Renvis: are you saying I should stick with my code of removing the options and use some code to make them reappear? [import]uid: 59140 topic_id: 14026 reply_id: 51673[/import]

it depends on the trade-off between the size of the object loaded and how frequently it is shown and hidden…
[import]uid: 71210 topic_id: 14026 reply_id: 51677[/import]

@renvis hit it. Its about trade offs.

How much texture memory are you using? How big are the buttons? How often are the showing/hiding/loading/unloading?

consider loading/unloading: under the hood, they have to go open a file in the app bundle, load it, close it, decompress it, show it. When you delete it, garbage collection has to come along and remove it.

consider showing/hiding: only has to go through the above process once, but your memory foot print is larger and you have objects that may not be needed often taking up memory. So if memory is tight, load/unload, if its not, show/hide. Determine which beast you need to address: speed or memory.
[import]uid: 19626 topic_id: 14026 reply_id: 51679[/import]

well explained robmiracle !! :slight_smile:

[import]uid: 71210 topic_id: 14026 reply_id: 51685[/import]

Yeah explanation Rob! Now I know what options I have. Two small question though, I decided to go with load/unload but I don’t know the code to delete and clean them up so they aren’t hanging out there. I know self:removeSelf() but I don’t know how to code it so that it will get rid of it, I always get an error Runtime error
…kilkenny/Desktop/Today’s Tutorials/acc_ball/main.lua:148: attempt to index global ‘self’ (a nil value)
stack traceback:
[C]: ?
…kilkenny/Desktop/Today’s Tutorials/acc_ball/main.lua:148: in function <…kilkenny tutorials>
?: in function <?:215>

The images are about 8kb each, about 126x30, and they show up and the end of every level do you think that the load/unload is a good idea? And I put some code I found into my game just to see how much memory I was using when I used the show/hide option and this was the result…

memUsage = 80.983 KB
memUsage = 81.917 KB
memUsage = 82.851 KB
memUsage = 83.503 KB
memUsage = 83.335 KB
memUsage = 84.093 KB
memUsage = 84.862 KB

Is that a lot to show/hide one image?

This is the code i’m using
<br>local noMoreApples = function()<br><br>local btn = display.newImage("Menu.png")<br>btn.x = 105<br>btn.y = 27<br><br>function touchHandler(e)<br> menuGroup = display.newGroup()<br>if(e.phase == "began") then<br>n = n - 5<br>elseif(e.phase == "ended") then<br>timer.performWithDelay(2000, spawnApple)<br>score = 0<br>scoreText.text = score<br>--This is where I'm not sure what to do<br> self:removeSelf(btn) <br> -- print memory usage<br>collectgarbage( "collect" )<br><br> local memUsage_str = string.format( "memUsage = %.3f KB", collectgarbage( "count" ) )<br> print( memUsage_str )<br>end<br>end<br>btn:addEventListener("touch", touchHandler)<br><br>end<br>

[import]uid: 59140 topic_id: 14026 reply_id: 51768[/import] </…kilkenny>

I suspect memUsage is returning “Lua” memory. This is your variables, tables and so on. 80Kbytes is next to nothing. There is a second block of memory called “Texture Memory”. This is where all your images get allocated from (and probably audio too). There is an api call to get the texture memory. You should probably print that out as well. That will be in megabytes and is the big chunk of memory to have to worry about.

local noMoreApples = function()  
   
local btn = display.newImage("Menu.png")  
btn.x = 105  
btn.y = 27  
   
function touchHandler(e)  
 menuGroup = display.newGroup()  
 if(e.phase == "began") then  
 n = n - 5  
 elseif(e.phase == "ended") then  
 timer.performWithDelay(2000, spawnApple)  
 score = 0  
 scoreText.text = score  
 --This is where I'm not sure what to do  
 self:removeSelf(btn)   
 -- print memory usage  
 collectgarbage( "collect" )  
 local memUsage\_str = string.format( "memUsage = %.3f KB", collectgarbage( "count" ) )  
 print( memUsage\_str )  
 end  
end  
btn:addEventListener("touch", touchHandler)  
   
end  

I’m not 100% sure what “self” is when you “self:removeSelf(btn)”

touchHandler is a function of your main chunk and isn’t part of the btn object which is what I would suspect “self” to be pointing too. But regarless, you don’t pass any parameters to removeSelf().

So try:

self:removeSelf()

or btn:removeSelf()

or e.target:removeSelf()

The last is probably the best way to go in case touchHandler is ever going to work with objects other than btn. e.target is the object that registered the touch event.

Once you do that, you need to “Nil” the object by going:

btn = nil

or

e.target = nil

Once that’s done, the garbage collector will automatically clean up on its next scheduled run. You don’t have to manually call it. Though sometimes its best to call it at the end of a level manually, you just don’t want to over call it because it does slow down performance.
[import]uid: 19626 topic_id: 14026 reply_id: 51774[/import]

Ok sounds good I got everything in place. I did put in the code to check for usage and these are the figures I came up with…

textureMemory = 100.736 MB
textureMemory = 98.032 MB
textureMemory = 95.268 MB
textureMemory = 99.134 MB
textureMemory = 111.757 MB
textureMemory = 189.430 MB
textureMemory = 180.513 MB

Now I don’t know about you but that seems like a lot to me, but if you don’t think that’s bad then I’ll leave it. The only thing is that’s only one button, I have two more buttons of the same size and two lines of text that I have to delete and recreate.

Oh and this is the code to print the size

[code]
local textureMemory_str = string.format( “textureMemory = %.3f MB”, collectgarbage( “count” ) )
print( textureMemory_str ) [import]uid: 59140 topic_id: 14026 reply_id: 51830[/import]

Given that an iPhone 3, 3G only have 128M of memory, a 3GS and first gen iPad only have 256M and the iPhone 4 and iPad 2 have 512M, yea its a lot.

My entire space shooter game, OmniBlaster with all the audio and most of the art loaded uses between 12-25mb
I just looked at your code to print memory. You’re still printing the Lua memory ( garbagecollect(“count”) ). You need to be using:

system.getInfo(“textureMemoryUsed”)

[import]uid: 19626 topic_id: 14026 reply_id: 51831[/import]

Please forgive me for being a complete newbie but are you talking about the code looking like
print( system.getInfo( “textureMemoryUsed” ) ) [import]uid: 59140 topic_id: 14026 reply_id: 51837[/import]

Basically:

print("Texture Memory: " … system.getInfo(“textureMemoryUsed”))

it’s going to return a big number (in bytes), so if you want to scale it in megabytes:

print("Texture Memory: " .. string.format("%.3f MB", system.getInfo("textureMemoryUsed") / (1024\*1024) ) )  

[import]uid: 19626 topic_id: 14026 reply_id: 51839[/import]

Ah thats better! Much better result
Texture Memory: 1.112 MB

I think that’s the way to go then, loading/unloading, unless you think different. Thanks for the help and the explanations! I always like to learn along the way. [import]uid: 59140 topic_id: 14026 reply_id: 51841[/import]