Removing Sprite form list

Monkey Forums/Monkey Programming/Removing Sprite form list

Virtech(Posted 2011) [#1]
Apologies for the dumb question...

I want to modify Mark's Bouncy Aliens sample, so that I can (touch/mouseclick) any sprite and immediately delete it.

But I cant figure out how to delete a particular sprite from the list.

There is this...
If Not sprites.IsEmpty() sprites.Pop 

But that removes the last entry in the list.


Perturbatio(Posted 2011) [#2]
The sprites are stored in a stack, not a list.

You need to know it's index, then you can use stack.remove(index)

If you add an index field to the Sprite class, then assign the index to the sprite when it's created, you can then remove it easily.


Sledge(Posted 2011) [#3]
EDIT: Beaten to it by Pertster!

EDIT 2:
If you add an index field to the Sprite class, then assign the index to the sprite when it's created, you can then remove it easily.
Oh but don't forget to update all the index values as the stack contents get nudged along to fill the gap.

Actually I would advise the topic starter to get into the habit of pooling and reusing objects rather than instantiating and destroying them -- write some code to deactivate clicked sprites, not blitz 'em :D


slenkar(Posted 2011) [#4]
Pop means remove the top object
Push means put an object on top of the stack

(just in case you wondered)


Virtech(Posted 2011) [#5]
Thanks all for the fast response:)

I figured it out myself actually:p
Yes it is ofcourse a stack.

so i cooked this..
		For Local i:=0 to sprites.Length()-1
			If TouchHit(0)
				local sprite:=sprites.Get(i)
				if TouchX(0)>(sprite.x-30) And TouchX(0)<(sprite.x+30)
					if TouchY(0)>(sprite.y-30) And TouchY(0)<(sprite.y+30)
						sprites.Remove(i)
					endif
				EndIf
			Endif		
		Next

How does the grammar look?

[EDIT]

Made some changes to make it faster, preventing removing of more than 1 overlapping images and multi finger support :D
		For local t:=0 To 3
			If TouchHit(t)
				For Local i:=0 to sprites.Length()-1				
					local sprite:=sprites.Get(i)
					local w2:Float=(image.Width*sprite.sx)/2.0
					local h2:Float=(image.Height*sprite.sy)/2.0
					if TouchX(t)>(sprite.x-w2) And TouchX(t)<(sprite.x+w2)
						if TouchY(t)>(sprite.y-h2) And TouchY(t)<(sprite.y+h2)
							sprites.Remove(i)
							Exit
						endif
					EndIf		
				Next
			Endif
		next



Virtech(Posted 2011) [#6]

Actually I would advise the topic starter to get into the habit of pooling and reusing objects rather than instantiating and destroying them -- write some code to deactivate clicked sprites, not blitz 'em :D



I had to think about this and digest for little while;) To me it seems that dynamically adding/removing items would be the ideal thing to do, from an resource point of view. Care to elaborate what the downside of deleting an item vs code-deactivating like you suggest?

Thanks all for explaining me how stacks work. I've been living in a cave with a copy of blitz3D for a long time :D


Perturbatio(Posted 2011) [#7]
The downside is in the construction of the class instance, it's more of a performance hit in some languages than others (there was a youtube video linked to on this forum which discusses android game performance, and one of the things mentioned was that instantiating costs you a lot).

If you have a pool of inactive pre-created instances and a list of active ones you can simple shift the inactive to the active by changing their associated list.


Virtech(Posted 2011) [#8]
Thanks, I *think* I get it. It does make sense that creating classes on the fly may have a performance hit. I would assume this to be instantaneous. Also I would assume the hit to be proportional to the class complexity.

When I figure out how to write in code what you suggest, I'll do some benchmark tests.


Raz(Posted 2011) [#9]
If you have a pool of inactive pre-created instances and a list of active ones you can simple shift the inactive to the active by changing their associated list.


How do you move an item from one list to another? It sounds like a better way to do what I have below.

Currently I am using a global array of items where each item has an active bool flag. This array is iterated through, and if the item is active, it is drawn/updated.

When it comes to creating another instance of the item, I just loop through the array until I find an inactive entry, at which point I activate it with whatever values I need.


Hima(Posted 2011) [#10]
You could have one list that act as a pool. Instead of destroying an object, you have to put it into the pool. Then, write a factory method that check whether the pool is empty or not. If not, then select an existed object from the pool, and activate it with values you need. If the pool is empty, then create a new one and initialize it with the values you need.

The pool can just be a stack so you can just push and pop the object, since the order doesn't really matter. This way you don't need to iterate through the array to find the inactive object :D


Raz(Posted 2011) [#11]
Sounds like I should be using stacks instead of arrays then :)