Particles spawning other particles?

Blitz3D Forums/Blitz3D Programming/Particles spawning other particles?

AdsAdamJ(Posted 2005) [#1]
I'm currently trying to build a particle system up, and up until now it's worked great. It's only simple really, when the sprites alpha reaches 0, then particle & entity are deleted.

Anyway, I have a Fire sprite that I want to spawn a smoke sprite halfway through it's 'life'. I have it set up so when the alpha drops below a certain value and the spawn flag hasn't been triggered (FALSE), it creates a new particle and sets the spawned flag to triggered (TRUE).
The problem is, it seems to be ignoring the triggered flag and spawning dozens, if not a couple of hundred smoke sprites! They stop eventually and continue to fade away as normal, but I only want each fire sprite to spawn one smoke sprite.
I've checked all the varible names, etc. and in theory it should work, but this has flummoxed me completely!

Could it be something to do with the way Blitz handles 'for...each' loops? I'm creating a new particle (and therefore adding to the type list) mid-loop. I've tried adding the code to a seperate loop but it's doing the same thing still. I'm not sure why it's doing this. Here's the bit of code in question:

	For particle.particle_dat = Each particle_dat
		Select particle\ptype
			Case FIRE
				particle\r			= tween(particle\tr, particle\r, .05)
				particle\g			= tween(particle\tg, particle\g, .05)
				particle\b			= tween(particle\tb, particle\b, .05)
				particle\scale		= tween(particle\max_scale, particle\scale, .05)
				particle\alpha		= particle\alpha - Rnd(particle\fade)
				particle\spr_ang	= particle\spr_ang + Sgn(particle\spr_ang) * particle\spd
				particle\spd		= particle\spd * .92

				MoveEntity		particle\obj, 0, 0, particle\spd
				
				RotateSprite	particle\obj, particle\spr_ang
				
				ScaleSprite		particle\obj, particle\scale, particle\scale
				
				EntityColor		particle\obj, particle\r, particle\g, particle\b
				EntityAlpha		particle\obj, particle\alpha
				
				If particle\alpha < 0.25 Then
					If particle\pspawn = False Then
						create_particle(SMOKE, EntityX(particle\obj), EntityY(particle\obj), EntityZ(particle\obj), 0, 0, 0, .001)
						particle\pspawn = True
					End If
				End If
					
				
			Case SMOKE
				particle\r			= tween(particle\tr, particle\r, .02)
				particle\g			= tween(particle\tg, particle\g, .02)
				particle\b			= tween(particle\tb, particle\b, .02)
				particle\scale		= tween(particle\max_scale, particle\scale, .02)
				particle\alpha		= particle\alpha - particle\fade
				particle\spr_ang	= particle\spr_ang + Sgn(particle\spr_ang) * particle\spd
				particle\spd		= particle\spd * .5

				MoveEntity		particle\obj, 0, 0, particle\spd
				TranslateEntity particle\obj, 0, .01, 0
				
				RotateSprite	particle\obj, particle\spr_ang
				
				ScaleSprite		particle\obj, particle\scale, particle\scale
				
				EntityColor		particle\obj, particle\r, particle\g, particle\b
				EntityAlpha		particle\obj, particle\alpha
							
		End Select
	Next


Thanks for any assistance!


octothorpe(Posted 2005) [#2]
I can't see anything wrong with the code you posted. It's perfectly fine to add new objects while iterating with Each.

I'd recommend testing this with a single Global fire particle, so you can watch it with the debugger. Stop right before you create the smoke particle and step through your program. Presumably, your fire particle's pspawn field is being reset to false somehow.


AdsAdamJ(Posted 2005) [#3]
Just gave that a go. The section which controls the spawning of a new particle still ignores what is stored in 'particle\pspawn'. There is nothing else in the code which appears to revert the variable to 'False'.

I still think it's something to do with the 'for...each' loop. Perhaps by adding a new particle it stuffs up the loop somehow? (my brain is tired to make sense of it all now, it's 1.30-something am!)

Tomorrow I'm going to try an idea I just had - put all new particles in a temporary handle and copy them across after the main 'for...each' loop. That might sort it out and have advantages elsewhere.


octothorpe(Posted 2005) [#4]
I think you're barking up the wrong tree here. Blitz's "Each" loop is a simple iterator over a linked list. Objects you add after the one you're currently working with will be looped over, while objects added before the current object will not. By default, New adds objects to the end of the list.

particle isn't global is it? If it is, the call to create_particle() might modify it, meaning that you'd set the smoke particle's pspawn field to true instead of the fire particles'. A simple way to test this would be to move "particle\pspawn = True" above your call to create_particle().


AdsAdamJ(Posted 2005) [#5]
You're right, thanks! It's always the most simplest of things in the end. I must admit I feel kinda stupid now because I've always been good at producing linked lists in C++... *slaps forehead*