About Monkey 2 › Forums › General Programming Discussion › Basic Particle Engine
Tagged: example
This topic contains 1 reply, has 1 voice, and was last updated by 
 Matthew Smith
 2 years, 9 months ago.
- 
		AuthorPosts
 - 
		
			
				
July 14, 2016 at 11:25 am #2132
Using some converted BlizMax code by Mark Incitti, find below a basic particle engine using DrawLine and Image to generate various types of particles.
You will require the latest change to the Canvas code here (or v1.0.2 or greater)
https://github.com/blitz-research/monkey2/commit/f281fe921c317ab3330a99cde4c131dbbb368209
The required particle image is attached at the bottom. Also much thanks to Mark for adding LineWidth and some line smoothing! Particle Style 3 looks the goods!
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388'-----------------------------------------------------------------------'' Based on BlitzMax code created by Mark Incitti''-----------------------------------------------------------------------Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..#Import "particle.png"Global particleImage:ImageConst Size:=New Vec2i( 640,360 )Const NumParticles:Int=2048Const ParticleLife:Int=40Const ParticleDecay:Float=0.95Function Main()New AppInstanceNew MyWindowApp.Run()EndClass MyWindow Extends WindowPrivateField _particles:ParticleManagerField _style:Int=0PublicMethod New()'Create windowSuper.New( "Particles!",640,480,WindowFlags.Fullscreen )Layout="letterbox"ClearColor=New Color(0,0,0)Mouse.PointerVisible=TrueStyle.BackgroundColor=GetColor(2,2,2)'Load imageparticleImage=Image.Load("asset::particle.png",TextureFlags.Filter)particleImage.Handle=New Vec2f(0.5,0.5)'Initialise particles_particles=New ParticleManager()'RandomiseSeedRnd(Millisecs())EndMethod OnRender( canvas:Canvas ) Override'FeaturesIf (Keyboard.KeyHit(Key.P)) _style=(_style + 1) Mod 5'Release particles?If(Rnd(0,100)>90) _particles.CreateFireWorks(0,_style)'Update_particles.Update()'RenderApp.RequestRender()_particles.Render(canvas)'Textcanvas.Color=Color.Whitecanvas.DrawText("Style: "+_style,4,App.ActiveWindow.Height-40)canvas.DrawText("Press 'P' to change",4,App.ActiveWindow.Height-25)EndMethod OnKeyEvent( event:KeyEvent ) Overrideselect event.TypeCase EventType.KeyDownIf ( event.Key=Key.Enter And event.Modifiers & Modifier.Alt ) Fullscreen=Not FullscreenIf ( event.Key=Key.Escape ) App.Terminate()EndEndMethod OnMeasure:Vec2i() OverrideReturn SizeEndEndClass ParticleManagerPrivateField _points:ParticlePoint[]Field _index:Int=0PublicMethod New()'Initialise_points=New ParticlePoint[NumParticles]EndMethod CreateParticles(x:Int,y:Int,style:Int=2,type:Int=0,particles:Int=32)'PrepareLocal r:Int=Rnd(0,4)*64Local g:Int=Rnd(0,4)*64Local b:Int=Rnd(0,4)*64'CreateSelf.CreateParticles(x,y,style,type,r,g,b,particles)EndMethod CreateParticles(x:Int,y:Int,style:Int=2,type:Int=0,r:Int,g:Int,b:Int,particles:Int=32)'CreateFor Local t:Int=0 Until particlesSelf.Create(x,y,style,type,r,g,b)NextEndMethod CreateFireWorks(position:Int,style:Int=2,type:Int=0)'PrepareLocal x:Int,y:IntLocal r:Int=Rnd(0,4)*64Local g:Int=Rnd(0,4)*64Local b:Int=Rnd(0,4)*64'Randomise style?If (style>3) style=Int(Rnd(0,4))'Get locationSelect positionCase 1If (Rnd()>=0.5)x=Rnd(100,App.ActiveWindow.Width-100)y=16If (Rnd()>=0.5) y=App.ActiveWindow.Height-16Elsey=Rnd(50,App.ActiveWindow.Height-50)x=16If (Rnd()>=0.5) x=App.ActiveWindow.Width-16EndCase 2x=App.ActiveWindow.Width/2y=App.ActiveWindow.Height/2Defaultx=Rnd(0,App.ActiveWindow.Width-100)y=Rnd(0,App.ActiveWindow.Height-50)End'CreateFor Local t:Int=0 To 63Self.Create(x,y,style,type,r,g,b)NextEndMethod Update()'ProcessFor Local t:Int=0 To NumParticles-1If (_points[t].active>0) _points[t].Update()NextEndMethod Reset()'Reset_index=0For Local t:Int=0 To NumParticles-1_points[t].x=0_points[t].y=0_points[t].r=0_points[t].g=0_points[t].b=0_points[t].active=0_points[t].dx=0_points[t].dy=0NextEndMethod Render(canvas:Canvas)Local r:Float,g:Float,b:Float'Preparecanvas.BlendMode=BlendMode.Additivecanvas.TextureFilteringEnabled=True'ProcessFor Local t:int=0 To NumParticles-1If (_points[t].active>0)Select _points[t].styleCase 0'Get colorr=Min(_points[t].r*1.25,255.0)g=Min(_points[t].g*1.25,255.0)b=Min(_points[t].b*1.25,255.0)canvas.Color=GetColor(r,g,b)'Drawcanvas.LineWidth=2.0canvas.Alpha=1.0canvas.DrawLine(_points[t].x,_points[t].y,_points[t].x+_points[t].dx,_points[t].y+_points[t].dy)Case 1'Get colorr=Min(_points[t].r*1.25,255.0)g=Min(_points[t].g*1.25,255.0)b=Min(_points[t].b*1.25,255.0)canvas.Color=GetColor(r,g,b)'Drawcanvas.LineWidth=3.0canvas.Alpha=0.8canvas.DrawLine(_points[t].x,_points[t].y,_points[t].x+_points[t].dx,_points[t].y+_points[t].dy)Case 2'Get colorr=Min(_points[t].r*1.5,255.0)g=Min(_points[t].g*1.5,255.0)b=Min(_points[t].b*1.5,255.0)canvas.Color=GetColor(r,g,b)'Drawcanvas.LineWidth=2.0canvas.Alpha=1.0canvas.DrawImage(particleImage,_points[t].x+_points[t].dx,_points[t].y+_points[t].dy,0,0.5,0.5)Case 3'BEST!'Get colorr=Min(_points[t].r*1.25,255.0)g=Min(_points[t].g*1.25,255.0)b=Min(_points[t].b*1.25,255.0)canvas.Color=GetColor(r,g,b)'Draw (line)canvas.LineWidth=2.0canvas.Alpha=0.8canvas.DrawLine(_points[t].x,_points[t].y,_points[t].x+_points[t].dx,_points[t].y+_points[t].dy)'Draw (image)canvas.Alpha=0.25canvas.DrawImage(particleImage,_points[t].x+_points[t].dx*1.0,_points[t].y+_points[t].dy*1.0)EndEndNext'Resetcanvas.BlendMode=BlendMode.Alphacanvas.Alpha=1.0canvas.LineWidth=1.0EndPrivateMethod Create(x:Float,y:Float,style:Int,type:Int,r:Int,g:Int,b:Int,rot:Float=0.0,size:Int=1)'PrepareLocal dir:FloatLocal mag:Float'Set particle_points[_index].x=x_points[_index].y=y_points[_index].r=r_points[_index].g=g_points[_index].b=b_points[_index].active=Rnd(ParticleLife-20,ParticleLife)_points[_index].style=style'ValidateSelect typeCase 0'Randomdir=Rnd(0,360)mag=Rnd(3,11)_points[_index].dx=Cos(dir)*mag_points[_index].dy=Sin(dir)*magCase 1mag=16_points[_index].dx=Cos(rot)*mag_points[_index].dy=Sin(rot)*mag_points[_index].active=24Case 2mag=8_points[_index].dx=Cos(rot)*mag_points[_index].dy=Sin(rot)*magCase 3' 3 dirsdir=120*Rnd(0,3)+rotmag=Rnd(3,10)_points[_index].dx=Cos(dir)*mag_points[_index].dy=Sin(dir)*magCase 4' 4 dirsdir=90*Rnd(0,4)+rotmag=Rnd(3,11)_points[_index].dx=Cos(dir)*mag_points[_index].dy=Sin(dir)*magCase 5' 8 dirsdir=45*Rnd(0,8)+rotmag=Rnd(3,11)_points[_index].dx=Cos(dir)*mag_points[_index].dy=Sin(dir)*magCase 6' any dir and speedmag=Rnd(0.5,2.0)_points[_index].dx=Cos(rot)*mag_points[_index].dy=Sin(rot)*magCase 7' randomdir=Rnd(0,360)mag=Rnd(1,14)_points[_index].dx=Cos(dir)*mag_points[_index].dy=Sin(dir)*magEnd'Finalise_points[_index].dx=_points[_index].dx*1.5_points[_index].dy=_points[_index].dy*1.5_points[_index].x+=_points[_index].dx*size_points[_index].y+=_points[_index].dy*size'Increment_index=(_index+1) Mod NumParticlesEndEnd ClassStruct ParticlePointField x:Float=0.0Field y:Float=0.0Field dx:Float=0.0Field dy:Float=0.0Field r:Float=0Field g:Float=0Field b:Float=0Field active:Int=0Field style:Int=0Method Update()x+=dxy+=dyIf (x<=dx)dx=Abs(dx)x+=dx*2EndIf(x>App.ActiveWindow.Width-1-dx)dx=-Abs(dx)x+=dx*2EndIf (y<=dy)dy=Abs(dy)y+=dy*2EndIf (y>App.ActiveWindow.Height-1-dy)dy=-Abs(dy)y+=dy*2Enddx*=ParticleDecaydy*=ParticleDecayactive-=1If (active<20)If (active<10)r=Max(r*0.8,0.0)g=Max(g*0.8,0.0)b=Max(b*0.8,0.0)Elser=Max(r*0.97,0.0)g=Max(g*0.97,0.0)b=Max(b*0.97,0.0)EndElseif (active>200)active=200EndEndEnd StructFunction GetColor:Color(red:Float,green:Float,blue:Float)Return New Color(red/255,green/255,blue/255)EndAttachments:
July 14, 2016 at 11:40 pm #2146Cleaned it up a little more.
 - 
		AuthorPosts
 
You must be logged in to reply to this topic.