2
0
Mark Sibly 9 жил өмнө
parent
commit
7b6262f7c3

+ 393 - 0
bananas/particles/particles.monkey2

@@ -0,0 +1,393 @@
+'-----------------------------------------------------------------------
+'
+'  Based on BlitzMax code created by Mark Incitti
+'
+'-----------------------------------------------------------------------
+ 
+Namespace myapp
+ 
+#Import "<std>"
+#Import "<mojo>"
+ 
+Using std..
+Using mojo..
+ 
+#Import "particle.png"
+Global particleImage:Image
+ 
+Const Size:=New Vec2i( 640,360 )
+Const NumParticles:Int=2048
+Const ParticleLife:Int=40
+Const ParticleDecay:Float=0.95
+ 
+Function Main()
+	New AppInstance
+	New MyWindow
+	App.Run()
+End
+ 
+Class MyWindow Extends Window
+ 
+Private
+	Field _particles:Particles
+	Field _style:Int=0
+Public
+ 
+	Method New()
+		'Create window
+		Super.New( "Particles!",640,480,WindowFlags.Fullscreen )
+		Layout="letterbox"
+		ClearColor=New Color(0,0,0)
+		Mouse.PointerVisible=True
+		Style.BackgroundColor=GetColor(2,2,2)
+		
+		'Load image
+		particleImage=Image.Load("asset::particle.png",TextureFlags.Filter)
+		particleImage.Handle=New Vec2f(0.5,0.5)
+		
+		'Initialise particles
+		_particles=New Particles()
+ 
+	End
+ 
+	Method OnRender( canvas:Canvas ) Override
+		'Features
+		If (Keyboard.KeyHit(Key.P)) _style=(_style + 1) Mod 4
+		
+		'Release particles?
+		If(Rnd(0,100)>90) _particles.CreateFireWorks(3,_style)
+		
+		'Update
+		_particles.Update()
+		
+		'Render
+		App.RequestRender()
+		_particles.Render(canvas)
+				
+		'Text
+		canvas.Color=Color.White
+		canvas.DrawText("Style: "+_style,4,App.ActiveWindow.Height-40)
+		canvas.DrawText("Press 'P' to change",4,App.ActiveWindow.Height-25)
+		
+	End
+	
+	Method OnKeyEvent( event:KeyEvent ) Override
+	
+		select event.Type
+			Case EventType.KeyDown 
+				If ( event.Key=Key.Enter And event.Modifiers & Modifier.Alt	) Fullscreen=Not Fullscreen	
+				If ( event.Key=Key.Escape )	App.Terminate()		
+		End
+	
+	End
+	
+	Method OnMeasure:Vec2i() Override	
+		Return Size
+		
+	End
+	
+End
+ 
+Class Particles
+ 
+Private
+	Field _points:ParticlePoint[]
+	Field _index:Int=0
+Public
+ 
+	Method New()
+		'Initialise
+		_points=New ParticlePoint[NumParticles]				
+	End
+	
+	Method CreateParticles(x:Int,y:Int,style:Int=2,type:Int=0,particles:Int=32)
+		'Prepare
+		Local r:Int=Rnd(0,4)*64
+		Local g:Int=Rnd(0,4)*64
+		Local b:Int=Rnd(0,4)*64
+ 
+		'Create
+		Self.CreateParticles(x,y,style,type,r,g,b,particles)	
+	End
+ 
+	Method CreateParticles(x:Int,y:Int,style:Int=2,type:Int=0,r:Int,g:Int,b:Int,particles:Int=32)
+		'Create
+		For Local t:Int=0 Until particles
+			Self.Create(x,y,style,type,r,g,b)
+		Next	
+	End
+	
+	Method CreateFireWorks(position:Int,style:Int=2,type:Int=0)
+		'Prepare
+		Local x:Int,y:Int
+		Local r:Int=Rnd(0,4)*64
+		Local g:Int=Rnd(0,4)*64
+		Local b:Int=Rnd(0,4)*64
+				
+		'Get location
+		Select position
+			Case 1
+				If (Rnd(0,1))
+					x=Rnd(100,App.ActiveWindow.Width-100)
+					y=16
+					If (Rnd(0,1)) y=App.ActiveWindow.Height-16
+				Else
+					y=Rnd(50,App.ActiveWindow.Height-50)
+					x=16
+					If (Rnd(0,1)) x=App.ActiveWindow.Width-16
+				End
+	
+			Case 2
+				x=App.ActiveWindow.Width/2
+				y=App.ActiveWindow.Height/2
+			Default
+				x=Rnd(0,App.ActiveWindow.Width-100)
+				y=Rnd(0,App.ActiveWindow.Height-50)
+		
+		End
+		
+		'Create
+		For Local t:Int=0 To 63
+			Self.Create(x,y,style,type,r,g,b)
+		Next
+	End
+	
+	Method Update()
+		'Process
+		For Local t:Int=0 To NumParticles-1
+			If (_points[t].active>0) _points[t].Update()
+		Next		
+	End
+	
+	Method Reset()
+		'Process
+		For 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=0
+		Next		
+	
+		'Reset
+		_index=0
+		
+	End
+	
+	Method Render(canvas:Canvas)
+		Local r:Float,g:Float,b:Float
+			
+		'Prepare
+		canvas.BlendMode=BlendMode.Additive
+		canvas.Alpha=1.0
+		canvas.TextureFilteringEnabled=True
+		canvas.LineWidth=2.0
+		
+		'Process
+		For Local t:int=0 To NumParticles-1
+			If (_points[t].active>0)
+				Select _points[t].style
+					Case 0
+						'Get color
+						r=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
+						canvas.DrawLine(_points[t].x,_points[t].y,_points[t].x+_points[t].dx,_points[t].y+_points[t].dy)
+									
+					Case 1						
+						'Get color
+						r=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
+						canvas.LineWidth=3.0
+						canvas.Alpha=0.9
+						canvas.DrawLine(_points[t].x,_points[t].y,_points[t].x+_points[t].dx,_points[t].y+_points[t].dy)
+									
+					Case 2
+						'Get color
+						r=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)
+						
+						'Draw
+						canvas.Alpha=1.0 '.9
+						canvas.DrawImage(particleImage,_points[t].x+_points[t].dx,_points[t].y+_points[t].dy,0,0.5,0.5)		
+										
+					Case 3 
+						'BEST!
+						Local px:Float,py:Float
+						Local r:Float,g:Float,b:Float
+						
+						'Get color
+						r=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)
+						px=_points[t].x
+						py=_points[t].y
+						canvas.Alpha=0.8
+						canvas.DrawLine(px,py,px+_points[t].dx,py+_points[t].dy)				
+						'Draw (image)
+						Local rot:Float=ATan(_points[t].dy/_points[t].dx)
+						px=_points[t].x
+						py=_points[t].y					
+						canvas.Alpha=0.25
+						canvas.DrawImage(particleImage,px+_points[t].dx*1.0,py+_points[t].dy*1.0)						
+				End
+			End
+			
+		Next
+		
+		'Reset
+		canvas.BlendMode=BlendMode.Alpha
+		canvas.Alpha=1.0
+		canvas.LineWidth=1.0
+			
+	End
+	
+Private
+	Method Create(x:Float,y:Float,style:Int,type:Int,r:Int,g:Int,b:Int,rot:Float=0.0,size:Int=1)
+		'Prepare
+		Local dir:Float
+		Local 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
+		
+		'Validate
+		Select type
+			Case 0
+				'Random
+				dir=Rnd(0,360)
+				mag=Rnd(3,11)
+				_points[_index].dx=Cos(dir)*mag
+				_points[_index].dy=Sin(dir)*mag
+			Case 1
+				mag=16
+				_points[_index].dx=Cos(rot)*mag
+				_points[_index].dy=Sin(rot)*mag
+				_points[_index].active=24
+			Case 2
+				mag=8
+				_points[_index].dx=Cos(rot)*mag
+				_points[_index].dy=Sin(rot)*mag
+			Case 3
+				' 3 dirs
+				dir=120*Rnd(0,3)+rot
+				mag=Rnd(3,10)			
+				_points[_index].dx=Cos(dir)*mag
+				_points[_index].dy=Sin(dir)*mag
+			Case 4
+				' 4 dirs
+				dir=90*Rnd(0,4)+rot
+				mag=Rnd(3,11)
+				_points[_index].dx=Cos(dir)*mag
+				_points[_index].dy=Sin(dir)*mag
+			Case 5
+				' 8 dirs
+				dir=45*Rnd(0,8)+rot
+				mag=Rnd(3,11)
+				_points[_index].dx=Cos(dir)*mag
+				_points[_index].dy=Sin(dir)*mag
+			Case 6
+				' any dir and speed
+				mag=Rnd(0.5,2.0)			
+				_points[_index].dx=Cos(rot)*mag
+				_points[_index].dy=Sin(rot)*mag
+			Case 7
+				' random
+				dir=Rnd(0,360)
+				mag=Rnd(1,14)
+				_points[_index].dx=Cos(dir)*mag
+				_points[_index].dy=Sin(dir)*mag
+		End
+		
+		'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 NumParticles
+		
+	End
+	
+End Class
+ 
+Struct ParticlePoint
+	Field x:Float=0.0
+	Field y:Float=0.0
+	Field dx:Float=0.0
+	Field dy:Float=0.0
+	Field r:Float=0
+	Field g:Float=0
+	Field b:Float=0
+	Field active:Int=0
+	Field style:Int=0
+	
+	Method Update()
+		x=x+dx
+		y=y+dy
+		If (x<=dx)
+			dx=Abs(dx)
+			x=x+dx*2
+		End
+		If(x>App.ActiveWindow.Width-1-dx)
+			dx=-Abs(dx)
+			x=x+dx*2
+		End
+		If (y<=dy)
+			dy=Abs(dy)
+			y=y+dy*2
+		End
+		If (y>App.ActiveWindow.Height-1-dy)
+			dy=-Abs(dy)
+			y=y+dy*2
+		End
+		dx=dx*ParticleDecay
+		dy=dy*ParticleDecay
+		
+		active-=1
+		If (active<20)
+			If (active<10)
+				r*=0.8
+				g*=0.8
+				b*=0.8
+			Else
+				r*=0.97
+				g*=0.97
+				b*=0.97
+			End
+			If (r<0) r=0
+			If (g<0) g=0
+			If (b<0) b=0
+		Elseif (active>200)
+			active=200
+		End
+		
+	End
+ 
+End Struct
+ 
+Function GetColor:Color(red:Float,green:Float,blue:Float)
+	Return New Color(red/255,green/255,blue/255)
+End