Mysterious sprite resurrection with spriteExists()?
-
During the hunt of memory leaks, I discovered the very useful function
spriteExists()
in the manual. I expected thatspriteExists()
can be used to check if a sprite has already been removed or not. But somehow there is a bug or misunderstanding of how to use handles.
Appendix: Clarification:spriteExists()
returns true instead of false for removed sprites, when another sprite is created meanwhile.a = createSprite() print("sprite a exists = ", spriteExists(a)) print() removeSprite(a) print("sprite a exists = ", spriteExists(a)) b = createSprite() print() print("sprite a exists = ", spriteExists(a) ," resurrection!") print() print("sprite b exists = ", spriteExists(b)) updateSprites() // tried with this in other places as well update() // tried with this in other places as well sleep(10)
This prints:
sprite a exists = 1 sprite a exists = 0 sprite a exists = 1 resurrection! sprite b exists = 1
Removing "a" twice, results in a never existing "b".
a = createSprite() print("sprite a exists = ", spriteExists(a)) print() removeSprite(a) print("sprite a exists = ", spriteExists(a)) b = createSprite() print() print("sprite a exists = ", spriteExists(a) ," resurrection!") removeSprite(a) print() print("sprite b exists = ", spriteExists(b)) updateSprites() // tried with this in other places as well update() // tried with this in other places as well sleep(10)
This prints:
sprite a exists = 1 sprite a exists = 0 sprite a exists = 1 resurrection! sprite b exists = 0
Thank you for checking :-)
-
It looks like
createSprite()
generates a handle. If that handle is removed withremoveSprite()
, the handle is actually free again. But then, it creates the same handle on the nextcreateSprite()
call. Usually for me things worked well, until I started to create and remove sprites in the same game loop. Not sure now, if its the handle handling or the spriteExists().
Appendix: my workaround is now to do all createSprite() calls first and all removeSprite() calls after and not free up and re-use memory until going to the next level or restart of the game. -
My final conclusion and workaround suggestion: the sequence of createSprite () and removeSprite () does not matter. Just avoid spriteExists() right now (FUZE 3.1.0) and add
your own user variable, e.g. spritename.deleted (use whatever name you want) totrack it by yourself.Appendix: Nope, because how to check spr.deleted if spr has been removed? 🙄 Actually, you have to put the sprite into a struct and add the deleted attribute to the struct, like this:
sprite = createSprite() spriteElement = [.spr = sprite, .deleted = false] cleanSpriteElement(spriteElement) function cleanSpriteElement(ref element) { removeSprite(element.spr) element.deleted = true }
-
I never even heard of that function before. I'm guessing it is undocumented and unsupported...
How did you even find out about it in the first place? -
@vinicity Help->Command Reference->2D Graphics->Sprites->spriteExists
-
Huh, I must have totally missed that!
-
My workaround needed some adoptions, see above. Actually I wonder now, if I completely over-engineer things. Did anybody free up memory during the game? I mean before restarting the game level, where you could remove all objects at once?
-
I mean, it depends on the game. For White-Out with thousands of enemies it was certainly necessary…