| [source] - PARTICLE SPRAY by IKER 
 
	 
	
		| Author | Message |   
		| iker 
 
  
 
 
 | 
			
				|  Posted: Sun Feb 12, 2006 8:54 pm    Post subject: [source] - PARTICLE SPRAY by IKER |  |   
				| 
 |  
				| here is a little particle system that I put together, thought I might share the source with everyone here. Its actualy quite fun to watch, especialy when you screw around with the constants. The bursts dicipate after a while, and the particles spray at a constant rate, which is better. Anyways, have fun and edit at will   
 
 	  | code: |  	  | setscreen ("graphics:max;max,offscreenonly,nobuttonbar")
% Particle Spray by : Chris "Iker" Iaconis
 % A basic Particle Spray,
 % particles spawn at mouse coordinates
 % have different speeds, directions
 % may take a few seconds to not come out in "bursts"
 
 % consts are editable for speed purposes
 const aOP := 512 % amount of particles
 const dT := 0 % delay time (1/1000 seconds)
 const pS := 6 % particle size
 const pG := 3 % particle gravity
 const pF := .2 % particle fade
 const pD := 6 %particle distance
 
 type particles :
 record
 PX : array 0 .. aOP of int
 PY : array 0 .. aOP of int
 PD : array 0 .. aOP of int
 PC : array 0 .. aOP of real
 PS : array 0 .. aOP of int
 end record
 var aO : particles
 var r, g, b : real
 var count, countDelay, mouseX, mouseY, mouseButton : int := 0
 for i : 0 .. aOP
 aO.PX (i) := 0
 aO.PY (i) := 0
 aO.PC (i) := 0
 end for
 
 proc spawnParticle (pN : int)
 Mouse.Where (mouseX, mouseY, mouseButton)
 aO.PX (pN) := mouseX
 aO.PY (pN) := mouseY
 randint (aO.PD (pN), 1, 359)
 randint (aO.PS (pN), 0, pD)
 aO.PC (pN) := 31
 end spawnParticle
 
 proc particleGravity (pN : int)
 if aO.PD (pN) > 0 and aO.PD (pN) < 180 then
 aO.PD (pN) += pG
 elsif aO.PD (pN) < 360 and aO.PD (pN) > 180 then
 aO.PD (pN) -= pG
 end if
 end particleGravity
 
 proc particleFade (pN : int)
 aO.PC (pN) -= pF
 end particleFade
 
 proc particleShow (pN : int)
 drawfilloval (aO.PX (pN), aO.PY (pN), pS, pS, round (aO.PC (pN)))
 end particleShow
 
 proc particleMove (pN : int)
 aO.PX (pN) += round (sind (aO.PD (pN)) * aO.PS (pN))
 aO.PY (pN) += round (cosd (aO.PD (pN)) * 5)
 end particleMove
 
 proc particleJudge (pN : int)
 if aO.PD (pN) = 0 then
 spawnParticle (pN)
 end if
 if aO.PC (pN) <= 17 then
 spawnParticle (pN)
 end if
 end particleJudge
 
 for i : 0 .. aOP
 spawnParticle (i)
 end for
 
 loop
 spawnParticle (count)
 count += 1
 if count = aOP then
 count := 0
 end if
 for decreasing i : aOP .. 0
 particleJudge (i)
 particleGravity (i)
 particleMove (i)
 particleFade (i)
 particleShow (i)
 end for
 colorback (16)
 View.Update
 cls
 delay (dT)
 end loop
 | 
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| Sponsor Sponsor
 
  
   |  |   
		|  |   
		| Cervantes 
 
  
 
 
 | 
			
				|  Posted: Sun Feb 12, 2006 10:01 pm    Post subject: (No subject) |  |   
				| 
 |  
				| Why do the particles lose their horizontal velocity so abruptly? 
 
 	  | code: |  	  | 
type particles :
 record
 PX : array 0 .. aOP of int
 PY : array 0 .. aOP of int
 PD : array 0 .. aOP of int
 PC : array 0 .. aOP of real
 PS : array 0 .. aOP of int
 end record
 var aO : particles
 
 | 
 Why?  I think you'll find the following to make a lot more sense:
 
 	  | code: |  	  | 
type particle :
 record
 PX, PY, PD, PS : int
 PC : real
 end record
 var aO : array 0 .. aOP of particle
 
 | 
 
 The next step up from this is to make each particle an object.
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| iker 
 
  
 
 
 | 
			
				|  Posted: Mon Feb 13, 2006 4:24 pm    Post subject: (No subject) |  |   
				| 
 |  
				| try using 
 	  | code: |  	  | const aOP := 1024 % amount of particles
const dT := 0 % delay time (1/1000 seconds)
 const pS := 1 % particle size
 const pG := 1 % particle gravity
 const pF := .5 % particle fade
 const pD := 8 %particle distance
 | 
 for the constants, and as for making them into objects, I don't know if I want to seeing as how this isn't realy a project... but I might.
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| Cervantes 
 
  
 
 
 | 
			
				|  Posted: Mon Feb 13, 2006 5:42 pm    Post subject: (No subject) |  |   
				| 
 |  
				| iker wrote: and as for making them into objects, I don't know if I want to seeing as how this isn't realy a project... but I might. 
 Why do you think it best to learn the concepts you need while doing a project (worth marks)?  It's far better to learn the concepts ahead of time, so applying them is easy.  This extends to learning the concepts out of class, before the lessons, so that the lessons are easier.  This extends to all subjects, not just computer science.
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| iker 
 
  
 
 
 | 
			
				|  Posted: Mon Feb 13, 2006 6:15 pm    Post subject: (No subject) |  |   
				| 
 |  
				| Cervantes wrote: iker wrote: and as for making them into objects, I don't know if I want to seeing as how this isn't realy a project... but I might. 
Why do you think it best to learn the concepts you need while doing a project (worth marks)?  It's far better to learn the concepts ahead of time, so applying them is easy.  This extends to learning the concepts out of class, before the lessons, so that the lessons are easier.  This extends to all subjects, not just computer science.
 I'm not actualy in a computer science class, I haven't been for the last year or so... all programming that I've done has been done for my own purposes. I'm basically done with turing, moving onto Java and/or Ruby, which use classes and objects as one of my friends was telling me, so I'm learning them anyways. Didn't say that I didn't want to learn classes, just meant that I didn't want to apply them to this program.
 
 modded my own code for randomn colored particles
 
 
 	  | code: |  	  | setscreen ("graphics:max;max,offscreenonly,nobuttonbar")
% Particle Spray by : Chris "Iker" Iaconis
 % A basic Particle Spray,
 % particles spawn at mouse coordinates
 % have different speeds, directions
 % may take a few seconds to not come out in "bursts"
 
 % consts are editable for speed purposes
 const aOP := 1024 % amount of particles
 const dT := 0 % delay time (1/1000 seconds)
 const pS := 0 % particle size
 const pG := 2 % particle gravity
 const pF := .02 % particle fade
 const pD := 8 %particle distances
 
 type particles :
 record
 PX, PY, PD, PS, PRGB, PC : array 0 .. aOP of int
 PR, PG, PB : array 0 .. aOP of real
 end record
 var aO : particles
 var mouseX, mouseY, mouseButton, count, countDelay : int := 0
 for i : 0 .. aOP
 aO.PX (i) := 0
 aO.PY (i) := 0
 end for
 
 proc spawnParticle (pN : int)
 Mouse.Where (mouseX, mouseY, mouseButton)
 aO.PX (pN) := mouseX
 aO.PY (pN) := mouseY
 randint (aO.PRGB (pN), 1, 3)
 aO.PR (pN) := 0
 aO.PG (pN) := 0
 aO.PB (pN) := 0
 if aO.PRGB (pN) = 1 then
 aO.PR (pN) := Rand.Int (0, 10) / 10
 elsif aO.PRGB (pN) = 2 then
 aO.PG (pN) := Rand.Int (0, 10) / 10
 elsif aO.PRGB (pN) = 3 then
 aO.PB (pN) := Rand.Int (0, 10) / 10
 end if
 randint (aO.PD (pN), 1, 359)
 randint (aO.PS (pN), 0, pD)
 end spawnParticle
 
 proc particleGravity (pN : int)
 if aO.PD (pN) > 0 and aO.PD (pN) < 175 then
 aO.PD (pN) += pG
 elsif aO.PD (pN) < 360 and aO.PD (pN) > 185 then
 aO.PD (pN) -= pG
 end if
 end particleGravity
 
 proc particleFade (pN : int)
 if aO.PRGB (pN) = 1 then
 aO.PR (pN) -= pF
 elsif aO.PRGB (pN) = 2 then
 aO.PG (pN) -= pF
 elsif aO.PRGB (pN) = 3 then
 aO.PB (pN) -= pF
 end if
 aO.PC (pN) := RGB.AddColor (aO.PR (pN), aO.PG (pN), aO.PB (pN))
 end particleFade
 
 proc particleShow (pN : int)
 drawfilloval (aO.PX (pN), aO.PY (pN), pS, pS, aO.PC (pN))
 end particleShow
 
 proc particleMove (pN : int)
 aO.PX (pN) += round (sind (aO.PD (pN)) * aO.PS (pN))
 aO.PY (pN) += round (cosd (aO.PD (pN)) * 5)
 end particleMove
 
 proc particleJudge (pN : int)
 if aO.PRGB (pN) = 1 then
 if aO.PR (pN) <= .05 then
 spawnParticle (pN)
 end if
 elsif aO.PRGB (pN) = 2 then
 if aO.PG (pN) <= .05 then
 spawnParticle (pN)
 end if
 elsif aO.PRGB (pN) = 3 then
 if aO.PB (pN) <= .05 then
 spawnParticle (pN)
 end if
 end if
 end particleJudge
 
 for i : 0 .. aOP
 spawnParticle (i)
 end for
 
 loop
 particleFade (count)
 countDelay += 1
 if countDelay >= 1 then
 countDelay := 0
 count += 1
 if count = aOP then
 count := 0
 end if
 end if
 for decreasing i : aOP .. 0
 particleFade (i)
 particleJudge (i)
 particleGravity (i)
 particleMove (i)
 particleShow (i)
 end for
 colorback (16)
 View.Update
 cls
 Time.DelaySinceLast (dT)
 end loop
 | 
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| Martin 
 
  
 
 
 | 
			
				|  Posted: Mon Feb 13, 2006 8:30 pm    Post subject: (No subject) |  |   
				| 
 |  
				| 	  | code: |  	  | type particle :
record
 _x, _y : real     %location
 _vx, _vy : real   %velocity
 _life : real      %amount of life remaining
 _fade : real      %how much life decreases each frame
 _r, _g, _b : real %colour
 
 _gx, gy : real %gravity, so that you can change it dynamically
 end record
 | 
 
 Now what we've done is created a particle with life and rgb colour values. From here, what you can now do is use some basic alpha blending to make the particle's colour slowly fade into whatever the background colour is. For example, supposing that a particle was given the initial RGB colours (1.0,0.8,0.5), the background colour was (0.0,0.0,0.0) (black), then you could determine the current colour by the following formula:
 CurrentColor = life * initialColour + (1 - life) * backgroundColour
 
 or simply
 
 new_r = life * particle._r + (1 - life)* background._r
 new_g = life * particle._g + (1 - life)* background._g
 new_b = life * particle._b + (1 - life)* background._b
 
 (I don't remember how to use colour codes in Turing, sorry).
 
 Then, you'll want to do the following:
 1. Create an array of particles.
 2. Initialize each particle to some default values, with _life = 0
 main loop
 3. When the event occurs (ie. mouse is down), start setting particles which are not alive (_life <= 0) to have life 1.0
 4. Draw all particles that have life > 0. Draw the particle using the formula given above. Don't change the values of _r, _g, _b within your particle, however.
 5. For each particle, subtract fade from its life. myParticle._life -= myParticle._fade
 End main loop
 
 This'll make it so that particles die out after you stop clicking, but don't disappear immediately (I haven't run your code, I don't have turing).
 
 And you will have on your hands a very fancy particle engine.
 
 EDIT: updated it a bit
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| Cervantes 
 
  
 
 
 | 
			
				|  Posted: Mon Feb 13, 2006 9:31 pm    Post subject: (No subject) |  |   
				| 
 |  
				| iker wrote: 
I'm not actualy in a computer science class, I haven't been for the last year or so... all programming that I've done has been done for my own purposes. I'm basically done with turing, moving onto Java and/or Ruby, which use classes and objects as one of my friends was telling me, so I'm learning them anyways. Didn't say that I didn't want to learn classes, just meant that I didn't want to apply them to this program.
 
 I'm glad to see Ruby in there.
   
 When you move your next language, you will be surrounded by (varying degrees of) unfamiliar syntax.  Knowing the major concepts that a language employs (OOP, in this case) will ease that transition.  Turing can provide a good introduction to OOP.  Of course, even if you master Turing's OOP, there are still things to learn that you will be confronted with when moving to Java or Ruby (or other languages).  For example, in Ruby, you will learn that everything is an object, unlike in Turing where very few things are objects (only the things you write classes for).  Learning OOP in Turing will get the some of the main concepts under your belt, so you have less to worry about when you move on to your next language.
 
 
 Iker wrote: 
	  | code: |  	  | 
randint (aO.PD (pN), 1, 359)
 randint (aO.PS (pN), 0, pD)
 
 | 
 
 How about,
 
 	  | code: |  	  | 
aO.PD (pN) := Rand.Int (1, 359)
 aO.PS (pN) := Rand.Int (0, pD)
 
 | 
 Functions should be used in place of procedures, wherever possible.  It makes far more sense to assign a variable to the value returned by a function than to allow a procedure full written control over the variable you pass to it.
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| iker 
 
  
 
 
 | 
			
				|  Posted: Tue Feb 14, 2006 4:52 pm    Post subject: (No subject) |  |   
				| 
 |  
				| Thanks for all of the tips, but actualy, after i posted that last message, I decided to make it into a class and everything, and it uses alot of what you guys said, even though I didn't read it before I did it... 
 anyways, heres the class, might be usefull for a game with headshots...
 
 	  | code: |  	  | %Particle unit by Chris "Iker" Iaconis
 unit
 module pervasive Particle
 export spawn, animate
 
 const aOP := 1000 % amount of particles (can be changed to anything)
 
 var pS : array 0 .. 16 of int % particle size
 var pG : array 0 .. 16 of int % particle gravity
 var pFS : array 0 .. 16 of real % particle fade
 var fin : array 0 .. 16 of boolean % check if particle faded
 type particles :
 record
 %each particle of each "Num"'s
 %X, Y, Direction, Speed
 PX, PY, PD : array 0 .. 16, 0 .. aOP of int
 PS : array 0 .. 16, 0 .. aOP of real
 %Red, Green, Blue value
 PR, PG, PB : array 0 .. 16 of real
 %Color
 PC : array 0 .. 16 of int
 end record
 var aO : particles
 var count, countDelay : int := 0
 
 proc spawn (Num, x, y, Color, Size, Gravity : int, FadeSpeed : real)
 pS (Num) := Size
 pG (Num) := Gravity
 pFS (Num) := FadeSpeed
 %color
 RGB.GetColor (Color, aO.PR (Num), aO.PG (Num), aO.PB (Num))
 %x/y start, direction, speed
 for pN : 0 .. aOP
 aO.PX (Num, pN) := x
 aO.PY (Num, pN) := y
 randint (aO.PD (Num, pN), 1, 359)
 aO.PS (Num, pN) := Rand.Int (0, 30) / 5
 end for
 fin (Num) := false
 end spawn
 
 proc animate (Num, particles : int)
 if fin (Num) = false then
 %fade/judge
 if aO.PR (Num) >= .05 then
 aO.PR (Num) -= pFS (Num)
 end if
 if aO.PG (Num) >= .05 then
 aO.PG (Num) -= pFS (Num)
 end if
 if aO.PB (Num) >= .05 then
 aO.PB (Num) -= pFS (Num)
 end if
 if aO.PR (Num) <= .1 and aO.PG (Num) <= .1 and aO.PB (Num) <= .1 then
 fin (Num) := true
 end if
 aO.PC (Num) := RGB.AddColor (aO.PR (Num), aO.PG (Num), aO.PB (Num))
 %grav/move
 for i : 0 .. particles
 if aO.PD (Num, i) > 0 and aO.PD (Num, i) < 175 then
 aO.PD (Num, i) += pG (Num)
 elsif aO.PD (Num, i) < 360 and aO.PD (Num, i) > 185 then
 aO.PD (Num, i) -= pG (Num)
 end if
 aO.PX (Num, i) += round (sind (aO.PD (Num, i)) * aO.PS (Num, i))
 aO.PY (Num, i) += round (cosd (aO.PD (Num, i)) * aO.PS (Num, i))
 drawfilloval (aO.PX (Num, i), aO.PY (Num, i), pS (Num), pS (Num), aO.PC (Num))
 end for
 end if
 end animate
 
 end Particle
 | 
 
 And heres a "program" to call that class
 
 
 	  | code: |  	  | import ("Particle")
setscreen ("offscreenonly,nobuttonbar")
 colorback (black)
 cls
 loop
 Particle.spawn (1, Rand.Int (0, maxx), Rand.Int (0, maxy), Rand.Int (34, 100), 2, 1, .02)
 Particle.spawn (2, Rand.Int (0, maxx), Rand.Int (0, maxy), Rand.Int (34, 100), 2, 1, .02)
 Particle.spawn (3, Rand.Int (0, maxx), Rand.Int (0, maxy), Rand.Int (34, 100), 2, 1, .02)
 Particle.spawn (4, Rand.Int (0, maxx), Rand.Int (0, maxy), Rand.Int (34, 100), 2, 1, .02)
 Particle.spawn (5, Rand.Int (0, maxx), Rand.Int (0, maxy), Rand.Int (34, 100), 2, 1, .02)
 %Particle.spawn (Num, x, y, color, radius, gravityspeed, fadespeed)
 %where
 %   Num = Spawn Number
 %   x/y = X/Y start position
 %   color = start color (1<=color<=255)
 %   radius = particle radius
 %   gravityspeed = how fast moves toward down
 %   fadespeed = how fast it fades to next color
 for i : 0 .. 100 %make sure the last number is as big as the second
 field of any animations
 %Particle.animate (Num, Particles)
 %where
 % Num = Spawn Number
 % Particles = # of particles shown (must be <= aOP in class)
 Particle.animate (1, 100)
 Particle.animate (2, 100)
 Particle.animate (3, 100)
 Particle.animate (4, 100)
 Particle.animate (5, 100)
 Time.DelaySinceLast (10)
 View.Update
 cls
 end for
 end loop
 | 
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| Sponsor Sponsor
 
  
   |  |   
		|  |   
		| [Gandalf] 
 
  
 
 
 | 
			
				|  Posted: Tue Feb 14, 2006 5:06 pm    Post subject: (No subject) |  |   
				| 
 |  
				| That's a module not a class.  While the two may look similar, they really involve completely unique concepts. 
 In a class everything revolves around objects, while a module is basically just a 'shell' for your code.  A module is no doubt useful, but in this case a class would be much better suited since each particle can act as an 'object'.
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| iker 
 
  
 
 
 | 
			
				|  Posted: Tue Feb 14, 2006 5:09 pm    Post subject: (No subject) |  |   
				| 
 |  
				| [Gandalf] wrote: That's a module not a class.  While the two may look similar, they really involve completely unique concepts.
 In a class everything revolves around objects, while a module is basically just a 'shell' for your code.  A module is no doubt useful, but in this case a class would be much better suited since each particle can act as an 'object'.
 I guess I did say class... but I meant module... sry for the mixup, I was just reading about someone saying for me to make it into a class, guess I was thinking module and put class... no worrys
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		| Cervantes 
 
  
 
 
 | 
			
				|  Posted: Tue Feb 14, 2006 6:32 pm    Post subject: (No subject) |  |   
				| 
 |  
				| iker wrote: no worrys But, but!  You still don't have particle objects.
 
 And, why did you make the module pervasive?  What happens if you don't make it pervasive, and import it normally?  ie.
 
 	  | code: |  	  | 
%import <ModuleName>
 import Particle
 
 | 
 
 Be sure to have the module saved as "Particle.tu".  If it's not, you'll have to do something like
 
 	  | code: |  	  | 
import Particle in "[optional_path_to_file/]file_name.extension"
 
 | 
 |  
				|  |  |   
		|  |  |  
	  
		|  |   
		|  |  
 |