News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Challenge #22 - Snow Particle Effect

Started by kevin, December 18, 2010, 08:39:43 PM

Previous topic - Next topic

kevin






Challenge #22 - Snow Particle Effect



    With Christmas rapidly approaching,  this challenge is to create a particle effect that gives the viewer a convincing falling snow effect. 




Submission

* Submissions can be written in any version of PlayBASIC

* Submission can only be accepted in Source Code form only.

* Authors can use external Media (images/music) provided you created the media/and or have permission to distribute the includes media or the Media is in the public domain.

* Zip up your Submissions and please try to keep it smaller than 500K !

* Authors automatically give consent for their submission(s) to distributed and used for promotional purposes via UnderwareDesign.com, PlayBasic code tank.

* Authors can submit as many times as they like.

* To make a submission, zip up your projects source code + media and either post it in this thread, or create your own thread in either the Source Codes or Show Case forums and post a link bellow.



Dead Line

     Anytime before the next ice age



Prizes

     * The best submissions will be periodically highlighted through the PlayBasic IDE news service/News Letters or on Twitter



daver

My first try at responding to one of these challenges, hope you like it. I ended up going with a simple algorithm for the snow effect, just to make sure I finished the project!

A couple of features:
D key - makes it day
N key - makes it night
+ on keypad - adds snowflakes
- on keypad - removes snowflakes


darkx

#2
This one uses the library and external media sprite way although it is less efficient. Mostly due to a old library and that the sprites and alpha effects take up a chunk of memory.

Press up to increase the amount of snow particles spawned, down to decrease.


Note:There is no limit to the amount of particles you can spawn. Be sure not to overstress your pc.

monkeybot

#3
just a quickie,i am going to add settling snow when i get around to it...
PlayBASIC Code: [Select]
; PROJECT : so fake snowflake
; AUTHOR : Monkeybot
; CREATED : 04/01/2011
; EDITED : 04/01/2011
; ---------------------------------------------------------------------
explicit on
constant gravity=1
Constant SnowNum=1

type t_flake
x#
y#
cnt#
mstep#
min#
max#
endtype
local g
dim flake as t_flake list
setfps(50)
repeat
for g=0 to SnowNum
flake =new t_flake
flake.x#=rnd(800)
flake.cnt=rndrange(150,210) ;set start point
flake.y#=-rnd(50)
flake.mstep#=rndrange#(-1,1)
; flake.min#=rndrange(90,180)
; flake.max#=rndrange(180,270)
next
cls
lockbuffer
print "No of flakes "+str$(getlistsize(flake()))
for each flake()
flake.y#+=gravity
flipflop3(flake.x#,flake.y#,150,210,30,60)
if flake.y>600 then flake=null
next
UnLockBuffer
sync
until false

;
function flipFlop3(x# ,y#,min#,max#,xr#,yr#)

;0=left 1=right
; print "min "+str$(min#)
; print "max "+str$(max#)
; print "x "+str$(x#)
; print "y "+str$(y#)
; print "flake.cnt "+str$(flake.cnt#)
; print "flake.mstep "+str$(flake.mstep#)
if flake.mstep#>0
flake.cnt#+=flake.mstep#
if flake.cnt#>max# then flake.mstep#=-flake.mstep#;end
endif

if flake.mstep#<0
flake.cnt#-=abs(flake.mstep#)
if flake.cnt#<min# then flake.mstep#=abs(flake.mstep#);end
endif
circle x#+(sin(flake.cnt)*xr#),y#-(cos(flake.cnt)*yr#),2,1
endfunction



kevin


Nice ! - There's some really elegant solutions there !

monkeybot

done a version with settling effect,more difficult than i imagined!


http://dl.dropbox.com/u/19400361/snowflake.rar

kevin

#6
  Looks pretty good, but there's a few tidbits that could be fine tuned though.  


 The move snow routine can be tweaked so the cost per flake is reduced, for example.

PlayBASIC Code: [Select]
function movesnow2()
local ypos

for each flake()
flake.y#+=gravity
flipflop3(150,210)
ypos=gety(flake.x#);-60

; couldn't this this stored in the ground height, so it's absolute comparison. Which means less instructions per flake
if flake.y#>((sh-(imageheight-ypos))-ySwing);+3
hitLand(flake.x#,flake.y#)
endif
next
endfunction

Psub gety(num#)
local y,t=abs(num#)
SetListPos land(),t
y=land.y
EndPsub y


Psub flipFlop3(min#,max#)
;,xr#,yr#)
if flake.mstep#>0
flake.cnt#+=flake.mstep#
if flake.cnt#>max# then flake.mstep#*=-1
else
; Note: the ABS function of Mstep could be
; removed and stored in the structure.
flake.cnt#-=abs(flake.mstep#)
if flake.cnt#<min# then flake.mstep#=abs(flake.mstep#)
endif
endPsub




  You can take this further by using a 1d array to store the grounds height rather than a list, which is significantly less overhead than reading a field in a type.  The ground collision could also store the  highest peek in a global variable for example, so the Y cord is first compared against the highest current peek, which could act as an early rejection for flakes that can't possibly have hit the ground.  Which is going to be say %60 of them..  

  While i think of it, got to careful using too many 'small task' functions in tight loops like this (ie flipFlop3() and gety() ).  Every time you call a function there can be a pretty hefty overhead (the more locals these functions have the bigger the cost), so swapping them to Projected subroutines (psub) can be an easy way of winning back some free time.   The same applies to passing parameters in that aren't being used.  It's just wasted cycles in the vm.  


 


monkeybot

#7
cool thanks.Food for thought.