[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"
 
  | 	 
  | 
			 
			
				 | 
			 
		  | 
	 
	 
		 | 
		
		 | 
	 
	  
		  | 
	 
				 
		 | 
	 
 
	
	
	 
	
	 |