# Particles

There are loads of cool particle systems out there: we even a post on it last week.  So I decided to write my own today and here is the video.  The particles follow your mouse as though your mouse pointer was a source of gravity.

Here is the BB4W code for you to play with.

REM Particles
REM version 1.0.0.1
REM T Street
REM 2015-11-08
REM Particles acting under gravity

MODE 12 : OFF
OSCLI
"escape off"
ON ERROR ERROR 0, "Ooops! Something went wrong. A particle probably left the edge of the known universe."
REM global constants

NumParticles% = 200 : REM increase if you have a fast machine

GravityConstant% = 50 : REM increase for stronger gravity

ParticleSize% = 16 : REM size of each particle

REM set up the initial positions of particles

DIM part{(NumParticles%) x, y, dx, dy, red%, green%, blue% }
PROC_randomPositions( part{()}, NumParticles%)
PROC_randomColours( part{()}, NumParticles%)

REM main loop

REPEAT
OSCLI
"refresh off"
CLS
PROC
_showParticles( part{()}, NumParticles%)
MOUSE x, y, click : REM get current position of the mouse

PROC_moveParticles( part{()}, NumParticles%, x, y )
OSCLI "refresh on"
OSCLI "refresh"
UNTIL FALSE

DEFPROC_moveParticles( particle{()}, n%, x, y )
REM find the current distance from the mouse
REM and apply effect on motion of particle

LOCAL i%
LOCAL d : REM distance

FOR i% = 0 TO n%
REM find distance from mouse

d = SQR( ((particle{(i%)}.x - x )^2) +  ((particle{(i%)}.y - y )^2) )
IF d<>0 THEN

REM add new velocity

particle{(i%)}.dx += (GravityConstant% *  (x - particle{(i%)}.x) / d^2 )
particle{(i%)}.dy += (GravityConstant% *  (y - particle{(i%)}.y) / d^2 )
ENDIF

REM change particle's position by speed factor

particle{(i%)}.x += particle{(i%)}.dx
particle{(i%)}.y += particle{(i%)}.dy
NEXT
ENDPROC

DEFPROC_showParticles( particle{()}, n% )
REM show particles on screen

LOCAL i%
FOR i% = 0 TO n%
COLOUR 1, particle{(i%)}.red%, particle{(i%)}.green%, particle{(i%)}.blue%
GCOL 0,1
CIRCLE FILL particle{(i%)}.x, particle{(i%)}.y, ParticleSize%
NEXT
ENDPROC

DEFPROC_randomPositions( particle{()}, n% )
REM assign a new position to the particles at random

LOCAL i%
FOR i% = 0 TO n%
particle{(i%)}.x  = RND(2000)
particle{(i%)}.y  = RND(2000)
NEXT
ENDPROC

DEFPROC_randomColours( particle{()}, n% )
REM assign a new position to the particles at random
REM (blue not used)

LOCAL i%
FOR i% = 0 TO n%
particle{(i%)}.red% = RND(255)
particle{(i%)}.green% = RND(255)
NEXT
ENDPROC

...And here is version 2 which forbids the particles from leaving the confines of the screen.

REM Particles
REM version 1.0.0.2
REM T Street
REM 2015-11-08
REM Particles acting under gravity

MODE 12 : OFF
OSCLI
"escape off"
ON ERROR ERROR 0, "Ooops! Something went wrong. A particle probably left the edge of the known universe."
REM global constants

NumParticles% = 100 : REM increase if you have a fast machine

GravityConstant% = 100 : REM increase for stronger gravity

ParticleSize% = 16 : REM size of each particle

REM set up the initial positions of particles

DIM part{(NumParticles%) x, y, dx, dy, red%, green%, blue% }
PROC_randomPositions( part{()}, NumParticles%)
PROC_randomColours( part{()}, NumParticles%)

REM main loop

REPEAT
OSCLI
"refresh off"
CLS
PROC
_showParticles( part{()}, NumParticles%)
MOUSE x, y, click : REM get current position of the mouse

PROC_moveParticles( part{()}, NumParticles%, x, y )
OSCLI "refresh on"
OSCLI "refresh"
*|wait 1 : rem optional pause
UNTIL FALSE

DEFPROC_moveParticles( particle{()}, n%, x, y )
REM find the current distance from the mouse
REM and apply effect on motion of particle

LOCAL i%
LOCAL d : REM distance

FOR i% = 0 TO n%
REM find distance from mouse

d = SQR( ((particle{(i%)}.x - x )^2) +  ((particle{(i%)}.y - y )^2) )
IF d<>0 THEN

REM add new velocity

particle{(i%)}.dx += (GravityConstant% *  (x - particle{(i%)}.x) / d^2 )
particle{(i%)}.dy += (GravityConstant% *  (y - particle{(i%)}.y) / d^2 )
ENDIF

REM change particle's position by speed factor

particle{(i%)}.x += particle{(i%)}.dx
particle{(i%)}.y += particle{(i%)}.dy
IF particle{(i%)}.x < 0 OR particle{(i%)}.x > 1920 particle{(i%)}.dx = particle{(i%)}.dx *-1
IF particle{(i%)}.y < 0 OR particle{(i%)}.y > 1536 particle{(i%)}.dy = particle{(i%)}.dy *-1
NEXT
ENDPROC

DEFPROC_showParticles( particle{()}, n% )
REM show particles on screen

LOCAL i%
FOR i% = 0 TO n%
COLOUR 1, particle{(i%)}.red%, particle{(i%)}.green%, particle{(i%)}.blue%
GCOL 0,1
CIRCLE FILL particle{(i%)}.x, particle{(i%)}.y, ParticleSize%
NEXT
ENDPROC

DEFPROC_randomPositions( particle{()}, n% )
REM assign a new position to the particles at random

LOCAL i%
FOR i% = 0 TO n%
particle{(i%)}.x  = RND(1920)
particle{(i%)}.y  = RND(1536)
NEXT
ENDPROC

DEFPROC_randomColours( particle{()}, n% )
REM assign a new position to the particles at random
REM (blue not used)

LOCAL i%
FOR i% = 0 TO n%
particle{(i%)}.red% = RND(255)
particle{(i%)}.green% = RND(255)
NEXT
ENDPROC