UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: darkx on July 27, 2009, 11:36:23 PM

Title: Simple particle library
Post by: darkx on July 27, 2009, 11:36:23 PM
Help file code below or just copy it from the post

[pbcode]
; PROJECT : particle
; AUTHOR  : user
; CREATED : 7/21/2009
; EDITED  : 7/26/2009
; THE NEW PARTICLE ENGINE VERSION 1.0
; ---------------------------------------------------------------------

`remove test when done
`#Include "Framesheetanims.pba"

`List of things to do


RemStart
~Create Animated particles
~Create Normal Particles
~Create Alpha Normal Particles
~Create Alpha Animated Particles
RemEnd



`1 for camera 0 for no camera
`Global ParticleCamera
`The number of the camera you want to use
`Global ParticleCameraNum
RemStart
`set sw and sh to global
Global ParticleSw
Global ParticleSh


`screen width
ParticleSw=GetScreenWidth()
`Screen Height
ParticleSh=GetScreenHeight()
RemEnd

`load particle images
Type particleimg
pimganimated
pimgnum
pimgframe
index
EndType


Dim partimg As particleimg List

`Particle Variables
Type particlevar
index
particleanime
particleanimated
particleframe
particlelife#
particledecrease#
particlex
particley
particlexdir
particleydir
particlealpha
particleimgnum
particlesprite
particlespeedx
particlespeedy
particleef
EndType

Dim particle As particlevar List





`test loop
RemStart
ParticleCamera=0

SetFPS 80

FrameSheetDefaultImageType=2
FrameSheetRGBMask=1

createnaptype(1,"dust.png",RGB(255,0,255))
createaptype(2,"duster.png",30,30,RGB(53,153,53))

Do
DrawOrderedSprites

`drawimage partimg.pimgnum,mousex(),mousey(),1



If MouseButton()=1

addparticle(1,1,1,0.01,MouseX(),MouseY(),1,1,2,2,1)
`addanimatedparticle(2,10,0,1,0.01,MouseX(),MouseY(),RndRange(1,2),RndRange(1,2),2,2,1,3)
FlushMouse
EndIf

If MouseButton()=2
deleteallparticle()
FlushMouse
EndIf

updateparticle()




Sync
Cls 0
Loop

RemEnd
`end of test loop

`functions


`add normal particle types(non-animated)

Function createnaptype(r,i$,e)
partimg = New particleimg
partimg.index=r
partimg.pimganimated=0
partimg.pimgnum=LoadNewFxImage(i$)
RGBMaskImage  partimg.pimgnum, $00ffffff
ImageMaskColour partimg.pimgnum,e
EndFunction

`add animated particle types
Function createaptype(r,i$,fw,fh,e)
partimg = New particleimg
partimg.index=r
partimg.pimganimated=1
`pimgnum
partimg.pimgframe=LoadFrameSheet(i$,fw,fh,e)
EndFunction

`delete non animated type
Function deletenaptype(r)
deleteallparticle()
For Each partimg()
If partimg.index=r
DeleteImage partimg.pimgnum
partimg=null
EndIf
Next
EndFunction

`deleteanimated type
Function deleteaptype(r)
deleteallparticle()
For Each partimg()
If partimg.index=r
deleteframesheet(partimg.pimgframe)
partimg=null
EndIf
Next
EndFunction

`delete all types
Function deleteallparticletype()
deleteallparticle()
For Each partimg()

If partimg.pimganimated=0
DeleteImage partimg.pimgnum
partimg=null
EndIf

If partimg.pimganimated=1
deleteframesheet(partimg.pimgframe)
partimg=null
EndIf

Next
EndFunction


`Add animated Particle
Function addanimatedparticle(in,rate,palpha,plife#,plifed#,psx,psy,pdirx,pdiry,pspeedx,pspeedy,pspx,endframe)
particle = New particlevar
particle.index=in
particle.particlealpha=palpha
For Each partimg()
If particle.index=partimg.index
particle.particleframe=partimg.pimgframe
EndIf
Next
particle.particleimgnum=NewAnim(particle.particleframe,rate)
particle.particlelife#=plife#
particle.particledecrease#=plifed#
particle.particlex=psx
particle.particley=psy
particle.particlesprite=NewSprite(particle.particlex,particle.particley,getanimimage(particle.particleimgnum))
If particle.particlealpha=1
If particle.particlelife#>1 Then particle.particlelife#=1
If particle.particledecrease#>1 Then particle.particledecrease#=1
SpriteDrawMode particle.particlesprite,4
EndIf
particle.particlexdir=pdirx
particle.particleydir=pdiry
particle.particlespeedx=pspeedx
particle.particlespeedy=pspeedy
particle.particleanimated=1
particle.particleef=endframe
PositionSpriteZ particle.particlesprite,pspx
EndFunction

`Add non animated Particle
Function addparticle(in,palpha,plife#,plifed#,psx,psy,pdirx,pdiry,pspeedx,pspeedy,pspx)
particle = New particlevar
particle.index=in
particle.particlealpha=palpha
For Each partimg()
If partimg.index=in
particle.particleimgnum=partimg.pimgnum
EndIf
Next
particle.particlelife#=plife#
particle.particledecrease#=plifed#
particle.particlex=psx
particle.particley=psy
particle.particlesprite=NewSprite(particle.particlex,particle.particley,particle.particleimgnum)
If particle.particlealpha=1
If particle.particlelife#>1 Then particle.particlelife#=1
If particle.particledecrease#>1 Then particle.particledecrease#=1
SpriteDrawMode particle.particlesprite,4
EndIf
particle.particlexdir=pdirx
particle.particleydir=pdiry
particle.particlespeedx=pspeedx
particle.particlespeedy=pspeedy
particle.particleanimated=0
PositionSpriteZ particle.particlesprite,pspx
EndFunction

`Update particles
Function updateparticle()
For Each particle()



If particle.particleanimated=0

`left
If particle.particlexdir=1
particle.particlex=particle.particlex-particle.particlespeedx
EndIf

`right
If particle.particlexdir=2
particle.particlex=particle.particlex+particle.particlespeedx
EndIf

`up
If particle.particleydir=1
particle.particley=particle.particley-particle.particlespeedy
EndIf

`down
If particle.particleydir=2
particle.particley=particle.particley+particle.particlespeedy
EndIf

If particle.particlealpha=1
SpriteAlphaLevel particle.particlesprite,particle.particlelife#
EndIf

particle.particlelife#=particle.particlelife#-particle.particledecrease#

If particle.particlelife#<=0
If GetSpriteStatus(particle.particlesprite)=1
DeleteSprite particle.particlesprite
EndIf
particle=null
EndIf

EndIf

If particle.particleanimated=1
For Each partimg()
If particle.index=partimg.index
SpriteImage particle.particlesprite,Stepanim(particle.particleimgnum)

`left
If particle.particlexdir=1
particle.particlex=particle.particlex-particle.particlespeedx
EndIf

`right
If particle.particlexdir=2
particle.particlex=particle.particlex+particle.particlespeedx
EndIf

`up
If particle.particleydir=1
particle.particley=particle.particley-particle.particlespeedy
EndIf

`down
If particle.particleydir=2
particle.particley=particle.particley+particle.particlespeedy
EndIf

If particle.particlealpha=1
SpriteAlphaLevel particle.particlesprite,particle.particlelife#
EndIf

particle.particlelife#=particle.particlelife#-particle.particledecrease#


If particle.particlelife#<=0 Or (GetAnimPos(particle.particleimgnum)>=particle.particleef And particle.particleef<>0)
If GetSpriteStatus(particle.particlesprite)=1
DeleteSprite particle.particlesprite
EndIf
deleteanim(particle.particleimgnum)
particle=null
EndIf
EndIf
Next
EndIf

If particle<>null
PositionSprite particle.particlesprite,particle.particlex,particle.particley
EndIf
Next
EndFunction



`delete all particles
Function deleteallparticle()
For Each particle()
particle.particlelife#=0
Next
updateparticle()
EndFunction

[/pbcode]


Help File
QuoteParticle Command list:



createnaptype(Index,Dir,rgb)
dir = Where the image is stored.
rgb = Mask colour the colour which is not shown when the particles are created.

Description
This command is used to load and create a particle type for use in Addparticle.

addparticle(Index,ParticleAlpha,Particlelife,Particlelifed,Particlestartx,Particlestarty,ParticleDirectionx,Particledirectiony,Particlespeedx,Particlespeedy,Particlezposition)
Index = The index of an image.
ParticleAlpha = If set to 1 particle will use alpha.
Particlelife = How long the particle will appear for. If alpha is set to one the max life is 1.
Particlelifed = How much the life will decrease by. If alpha is set to one the max life decrease is 1.
Particlestartx = The X position the particle will start at.
Particlestarty = The Y position the particle will start at.
ParticleDirectionx = The X direction the particle will go. 1 for left, 2 for right.
ParticleDirectiony = The Y direction the particle will go. 1 for up, 2 for down.
Particlespeedx = The speed it will move with along the X.
Particlespeedy = The speed it will move with along the Y.
Particlezposition = The depth of which it is drawn.

Description
This command is used to make a non-animated, alpha or non-alpha particle.

createaptype(Index,dir,FrameWidth,FrameHeight,Rgb)
Index = The index of an image
Dir = Where the file is stored.
FrameWidth = The width of the animated frame.
FrameHeight = The height of the animated frame.
Rgb = The colour which will not be displayed when particles are drawn.
Description
This command is used to add animated particle types.
addanimatedparticle(Index,Rate,ParticleAlpha,Particlelife,Particlelifed,Particlestartx,Particlestarty,ParticleDirectionx,Particledirectiony,Particlespeedx,Particlespeedy,Particlezposition,endframe)
Endframe = The Frame which the animated particle is deleted. Set to 0 for off.
Index = The index of an image.
rate= The Speed of which the particle will animate at.
ParticleAlpha = If set to 1 particle will use alpha.
Particlelife = How long the particle will appear for. If alpha is set to one the max life is 1.
Particlelifed = How much the life will decrease by. If alpha is set to one the max life decrease is 1.
Particlestartx = The X position the particle will start at.
Particlestarty = The Y position the particle will start at.
ParticleDirectionx = The X direction the particle will go. 1 for left, 2 for right.
ParticleDirectiony = The Y direction the particle will go. 1 for up, 2 for down.
Particlespeedx = The speed it will move with along the X.
Particlespeedy = The speed it will move with along the Y.
Particlezposition = The depth of which it is drawn.


Description
This command is used to make a animated, alpha or non-alpha particle.

Updateparticle()
Description
Used to update the particle positions and animated particle images(Requires you to call draworderedsprites in your loop).

deleteallparticle()

Description
Delete all particles.
deletenaptype(index)

Index = The index of the type you wish to delete.

Description
Delete non animated particle types.

deleteaptype(index)

Index = The index of the type you wish to delete.

Description
Delete animated types.

deleteallparticletype()

Description
Delete all particle type.


Feel free to modify, and report any bug if you find any  ;).


I will also post an example and screenshots later.


[Edit]
I forgot to mention that this requires framesheetanims.pba V0.02
Title: Re: Simple particle library
Post by: darkx on July 28, 2009, 12:05:52 AM
IT RAINING....RAIN ;D!!!

Example:
[plink]Download Source Code (http://www.underwaredesign.com/forums/index.php?action=dlattach;topic=3135.0;attach=2823)[/plink]

Title: Re: Simple particle library
Post by: Deano on July 28, 2009, 08:13:35 AM
Very cool! Nice work
Title: Re: Simple particle library
Post by: kevin on August 04, 2009, 01:54:02 AM

DarkX,

      Looks like somebody's building a game engine :)    -   Anyway,  You should think about implementing some form of  higher level Emitter wrapper..  So the user generates the emitter  with a set of properties.  The emitter is then tied to a sprites orientation.  So the user can basically just create the emitter and then call the update routine in their main loop, ie set and forget about it.  It'd have to be killed once the parent object dies though.      Further more,  you could add another abstraction layer above the emitter level.  These could be some built in styles,  such as fire,  exhaust smoke,  explosions etc..   

Title: Re: Simple particle library
Post by: darkx on August 06, 2009, 06:08:29 PM
Thanks for the advice Kevin. I'll keep that in mind when I build a newer more complex particle library.

[edit]
After a second thought I think adding an emitter by using this seems easy enough, but I'll do it later(After I either fail or lose motives on my current idea :P). Although the user will still have to load up the particle image, as for the styles I'm not quite sure how to add the fire style or smoke style mainly because I don't know how those particles are suppost move ???.
Title: Re: Simple particle library
Post by: ATLUS on August 06, 2009, 09:16:35 PM
good work ;)
Title: Re: Simple particle library
Post by: kevin on August 07, 2009, 01:27:45 AM
Quote from: darkx on August 06, 2009, 06:08:29 PM
Thanks for the advice Kevin. I'll keep that in mind when I build a newer more complex particle library.

[edit]
After a second thought I think adding an emitter by using this seems easy enough, but I'll do it later(After I either fail or lose motives on my current idea :P). Although the user will still have to load up the particle image, as for the styles I'm not quite sure how to add the fire style or smoke style mainly because I don't know how those particles are suppost move ???.

   Flames need to move in the direction of the emitter.   They could move and uniform speed, or decelerate.  Size wise they chunks get smaller in size as does their intensity.     

  Smoke could just move up at a fixed rate expanding and fading as it goes..

  It really depends upon what local controls each particle currently has.     


  Anyway here's a few examples..

   Particle Candle  (http://www.underwaredesign.com/forums/index.php?topic=2454.0)
 
   another approach for Fire is via  procedural effect.  There's some old examples       here (http://www.underwaredesign.com/forums/index.php?topic=1800.0)


Title: Re: Simple particle library
Post by: darkx on August 07, 2009, 01:54:48 PM
Flame particle animation can be done via addanimatedparticles by adding alpha and making a shrinking particle animation. As for the speed deceleration I'll have to add that.

[edit]
I could also use scale sprite but that wouldn't be as fast as animations would it?
Title: Re: Simple particle library
Post by: darkx on August 07, 2009, 02:21:38 PM
I seem to be having trouble making the sprites move does positionsprite support floats?
Title: Re: Simple particle library
Post by: kevin on August 07, 2009, 02:24:43 PM
[pbcode]

 cls 255
 getimage 1,0,0,16,16
 
 spr=newsprite(100,100,1)
 
 
 setfps 30
 
 Do
    cls 0
 
   Positionsprite spr,GetSpriteX(spr)+0.25,GetSpriteY(spr)
   
   print GetSpriteX(spr)
   print GetSpriteY(spr)

      drawallsprites
   
    Sync
 loop



[/pbcode]

Title: Re: Simple particle library
Post by: darkx on August 07, 2009, 02:46:43 PM
Okay all done! :D. The speed can now be reduced and the particles can be move using floats for more precision.
Sorry about the post above Kevin, it would seem that I forgot to add a # at the end of a variable(Pesky little things aren't they?).  I've also update the help file in the download file. I'll work on adding styles later, although I think it should be easy enough for the user already.

P.S. Sorry I still haven't added emitters, but that shouldn't be too hard for the user to write ;).



Download:
[plink]Download Particle Library /demo (http://www.underwaredesign.com/forums/index.php?action=dlattach;topic=3135.0;attach=2874)[/plink]
Title: Re: Simple particle library
Post by: darkx on August 07, 2009, 03:35:19 PM
A Fire Example, although it would work better with better sprites. I also suggest you cap the fps at 80 for this example.

[edit]
I also suggest adding an option in your framsheetanims to remove the alpha so we can just use RGB. It also makes me wonder if I should enter cleaver coder challenge 4 with this :D

Quick Update
I've changed the functions to psub and I've also added a new command called maxparticle(amount)
Title: Re: Simple particle library
Post by: kevin on August 16, 2023, 09:24:53 AM
  PlayBASIC - Particle LIbrary Demo

 This video shows fire effect created using DarkX's particle library for PlayBASIC from way back in 2009.  


 



 Related Examples:

     -  PlayBASIC Vector Blast Processing (2023-06-23) (https://www.underwaredesign.com/forums/index.php?topic=4738.0)

      - Alpha Particles (Project pack example) (https://www.underwaredesign.com/forums/index.php?topic=4404.0)



 Source Code

 Attached bellow