Finding oldest instance of an entity?

Blitz3D Forums/Blitz3D Programming/Finding oldest instance of an entity?

OrcSlayer(Posted 2006) [#1]
Ok, in my game, I want to be able to delete the oldest of two types of entities...decals and spent casings. I have these entities created and working properly, but instead of using my normal "lifespan" setting to limit their existence, I want to be able to set a specific limit of entities and if that limit is reached, delete the oldest one before creating a new one, thus enforcing a maximum number of each entity type.

I have a few ideas about how to do this, but I'm not sure if they will work, and if they do they seem hacky at best. So, let me hear some ideas...how would you go about keeping track of which entity is oldest?


Steven Noyce(Posted 2006) [#2]
I havent done this, but couldn't you just use the first or last commands?


Steven Noyce(Posted 2006) [#3]
Here is a quick example. There will only ever be 10 "whatever"s. Push the left mouse button to add a new "whatever", and click the right mouse button to veiw each one and its "number" field.
howmany=0

Type whatever
	Field number
End Type

While Not KeyDown(1)
	If MouseHit(1)
		w.whatever=New whatever
		w\number=howmany
		howmany=howmany+1
		Print "new whatever created w/ num"+w\number
	EndIf
	If MouseHit(2)
		For w.whatever=Each whatever
			Print w\number
		Next
	EndIf
	If howmany>10
		w.whatever=First whatever
		howmany=howmany-1
		Delete w
		For w.whatever=Each whatever
			w\number=w\number-1
		Next
	EndIf
	Delay 1
Wend

Hope I helped. If not, just post!


OrcSlayer(Posted 2006) [#4]
I was unaware of these commands, oddly enough (I thought I'd researched every one...), but if they do what they sound like it might just work the way I need it to. So first will always be the "oldest" entity I created? The list will resort itself so that new items don't become "first" in the list?


Steven Noyce(Posted 2006) [#5]
Not sure, just a minute, I'll figure it out.


Steven Noyce(Posted 2006) [#6]
Ok, I am pretty sure that the first command will always give you the oldest one. Look at the following modification of my program.
howmany=0
Type whatever
	Field number
End Type

While Not KeyDown(1)
	If MouseHit(1)
		w.whatever=New whatever
		w\number=howmany
		howmany=howmany+1
		Print "new whatever created w/ num"+w\number
	EndIf
	If MouseHit(2)
		For w.whatever=Each whatever
			Print w\number
		Next
	EndIf
	If MouseHit(3)
		w.whatever=First whatever
		Print w\number
		Delete w
	EndIf
	For w.whatever=Each whatever
		w\number=w\number+1
		w\number=w\number-1
	Next
	Delay 1
Wend



OrcSlayer(Posted 2006) [#7]
Thanks for the info then! I'll try this out immediatly and let you know if it does what it needs to...


OrcSlayer(Posted 2006) [#8]
It works perfectly, thanks a lot!

Now, on a related note, what's the fastest way to count how many entities of a type there are? Currently I'm doing...

For d.Decal = Each Decal
Decals = Decals + 1
Next

And then checking if the resulting number is greater than the maximum allowed (and if it is, terminate the oldest decal). Seems like there should be a faster way to check...


Matty(Posted 2006) [#9]
There is a faster way which is this:

Each time an entity is created increment a variable by 1, each time an entity is destroyed decrement a variable by 1. This variable will then always have the number of entities/type instances whatever that are currently in the game.


OrcSlayer(Posted 2006) [#10]
Heh, I had done that a while back on some test project...probably never would have though of it again if you hadn't mentioned it. Thanks!


Stevie G(Posted 2006) [#11]
Use recycling ... saves all this counting stuff. A simple particle example from a program I've written. It won't work off the bat but should give you an idea of what to do ..

Initialise the type vars ..

Type Particle
	Field life#
	Field Model
End Type
Global PARTICLEnext.Particle 
Global PARTICLE


Set up the required max instances .. 10 in this case.
Function PARTICLEinit()

	PARTICLE = CreateSphere() 
	EntityColor PARTICLE , 255,128,0
	EntityFX PARTICLE, 4
	HideEntity PARTICLE
	For l = 1 To 10
		p.particle = New particle
		p\Model = CopyEntity ( PARTICLE )
	Next
	PARTICLEnext = First Particle
	PARTICLEreset()
		
End Function


Create and instance ...
Function PARTICLEcreate( parent )

	p.particle = PARTICLEnext 
	PositionEntity p\Model , EntityX( parent ) , EntityY( parent ) , EntityZ( parent )
	ScaleEntity p\Model, 1, 1, 1
	EntityAlpha p\Model, 1
	ShowEntity p\Model
	p\Life = 1.0
	PARTICLEnext = After p
	If PARTICLEnext = Null PARTICLEnext = First Particle

End Function 


Update the active particles ...
Function PARTICLEupdate()

	For p.particle = Each particle
		If p\Life > 0
			p\Life = LIMIT( p\Life - .025 ,0 , 1.0 ) 
			Scale# = 5 + 100 * Sin( p\Life * 180.0 )
			ScaleEntity p\Model, Scale, Scale, Scale
			EntityAlpha p\Model, p\Life
			If p\Life = 0	HideEntity p\Model
		EndIf
	Next

End Function


Reset them all ...
Function PARTICLEreset()

	For p.particle = Each particle
		p\Life = 0
		HideEntity p\Model
	Next

End Function


The key to the recycling are these lines in the creation function ..

PARTICLEnext = After p
	If PARTICLEnext = Null PARTICLEnext = First Particle


Stevie


Steven Noyce(Posted 2006) [#12]
I did not read all of Stevie's post, and mabe you don't need any more help, but here is a simple example that I think is the best way to do this.
Type whatever
	Field number
End Type

For whatevers=0 To 2
	w.whatever=New whatever
	w\number=Rand(0,10)
Next

While Not KeyDown(1)
	If MouseHit(1)
		w.whatever=First whatever
		Delete w
		w.whatever=New whatever
		w\number=Rand(0,10)
		Print "oldest destroyed, new one created"
	EndIf
	If MouseHit(2)
		For w.whatever=Each whatever
			Print w\number
		Next
	EndIf
	Delay 1
Wend

I hope this helps!


OrcSlayer(Posted 2006) [#13]
I have it all working just fine, thanks for the help everyone!