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