Rudimentary Particle Emitter

Monkey Forums/Monkey Code/Rudimentary Particle Emitter

Big Jim(Posted 2011) [#1]
This is a basic particle emitter.
Feel free to use it or abuse it any way you wish.


Import mojo

Class Particle
	Field X#, Y#, XD#, YD#
	Field Age#  = 1.0
	Field DecayRate#
	Field GravityX# = 0.0
	Field GravityY# =0.0

	Method New(x#, y#, Scatter)
		Self.X = x
		Self.Y = y
		Self.XD = Rnd(-Scatter, Scatter)
		Self.YD = Rnd(-Scatter, Scatter)
		Self.Age = Rnd()
		Self.DecayRate = Rnd(.005, .01)
	End Method

	Method Update()
		X += XD + GravityX
		Y += YD + GravityY
		If X < 0 Or X > DeviceWidth Then Age = 0
		If Y < 0 Or Y > DeviceWidth Then Age = 0
		Age -= DecayRate
	End Method

End Class

Class ParticleEmitter
	Field Particles:= New List<Particle>
	Field Scatter#, ParticleCount
	Field GravityX# = 0, GravityY# = 0
	Field ParticleImage:Image
	Field RemainingParticles
	
	Method New(x#, y#, scatter#, particleCount, particleImage:Image, gravX#, gravY#)
		GravityX = gravX
		GravityY = gravY
		For Local i = 0 To ParticleCount	
			Particles.AddLast(New Particle(x, y, scatter))
		Next
		Self.ParticleImage = particleImage
		RemainingParticles = particleCount
	End Method
	
	Method Update()
		Local LiveParticles:= New List<Particle>
		For Local p:Particle = Eachin Particles
			p.GravityX = GravityX
			p.GravityY = GravityY
			p.Update()
			If p.Age > 0 Then LiveParticles.AddLast(p)
		Next
		Particles = LiveParticles
		RemainingParticles = Particles.Count
	End Method
	
	Method Render()
		For Local p:Particle = Eachin Particles
			SetAlpha p.Age
			SetBlend LightenBlend
			SetColor Rnd(100,255), Rnd(100,255), Rnd(100,255) 
			DrawImage (ParticleImage, p.X, p.Y,0,p.Age, p.Age)
		Next
	End Method

End Class

Class ParticleManager
	
	Field ParticleEmitters:= New List<ParticleEmitter>
	Field TotalParticles = 0
	
	Method AddParticleEmitter(x#, y#, scatter#, particleCount, particleImage:Image, gravX#, gravY#)
		ParticleEmitters.AddLast( New ParticleEmitter ( x, y, scatter, particleCount, particleImage, gravX, gravY ) )
	End Method
	
	Method Update()
		Local LivePE:= New List<ParticleEmitter>
		TotalParticles = 0
		For Local pe:= Eachin ParticleEmitters
			pe.Update()
			If pe.RemainingParticles > 0 
				LivePE.AddLast(pe)
				TotalParticles += pe.RemainingParticles
			End If
		Next
		ParticleEmitters = LivePE

	End Method

	Method Render()
		For Local pe:= Eachin ParticleEmitters
			pe.Render()
		Next
	End Method


End Class


Here's a test program

Import mojo
Import particleemitter

Class ParticleEmitterTester Extends App

	Field PMgr:ParticleManager = New ParticleManager
	Field Spark:Image
	
	Method OnCreate()
		SetUpdateRate 60
		Spark = LoadImage	("bluspark.png")
	End Method
	
	Method OnUpdate()
		Local gx# = 0.0, gy# = 0.0
		For Local i = 0 To 32
			If TouchDown(i)
#if TARGET = "android" Or TARGET = "ios" 
				gx = 2 * AccelX()				
				gy = 2* AccelY()
#endif
				PMgr.AddParticleEmitter(TouchX(i), TouchY(i), 2, 100, Spark, gx, gy)
			End If
		Next
		
		PMgr.Update()
		
	End Method
	
	Method OnRender()
		Cls 
		PMgr.Render()
	End Method 

End Class


Function Main()
	New ParticleEmitterTester
End Function