OOP Particle Tutorial (Bmax 1.14)

BlitzMax Forums/BlitzMax Tutorials/OOP Particle Tutorial (Bmax 1.14)

Matt McFarland(Posted 2005) [#1]
In less than 5 minutes learn and make something like this:

It does look better when watching though.
Ok, you need two things.

1) A legal copy of BlitzMax ;)
2) An image editor, something that does .png :)

Ok, before we start with the code, let us make a nifty spark. Go ahead and create a 16x16 spark (mine is just a white line with black backround, you do whatever you want, but I recommend shades of gray for color manipulation)

When you are done with your file, save it as "spark.png" and make sure it will exist in the same directory(folder) as your newly awaiting .bmx file.

Ok, now lets start with Initialization section
Strict
Graphics 800,600
Global SparkList:TList = CreateList()
AutoMidHandle(True)
Global iSpark:TImage = LoadImage ("spark.png",MIPMAPPEDIMAGE|FILTEREDIMAGE)
SetBlend LIGHTBLEND


Alright, that's simple enough. Now since we're doing this in BlitzMax I'm going to do this the OOP way.

So first we want to create a Type, I'll call it TSpark because it's good practice to put a T before anything that is a type.

Type TSpark
	Field x#,y#,r,g,b,xv#,yv#,scale#,life
End Type


Alright, the X and Y are going to be it's position, the r,g,b are going to be color settings which you can modify later if you want. The scale is also the scale of the image, this way you can modify the size of each particle respectivly. The life is how many "refreshes" a particle will last.


Ok, lets jump to the mainloop so we have an idea what is going on. Then we'll program the type. I'm doing it this way to help show you how this is going to work, but I programmed the type first because I already had in mind what I was going to do.

Repeat
	'Function Create(x,y,xv,yv,scale,life)
	Cls
	'When you hold the mouse down the emitter will be enabled.
	'This means you'll see some kewl particle effects on your
	'screen where your mouse cursor is.
	If MouseDown(1) 	
		'Ok, the yv, is the y velocity, this is going to be at
		'1, so y will update by 1 every refresh by default
		Local yv# = 1
		'ok I call this lx because its a local variable,
		'it is actually modifying the X velocity vector
		'of the particle so that we can see where this particle
		'will go.  
	        For Local lx# = 0.1 To 1 Step .1
	    	'Randomize the y velocity a bit to make it look neat
	    	yv#:-RndFloat()
	    	'Ok, so we go from .1 to 1 by .1 a step and create
	    	'two particles at a time.  the -lx in the latter
	    	'create function is so that it is mirrored.
	    	TSpark.Create (MouseX(),MouseY()-5,lx#,yv#,.2,660)
	    	TSpark.Create (MouseX(),MouseY()-5,-lx#,yv#,.2,660)
	    Next
	
	End If
	TSpark.UpdateAll
	Flip
Until KeyHit(KEY_ESCAPE)


Alright, so the code should be commented enough for you to get it, if not, just ask and you shall receive ;)

Now, lets scroll back up to the top of the program and modify this type. You should already notice we'll need a create function and an updateall function, so lets get to it!

New Type Code:
Type TSpark
	Field x#,y#,r,g,b,xv#,yv#,scale#,life
	Function Create(x,y,xv#,yv#,scale#,life)
		Local Spark:TSpark  = New TSpark
		Spark.x = x
		Spark.y = y
		Spark.xv# = xv#
		Spark.yv# = yv#
		spark.r = 255
		spark.g = 255
		spark.b = 255
		spark.scale# = scale#
		spark.life = life
		SparkList.AddLast(Spark)
	End Function
	Method Destroy()
		SparkList.Remove(Self)
	End Method
	Function UpdateAll()
		For Local Spark:TSpark = EachIn SparkList
			spark.yv#:+RndFloat()
			Spark.x#:+Spark.xv#
        	        Spark.y#:+Spark.yv#
        	        spark.r:-1
        	        spark.b:-2
        	        spark.g:-1
        	        SetColor spark.r,spark.g,spark.b
        	        SetScale spark.scale,spark.scale
        	        DrawImage (iSpark,spark.x,spark.y)
        	        SetColor 255,255,255
        	        SetScale 1,1
        	        spark.life:-1
	       	        If spark.life < 1 Then spark.Destroy()
		Next
	End Function
End Type


Ok, you can see in the UpdateAll function that the spark's y velocity increase at a random float (that's subtle) and it's x velocity is stable. The red and green colord go down only by 1 but the blue goes down by two. So the spark will turn a yellowish color as it fades away. The spark will destroy itself if its life goes down too low, and its scale is modifiable as well.

Ok Scott Shaver THIS IS HOW you make a tutorial!! :P Matt 1, Scott 0, Scott its your turn ;) (I'm messing with you Scott dont get mad, but ehm I am trying to tempt you into making a better one than this too) C'mon and "I dont have the time" is a copout!! hah, just kidding :)

On a final note: I hope you guys find this useful, and if you have any questions I'll try to answer as best as possible.


Snader(Posted 2005) [#2]
Thanx Matt! Informative and small!


Scott Shaver(Posted 2005) [#3]

Ok Scott Shaver THIS IS HOW you make a tutorial!! :P Matt 1, Scott 0, Scott its your turn ;) (I'm messing with you Scott dont get mad, but ehm I am trying to tempt you into making a better one than this too) C'mon and "I dont have the time" is a copout!! hah, just kidding :)



LOL, nice!


Sashnil(Posted 2006) [#4]
Love it, keep em coming! :)


Matt Merkulov(Posted 2007) [#5]
Here's version russified by JohnK:
http://blitzetc.boolean.name/articles/sparkle.htm


Matt McFarland(Posted 2007) [#6]
Sweet! I'm glad to see this one Russified :)


Dreamora(Posted 2007) [#7]
Sweet but the title is wrong, should be BM 1.24, there is no Strict + 1.14 ;-)


tonyg(Posted 2007) [#8]
Sweet but the title is wrong, should be BM 1.24, there is no Strict + 1.14 ;-)



Are you sure ?


Dreamora(Posted 2007) [#9]
yes, strict in its current way was part of the new GC and compiler -> BM 1.16+


H&K(Posted 2007) [#10]
Strict was in the 1.09 demo, maybe it does work differently now, but its documentation is the same "Strict advises the BlitzMax compiler to report as errors all auto defined variables."


tonyg(Posted 2007) [#11]
yes, strict in its current way was part of the new GC and compiler -> BM 1.16+



Are you sure?
From ReleaseNotes :

1.14 Release
************

Big change: automatic object/handle conversion has been removed
in Strict mode.




H&K(Posted 2007) [#12]
Right so in 1.16 it stopped doing
A:int = D:aType
automaticly.
So it can be 1.14 then, cos the listing hasnt done that


Dreamora(Posted 2007) [#13]
I'm a little stupid anyway, didn't realize that someone found it funny to dig out a stone age thread with a tut that won't work like this anymore in BM 1.24 ... (and that only a beginner would most likely do without some kind of pooling mechanism to prevent garbage flooding)


Trader3564(Posted 2008) [#14]
Here is an updated COPY+PASTE+GO version. I added FPS and OpenGL driver, but you can strip the driver code if you want.

Also all is now SuperStrict :-P
SuperStrict

SetGraphicsDriver GLMax2DDriver() 
Graphics 800, 600,,, GRAPHICS_BACKBUFFER

Global SparkList:TList = CreateList()
AutoMidHandle(True)

Global iSpark:TImage = LoadImage("star.png", MIPMAPPEDIMAGE | FILTEREDIMAGE) 
SetBlend LIGHTBLEND

Type TSpark
	Field x:Float
	Field y:Float
	Field r:Int
	Field g:Int
	Field b:Int
	Field xv:Float
	Field yv:Float
	Field scale:Float
	Field life:Int
	
	Function Create(x:Int, y:Int, xv:Float, yv:Float, scale:Float, life:Int) 
		Local Spark:TSpark = New TSpark
		Spark.x = x
		Spark.y = y
		Spark.xv = xv
		Spark.yv = yv
		spark.r = 255
		spark.g = 255
		spark.b = 255
		spark.scale = scale
		spark.life = life
		SparkList.AddLast(Spark) 
	End Function
	
	Method Destroy()
		SparkList.Remove(Self) 
	End Method
	
	Function UpdateAll()
		For Local Spark:TSpark = EachIn SparkList
		spark.yv:+RndFloat() 
		Spark.x:+Spark.xv
		Spark.y:+Spark.yv
		spark.r:-1
		spark.b:-2
		spark.g:-1
		SetColor spark.r, spark.g, spark.b
		SetScale spark.scale, spark.scale
		DrawImage(iSpark, spark.x, spark.y) 
		SetColor 255,255,255
		SetScale 1,1
		spark.life:-1
		If spark.life < 1 spark.Destroy() 
		Next
	End Function
End Type

Local t:Int = MilliSecs() 
Local counter:Int
Local FPS:Int

While Not KeyHit(KEY_ESCAPE) 
	Cls
	
	If t < MilliSecs() 
		t = MilliSecs() + 1000
		FPS = counter
		counter = 0
	End If
	counter:+1
	
	Local yv:Float = 1
	Local lx:Float
	For lx = 0.1 To 1 Step.1
		yv:Float:-RndFloat() 
		TSpark.Create(Rand(0, 800), 0, lx, yv, 2, 50) 
		TSpark.Create(Rand(0, 800), 0, - lx, yv, 2, 50) 
	Next
	TSpark.UpdateAll

	DrawText "FPS: " + FPS, 730, 580
	Flip 1
Wend



Taron(Posted 2008) [#15]
Hi everyone,

this is my first post or rather reply here on the forum, so forgive me, if I'm a little clumsy.

Even more wild, this is my first day with BlitzMax and I'm rather thrilled! I've played around with the code above and made some kind of pretty changes. If you like I'll post it, once I find out how to do it properly here...<shame>. If I've managed to write a new breakout and easily play around with code, I should handle the forum codes, too...<LOL>.

So yeah, let's try. I mean, if my posting this is not wanted, don't hesitate to delete the whole reply, but just for fun...

This is based on the latest code using openGL. I've just reintroduced the mouse spark emitting and changed the life behavior. Any life time results in a smooth fading and the color fading is a bit more vivid, too.



More than anything else, I want to say: THANK YOU! That's a wonder code with a really nice and easy explanation. I hope to find more such snippits around here.

Thanks again,

Taron