Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Particle Engine
Index -> Programming, Turing -> Turing Submissions
Goto page 1, 2  Next
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
zero-impact




PostPosted: Sun Jan 18, 2009 10:14 pm   Post subject: Particle Engine

This is a revamped version of a particle engine I made last year.
It now runs much much faster.

The controls are as follows:

Hold space bar to attract the particles to the mouse.

Hold Control to repulse the particles away from the mouse.

Click and hold the mouse to spawn particles.


Any tips, comments or criticism are greatly appreciated Posted Image, might have been reduced in size. Click Image to view fullscreen.


Note: Try playing around with some of the constants for different effects. Also if it is running too slowly for you just change the MAXPART constant. As well as in the graphics procedure you can uncomment the drawfillbox for a neat effect Smile


code:
%%particlesim%%
setscreen ("graphics:max;max;nobuttonbar;offscreenonly")

type particle :
    record
        x : int
        y : int
        xvel : real
        yvel : real
        col : int
    end record

const GRAV : real := 0.9
const AIR : real := 0.99
const TRANSFER : real := 0.5
const FRIC := 0.8
const NULL := 9876543
const BACKCOL : int := black

var mousex, mousey, mouseClick : int
var spawnRate := 10
const MAXPART := 2000
var part : array 1 .. MAXPART of particle
var mouseAngle : real
var chars : array char of boolean

for i : 1 .. MAXPART
    part (i).x := NULL
    part (i).y := NULL
    part (i).xvel := 0
    part (i).yvel := 0
    part (i).col := 0
end for

var currentPart : int := 0

proc spawnParticle (particlex : int, particley : int)
    for k : 1 .. spawnRate
        if currentPart = MAXPART then
            currentPart := 0
        end if
        currentPart += 1
        part (currentPart).x := particlex + k
        part (currentPart).y := particley

        %part (currentPart).xvel := Rand.Int (-10, 10)
        %part (currentPart).yvel := Rand.Int (1, 4)
        part (currentPart).xvel := cosd (Rand.Int (0,360)) * 10 %Help from http://compsci.ca/v3/viewtopic.php?t=17607
        part (currentPart).yvel := sind (Rand.Int (0,360)) * 10 % help from http://compsci.ca/v3/viewtopic.php?t=17607
       
        part (currentPart).col := Rand.Int (0, 15)

        if part (currentPart).col = black then
            part (currentPart).col += 1
        end if
    end for
end spawnParticle

function getMouseAngle (x, y : real) : real %Help from compsci.ca    http://compsci.ca/v3/viewtopic.php?t=17607
    if x = 0 and y = 0 then
        result 0
    elsif x = 0 and y > 0 then
        result 90
    elsif x = 0 and y < 0 then
        result 270
    elsif y = 0 and x > 0 then
        result 0
    elsif y = 0 and x < 0 then
        result 180
    elsif x > 0 and y > 0 then
        result arctand (y / x)
    elsif x < 0 and y > 0 then
        result 180 + arctand (y / x)
    elsif x > 0 and y < 0 then
        result 360 + arctand (y / x)
    elsif x < 0 and y < 0 then
        result 180 + arctand (y / x)
    else
        result 0
    end if
end getMouseAngle


proc getInput
        Mouse.Where (mousex, mousey, mouseClick)
        if mouseClick = 1 then
            spawnParticle (mousex, mousey)
        end if
end getInput

proc physics
    for i : 1 .. upper (part)

        Input.KeyDown (chars)
        if chars (' ') then
            mouseAngle := getMouseAngle (mousex - part (i).x, mousey - part (i).y)  %%Help from compsci.ca
            part (i).xvel += cosd (mouseAngle) * 2 %Help from http://compsci.ca/v3/viewtopic.php?t=17607
            part (i).yvel += sind (mouseAngle) * 2 % help from http://compsci.ca/v3/viewtopic.php?t=17607
        elsif chars (KEY_CTRL) then
            mouseAngle := getMouseAngle (mousex - part (i).x, mousey - part (i).y)          %%Help from compsci.ca
            part (i).xvel += -round (cosd (mouseAngle) * 2) %Help from http://compsci.ca/v3/viewtopic.php?t=17607
            part (i).yvel += -round (sind (mouseAngle) * 2) % help from http://compsci.ca/v3/viewtopic.php?t=17607
        end if



        if part (i).x = NULL & part (i).y = NULL then
            %do nothing
        else
            if part (i).y > 0 then
                part (i).yvel -= GRAV   %gravity
            end if
            if part (i).y < 0 then
                part (i).y := 0
                part (i).yvel := -part (i).yvel * TRANSFER
            end if
            if part (i).x >= maxx then
                part (i).x := 1
                %part (i).xvel := -part (i).xvel * TRANSFER  %bounce off right wall
                %part (i).on := false
            end if
            if part (i).x <= 0 then
                part (i).x := maxx - 1
                %part (i).xvel := -part (i).xvel * TRANSFER  %bounce off left wall
                %part (i).x := 0
            end if
        end if
        part (i).xvel *= AIR
        part (i).x += round (part (i).xvel)     %adding the x and y vel to the a and y position
        part (i).y += round (part (i).yvel)

    end for
end physics

proc gfx
    drawfillbox (0, 0, maxx, maxy, BACKCOL)     %background
    for i : 1 .. upper (part)
        %drawfillbox (part (i).x, part (i).y, part (i).x + 5, part (i).y + 5, part (i).col) %particle
        drawdot (part (i).x, part (i).y, part (i).col)     %particle
    end for
    View.Update
end gfx

loop
    getInput
    physics
    gfx
    Time.DelaySinceLast (30)
end loop
[/code][/syntax]
Sponsor
Sponsor
Sponsor
sponsor
saltpro15




PostPosted: Sun Jan 18, 2009 10:15 pm   Post subject: RE:Particle Engine

cool, great job lawson Very Happy
Amit




PostPosted: Sun Jan 18, 2009 10:29 pm   Post subject: Re: Particle Engine

Very impressive, this is one of the better particle engines I've seen. Just one thing I saw, you wrote

Turing:

        if part (i).x = NULL & part (i).y = NULL then
            %do nothing
        else
            *physics code*


Another way to do this would be

Turing:

        if not(part (i).x = NULL & part (i).y = NULL) then
            *physics code*


It does that same thing, but it gets rid of the unnecessary else statement.
zero-impact




PostPosted: Sun Jan 18, 2009 10:29 pm   Post subject: Re: Particle Engine

Hey uhm saltpro I dont believe I know who you are?

and thanks Amit, I'm glad you caught that Very Happy
Amit




PostPosted: Sun Jan 18, 2009 10:34 pm   Post subject: Re: Particle Engine

No problem, glad to help. One other thing, there is a constant FRIC that never seems to get used. Something you were going to include?
zero-impact




PostPosted: Mon Jan 19, 2009 7:34 am   Post subject: RE:Particle Engine

Oh yea it was just to stop the particles from sliding along the floor but the air friction works fine.
saltpro15




PostPosted: Mon Jan 19, 2009 1:15 pm   Post subject: RE:Particle Engine

drew
zero-impact




PostPosted: Mon Jan 19, 2009 3:06 pm   Post subject: Re: Particle Engine

oooh hey
Sponsor
Sponsor
Sponsor
sponsor
SNIPERDUDE




PostPosted: Thu Jan 22, 2009 10:18 am   Post subject: RE:Particle Engine

This is a great improvement from last years, I remember it quite well. I'm very surprised at the speed it's running, much faster than mine or any other I've seen, kudos. One thing that should be done I think is make the particles go invisible when the particles stop moving or have a constant altitude (stop moving vertically).

Awesome job 8)
zero-impact




PostPosted: Thu Jan 22, 2009 6:42 pm   Post subject: Re: Particle Engine

Thanks a lot SNIPERDUDE. I'm very surprised that you actually remembered that from the first version I posted.

This is just a small modification I did to show my teacher some things you could do with it.


code:

%%particleSim%%
%Lawson Fulton%
%%%12/19/09%%%%

%Controls:
%Spacebar - attract
%Control - repulse
%Left/Right Mouse - Spawn particles

%Note: Change MAXPART for more or less particles
%      Change SPAWNRATE to change the speed the particles spawn at.

setscreen ("graphics:max;max;nobuttonbar;offscreenonly")

type particle :
    record
        x : int
        y : int
        xvel : real
        yvel : real
        col : int
        prevSize : int
        size : int
        gettingSmaller : boolean
        shape : int %1 box   2 oval
    end record

const MAXPART := 2000
const SPAWNRATE := 10

const GRAV : real := 0
const AIR : real := 0.99
const TRANSFER : real := 0.5
const FRIC := 0.8
const NULL := 9876543
const BACKCOL : int := black
const MAXSIZE := 20


var mousex, mousey, mouseClick : int
var part : array 1 .. MAXPART of particle
var mouseAngle : real
var chars : array char of boolean

for i : 1 .. MAXPART
    part (i).x := NULL
    part (i).y := NULL
    part (i).xvel := 0
    part (i).yvel := 0
    part (i).col := 0
    part (i).prevSize := -1
    part (i).size := 0
    part (i).gettingSmaller := true
    part (i).shape := 0
end for

var currentPart : int := 0

proc spawnParticle (particlex : int, particley : int)
    for k : 1 .. SPAWNRATE
        if currentPart = MAXPART then
            currentPart := 0
        end if
        currentPart += 1
        part (currentPart).x := particlex % + k
        part (currentPart).y := particley

        %part (currentPart).xvel := Rand.Int (-10, 10)
        %part (currentPart).yvel := Rand.Int (1, 4)
        part (currentPart).xvel := cosd (Rand.Int (0, 360)) * 10 %Help from http://compsci.ca/v3/viewtopic.php?t=17607
        part (currentPart).yvel := sind (Rand.Int (0, 360)) * 10 % help from http://compsci.ca/v3/viewtopic.php?t=17607

        part (currentPart).col := Rand.Int (0, 15)
        part (currentPart).size := Rand.Int (1, MAXSIZE - 1)
        part (currentPart).shape := Rand.Int (1, 6)

        if part (currentPart).col = black then
            part (currentPart).col += 1
        end if
    end for
end spawnParticle

function getMouseAngle (x, y : real) : real %Help from compsci.ca    http://compsci.ca/v3/viewtopic.php?t=17607
    if x = 0 and y = 0 then
        result 0
    elsif x = 0 and y > 0 then
        result 90
    elsif x = 0 and y < 0 then
        result 270
    elsif y = 0 and x > 0 then
        result 0
    elsif y = 0 and x < 0 then
        result 180
    elsif x > 0 and y > 0 then
        result arctand (y / x)
    elsif x < 0 and y > 0 then
        result 180 + arctand (y / x)
    elsif x > 0 and y < 0 then
        result 360 + arctand (y / x)
    elsif x < 0 and y < 0 then
        result 180 + arctand (y / x)
    else
        result 0
    end if
end getMouseAngle


proc getInput
    Mouse.Where (mousex, mousey, mouseClick)
    if mouseClick = 1 then
        spawnParticle (mousex, mousey)
    end if
end getInput

proc physics
    for i : 1 .. upper (part)

        Input.KeyDown (chars)
        if chars (' ') then
            mouseAngle := getMouseAngle (mousex - part (i).x, mousey - part (i).y)  %%Help from compsci.ca
            part (i).xvel += cosd (mouseAngle) * 2 %Help from http://compsci.ca/v3/viewtopic.php?t=17607
            part (i).yvel += sind (mouseAngle) * 2 % help from http://compsci.ca/v3/viewtopic.php?t=17607
        elsif chars (KEY_CTRL) then
            mouseAngle := getMouseAngle (mousex - part (i).x, mousey - part (i).y)          %%Help from compsci.ca
            part (i).xvel += -cosd (mouseAngle) * 2 %Help from http://compsci.ca/v3/viewtopic.php?t=17607
            part (i).yvel += -sind (mouseAngle) * 2 % help from http://compsci.ca/v3/viewtopic.php?t=17607
        end if

        part (i).prevSize := part (i).size

        if part (i).gettingSmaller then
            part (i).size -= 1
        elsif ~part (i).gettingSmaller then
            part (i).size += 1
        end if

        if part (i).size >= MAXSIZE or part (i).size <= 0 then
            if part (i).prevSize < part (i).size then
                part (i).gettingSmaller := true
            else
                part (i).gettingSmaller := false
            end if
        end if

        if part (i).x = NULL & part (i).y = NULL then
            %do nothing
        else
            if part (i).y > 0 then
                part (i).yvel -= GRAV   %gravity
            end if
           /* if part (i).y < 0 then
             part (i).y := 0
             part (i).yvel := -part (i).yvel * TRANSFER
             end if
             if part (i).x >= maxx then
             part (i).x := 1 %infinite walls
             %part (i).xvel := -part (i).xvel * TRANSFER  %bounce off right wall
             %part (i).on := false
             end if
             if part (i).x <= 0 then
             part (i).x := maxx - 1 %infinite walls
             %part (i).xvel := -part (i).xvel * TRANSFER  %bounce off left wall
             %part (i).x := 0
             end if*/
        end if
        part (i).xvel *= AIR
        part (i).yvel *= AIR
        part (i).x += round (part (i).xvel)     %adding the x and y vel to the a and y position
        part (i).y += round (part (i).yvel)

    end for
end physics


proc gfx
    drawfillbox (0, 0, maxx, maxy, BACKCOL)     %background
    for i : 1 .. upper (part)
        %drawoval (part (i).x, part (i).y, part (i).size, part (i).size, part (i).col) %particle
        if part (i).shape = 1 then
            drawfillbox (part (i).x, part (i).y, part (i).x + part (i).size, part (i).y + part (i).size, part (i).col)
        elsif part (i).shape = 2 then
            drawfilloval (part (i).x, part (i).y, part (i).size, part (i).size, part (i).col)
        elsif part (i).shape = 3 then
            drawbox (part (i).x, part (i).y, part (i).x + part (i).size, part (i).y + part (i).size, part (i).col)
        elsif part (i).shape = 4 then
            drawoval (part (i).x, part (i).y, part (i).size, part (i).size, part (i).col)
        elsif part (i).shape = 5 then
            drawstar (part (i).x, part (i).y, part (i).x + part (i).size, part (i).y + part (i).size, part (i).col)
        elsif part (i).shape = 6 then
            drawfillstar (part (i).x, part (i).y, part (i).x + part (i).size, part (i).y + part (i).size, part (i).col)
        end if
        %drawdot (part (i).x, part (i).y, part (i).col)     %particle
    end for
    View.Update
end gfx

loop
    getInput
    physics
    gfx
    Time.DelaySinceLast (30)
end loop

saltpro15




PostPosted: Thu Jan 22, 2009 6:51 pm   Post subject: RE:Particle Engine

oh lawson, just had to one-up paul's particle engine eh? xD
A.J




PostPosted: Thu Jan 22, 2009 9:01 pm   Post subject: Re: Particle Engine

congrats Claping

you really outdone yourslef Very Happy (200 lines....wow)

instead of the stars and the constantly shrinking/growing ovals, why not actually have particles instead ? (like dots, for instance)

but u did a really good job Very Happy

well done!
zero-impact




PostPosted: Fri Jan 23, 2009 12:31 pm   Post subject: Re: Particle Engine

Drew- lol not really. Just seeing his inspired me to improve mine a bit.

A.J. - You can very easily change it back to particles if you look at the gfx procedure. You just have to take out the if statements and replace it with drawdot (part (i).x, part (i).y, part (i).col) Smile The stars and such were just to spruce it up a little :p


This is a miniputt game a friend of mine did for his final assignment. It uses the particle engine for the stars.



MiniPutt.zip
 Description:

Download
 Filename:  MiniPutt.zip
 Filesize:  12.32 KB
 Downloaded:  98 Time(s)

saltpro15




PostPosted: Sat Jan 24, 2009 4:11 pm   Post subject: RE:Particle Engine

well now you and paul have me interested in making a particle engine... oh + bits btw
zero-impact




PostPosted: Sat Jan 24, 2009 6:11 pm   Post subject: RE:Particle Engine

Haha ok well if you make one make sure it is better than both of ours combined :p Smile
Display posts from previous:   
   Index -> Programming, Turing -> Turing Submissions
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 2  [ 30 Posts ]
Goto page 1, 2  Next
Jump to:   


Style:  
Search: