Dark Bit Factory & Gravity

PROGRAMMING => Other languages => Blitz => Topic started by: mike_g on December 30, 2006

Title: Some particle FX[BB2D]
Post by: mike_g on December 30, 2006
Ive been coding in Blitz for about a year now, but only just got round to having a go at doing particle effects. Theres some pretty amazing stuff on this site. Makes me feel kinda dumb. Anyway heres my attempt. Its kinda like a slinky thing that follows the mouse around.
Code: [Select]
Graphics 1024, 768
Global particles = CreateImage(GraphicsWidth(), GraphicsHeight())
Global count, oldtime, fps ;for fps
Global mode
Global col_timer, col_change
SeedRnd MilliSecs()

Type particle
Field x#, y#, id, ang#, spd
;For colour effects
Field r, g, b; rf, gf, bf
;for circle particles. start size and expand rate
Field rad#, expand#, expand_max
End Type

Global rf =5
Global gf =5
Global bf =5

SetBuffer BackBuffer()
While Not KeyHit(1)
Cls
If mode = 0
NEW_BURST(MouseX(), MouseY(),10)
CIRCLE_PARTICLES(0)
Text 460, 0, "MOVE THE MOUSE"
If mousehit(1) Then mode = 1
COL_CHANGE()
Else
If Rand(0, 2) = 0 Then NEW_BURST(Rand(0, 1023), Rand(0, 768),Rand(10, 30))
CIRCLE_PARTICLES(1)
t=t+ 1
If t > 100
mode = 0
t=0
EndIf
EndIf

DrawImage particles, 0, 0
FPS()
Flip
Wend

;---------------------------;
Function NEW_BURST(x_pos, y_pos, parts)
a_step# = Float(360)/parts
test = a_step#
For i = 1 To parts
p.particle = New particle
p\x = x_pos
p\y = y_pos
p\ang# = angle#
angle# = angle# + a_step#


p\expand = 0.1
p\rad = 0.1
p\expand_max = 10
p\spd = 1
p\rad = 0.1
p\expand_max = 30
p\spd = 1
If mode = 1 Then p\expand = Float(Rand(1, 5))/10

p\r = 255
p\g = 255
p\b = 255
Next
End Function
;---------------------------;
Function CIRCLE_PARTICLES(fill)
SetBuffer ImageBuffer(particles)
Cls
LockBuffer
For p.particle = Each particle
If p\x < -rad Or p\x >= GraphicsWidth()+rad Or p\y < -rad Or p\y >= GraphicsWidth()+rad
Delete p.particle
Else
If p\rad# < p\expand_max Then p\rad# = p\rad# + p\expand#


If p\r >= rf Then p\r = p\r - rf
If p\g >= gf Then p\g = p\g - gf
If p\b >= bf Then p\b = p\b - bf
col = (p\r Shl 16) + (p\g Shl 8) + p\b

p\x = p\x +Cos(p\ang)*p\spd
p\y = p\y +Sin(p\ang)*p\spd
If fill = 0
CIRCLE(p\x, p\y, p\rad, col)
Else
F_CIRCLE(p\x, p\y, p\rad, col)
EndIf
If col <= (rf Shl 16)+(gf Shl 8)+bf Then Delete p.particle
EndIf
Next


UnlockBuffer
SetBuffer BackBuffer()
End Function
;---------------------------;
Function CIRCLE(cx, cy, rad, col)
inc# = Float(360/(rad*Pi*2))
steps = 360/inc#
For i = 0 To steps
x = (cx - rad * Cos(deg#))
y = (cy - rad * Sin(deg#))
If x >= 0 And x < GraphicsWidth() And y >= 0 And y < GraphicsHeight()
WritePixelFast x, y, col
EndIf
deg# = deg# + inc#
Next
End Function
;---------------------------;
Function F_CIRCLE(cx, cy, rad, col)
inc# = Float(360/(rad*Pi*2))
steps = 90/inc#
For i = 0 To steps
x1 = (cx - rad * Cos(deg#))
y1 = (cy - rad * Sin(deg#))

x2 = cx+cx-x1
y2 = cy+cy-y1

If x1 < 0 Then x1 = 0
If x2 > 1023 Then x2 = 1023
If y1 < 0 Then y1 = 0
If y1 > 767 Then y1 = 767
If y2 < 0 Then y2 = 0
If y2 > 767 Then y2 = 767

For x = x1 To x2
WritePixelFast x, y1, col
Next
For x = x1 To x2
WritePixelFast x, y2, col
Next
deg# = deg# + inc#
Next
End Function
;---------------------------;
Function FPS()
Text 0, 0, "FPS: "+fps
time = MilliSecs() - oldtime
count = count + 1
If time >= 1000
fps = count
count = 0
oldtime=MilliSecs()
EndIf
End Function
;---------------------------;
Function COL_CHANGE()
col_timer = col_timer + 1
If col_timer = 10
col_timer = 0
If col_change = 0
rf = rf - 1
If rf = 0
col_change = col_change + 1
EndIf
Else If col_change = 1
rf = rf + 1
gf = gf - 1
If gf = 0
col_change = col_change + 1
EndIf
Else If col_change = 2
bf = bf - 1
gf = gf + 1
If bf = 0
col_change = col_change + 1
EndIf
Else If col_change = 3
rf = rf - 1
gf = gf - 1
bf = bf + 1
If rf = 0
col_change = col_change + 1
EndIf
Else If col_change = 4
rf = rf + 1
bf = bf - 1
If bf = 0
col_change = col_change + 1
EndIf
Else If col_change = 5
bf = bf + 1
gf = gf + 1
If bf = 5
col_change =  0
EndIf
EndIf
EndIf
End Function
Title: Re: Some particle FX
Post by: Shockwave on December 30, 2006
Cheers for the source :) I can't run it on this comp as I don't have blitz installed but have some karma. Someone else will be able to run it.  O0
Title: Re: Some particle FX
Post by: mike_g on December 30, 2006
What no BB? Oh well. I uploaded an exe to my site for anyone that aint got it here (http://www40.brinkster.com/mikegrundel/)
Stupid brinkster dosent let me do remote linking. So you will have to click on the "Particle Thing" link there.
(http://i92.photobucket.com/albums/l15/mikegrundel/Particles.png)

Title: Re: Some particle FX
Post by: Shockwave on December 30, 2006
Thanks for the exe :) And that is bloody good. I like the explosions :)
Title: Re: Some particle FX
Post by: mike_g on December 30, 2006
Thanx. Yeah the explosions arent too bad. My FPS goes down to about 30 though when they go off. (My laptops got a 1.46ghz Athlon + 16MB mobility U1 graphics card). Anyway I plan on working on the speed a bit and adding more different kinds of effects. Hopefully I'll be able to use some of this stuff in a game someday.
Title: Re: Some particle FX
Post by: Stonemonkey on December 31, 2006
Nice stuff but i get a MAV a few moments after clicking the mouse :( possibly something being drawn offscreen?
Title: Re: Some particle FX
Post by: Jim on December 31, 2006
Me too, it crashes with the explosions.  Nice fx though!

edit: I think you need to check y1 and y2 more carefully in the 2nd loop.

Jim
Title: Re: Some particle FX
Post by: mike_g on December 31, 2006
Thats really strange. Doesent crash for me. I dont think that the problem would be that its drawing off screen.

This is the code that constarains the empty circle to the screen:
Code: [Select]
If x >= 0 And x < GraphicsWidth() And y >= 0 And y < GraphicsHeight()And this constarins the filled circles (x1 = x start pos; x2 = x end pos, etc):
Code: [Select]
If x1 < 0 Then x1 = 0
If x2 >= GraphicsWidth() Then x2 =GraphicsWidth()-1
If y1 < 0 Then y1 = 0
If y2 >= GraphicsHeight() Then y2 = GraphicsHeight()-1

If either of you guys have Blitz Basic. You could try run the prog with the debug on. That might help me to find out what going wrong. Cheers.

EDIT:
Quote from: Jim
edit: I think you need to check y1 and y2 more carefully in the 2nd loop.
Will do. /EDIT
Title: Re: Some particle FX
Post by: Ghost^BHT on December 31, 2006
Nice effect :)
change your bounds checking to this:
        If x1 < 0 Then x1 = 0
   If x2 > 767 Then x2 =767
   If y1 < 0 Then y1 = 0
   If y1 > 767 y1 = 767
   If y2 < 0 Then y2 = 0
   If y2 > 767 Then y2 =  767
should work
Title: Re: Some particle FX
Post by: mike_g on December 31, 2006
Okay cool. I modified the code and uploaded the new exe.

Only thing I did different was do this:  If x2 > 1023 Then x2 = 1023
Instead of this: If x2 > 767 Then x2 =767

As I figured it may have been a typo. Then again maybe it wasent but hopefully it should fix things.
Title: Re: Some particle FX
Post by: Jim on December 31, 2006
Yeah, that looks like a typo.  You've fixed it though and it works like a charm now.

It would make a really cool demo if you added some automatic mouse movements (sine waves, etc) and even timed it in with some music.

It's a really nice effect.

Jim
Title: Re: Some particle FX
Post by: mike_g on December 31, 2006
Quote from: Jim
It would make a really cool demo if you added some automatic mouse movements (sine waves, etc) and even timed it in with some music.

Yeah mabe next year :P In the mean time have fun peeps  :D
Title: Re: Some particle FX
Post by: Jim on January 01, 2007
It's next year now.  Where is it!? :p :D :D

Jim
Title: Re: Some particle FX
Post by: mike_g on January 01, 2007
Okay. Heres something for the new year :D The movements automatic now, no sound yet though.

I also replaced my empty circle function with a Bresenham version wrote by Gosse as its over twice as fast.

I uploaded an exe here (http://www40.brinkster.com/mikegrundel/). Its the fizzy vortex link.

And heres the code:
Code: [Select]
Graphics 1024, 768
Global particles = CreateImage(GraphicsWidth(), GraphicsHeight())
Global count, oldtime, fps ;for fps
Global mode
Global col_timer, col_change
SeedRnd MilliSecs()

Type particle
Field x#, y#, id, ang#, spd
;For colour effects
Field r, g, b; rf, gf, bf
;for circle particles. start size and expand rate
Field rad#, expand#, expand_max
End Type

Global rf =10
Global gf =10
Global bf =10

cx = 512: cy = 360: radius = 100
radmod = 1: degmod = 5

SetBuffer BackBuffer()
While Not KeyHit(1)
Cls
If mode = 0
degree = degree + degmod
If degree = 360 Then degree = 0

radius = radius + radmod
If radius > 300 Then radmod = -1
If radius < 50 Then radmod = 1

x_pos = (cx - radius * Cos(degree))
y_pos = (cy - radius * Sin(degree))
x_pos2 = (cx + radius * Cos(degree))
y_pos2 = (cy + radius * Sin(degree))

NEW_BURST(x_pos, y_pos, 8)
NEW_BURST(x_pos2, y_pos2, 8)

CIRCLE_PARTICLES(0)
Text 460, 0, "MOVE THE MOUSE"
If MouseHit(1)  Then mode = 1
If MouseHit(2) degmod = - degmod
COL_CHANGE()
Else
If Rand(0, 2) = 0 Then NEW_BURST(Rand(0, 1023), Rand(0, 768),Rand(10, 30))
CIRCLE_PARTICLES(1)
t=t+ 1
If t > 100
mode = 0
t=0
EndIf
EndIf

DrawImage particles, 0, 0
FPS()
Flip
Wend
;---------------------------;
Function NEW_BURST(x_pos, y_pos, parts)
a_step# = Float(360)/parts
test = a_step#
For i = 1 To parts
p.particle = New particle
p\x = x_pos
p\y = y_pos
p\ang# = Rand(0, 356)
p\expand = 0.1
p\rad = 0.1
p\expand_max = 10
p\spd = 1
p\rad = 0.1
p\expand_max = 30
p\spd = 1
If mode = 1 Then p\expand = Float(Rand(1, 5))/10

p\r = 255
p\g = 255
p\b = 255
Next
End Function
;---------------------------;
Function CIRCLE_PARTICLES(fill)
SetBuffer ImageBuffer(particles)
Cls
LockBuffer
For p.particle = Each particle
If p\x < -rad Or p\x >= GraphicsWidth()+rad Or p\y < -rad Or p\y >= GraphicsWidth()+rad
Delete p.particle
Else
If p\rad# < p\expand_max Then p\rad# = p\rad# + p\expand#


If p\r >= rf Then p\r = p\r - rf
If p\g >= gf Then p\g = p\g - gf
If p\b >= bf Then p\b = p\b - bf
col = (p\r Shl 16) + (p\g Shl 8) + p\b

p\x = p\x +Cos(p\ang)*p\spd
p\y = p\y +Sin(p\ang)*p\spd
If fill = 0
CIRCLE(p\x, p\y, p\rad, col)
Else
F_CIRCLE(p\x, p\y, p\rad, col)
EndIf
If col <= (rf Shl 16)+(gf Shl 8)+bf Then Delete p.particle
EndIf
Next


UnlockBuffer
SetBuffer BackBuffer()
End Function
;---------------------------;
Function CIRCLE(cx, cy, radius, col)
   d = 3 - (radius Shl 1)
   x = 0
   y = radius
   LockBuffer
   Repeat
      WritePixel cx + x, cy + y, col
      WritePixel cx + x, cy - y, col
      WritePixel cx - x, cy + y, col
      WritePixel cx - x, cy - y, col
      WritePixel cx + y, cy + x, col
      WritePixel cx + y, cy - x, col
      WritePixel cx - y, cy + x, col
      WritePixel cx - y, cy - x, col
      If d < 0 Then
         d = d + (x Shl 2) + 6
      Else
         d = d + ((x-y) Shl 2) + 10
         y = y - 1
      End If
      x = x + 1
   Until x > y
   UnlockBuffer
End Function
;---------------------------;
Function F_CIRCLE(cx, cy, rad, col)
inc# = Float(360/(rad*Pi*2))
steps = 90/inc#
For i = 0 To steps
x1 = (cx - rad * Cos(deg#))
y1 = (cy - rad * Sin(deg#))

x2 = cx+cx-x1
y2 = cy+cy-y1

If x1 < 0 Then x1 = 0
If x2 > 1023 Then x2 = 1023
If y1 < 0 Then y1 = 0
If y1 > 767 Then y1 = 767
If y2 < 0 Then y2 = 0
If y2 > 767 Then y2 = 767

For x = x1 To x2
WritePixelFast x, y1, col
Next
For x = x1 To x2
WritePixelFast x, y2, col
Next
deg# = deg# + inc#
Next
End Function
;---------------------------;
Function FPS()
Text 0, 0, "FPS: "+fps
time = MilliSecs() - oldtime
count = count + 1
If time >= 1000
fps = count
count = 0
oldtime=MilliSecs()
EndIf
End Function
;---------------------------;
Function COL_CHANGE()
col_timer = col_timer + 1
If col_timer = 10
col_timer = 0
If col_change = 0
rf = rf - 1
If rf = 0
col_change = col_change + 1
EndIf
Else If col_change = 1
rf = rf + 1
gf = gf - 1
If gf = 0
col_change = col_change + 1
EndIf
Else If col_change = 2
bf = bf - 1
gf = gf + 1
If bf = 0
col_change = col_change + 1
EndIf
Else If col_change = 3
rf = rf - 1
gf = gf - 1
bf = bf + 1
If rf = 0
col_change = col_change + 1
EndIf
Else If col_change = 4
rf = rf + 1
bf = bf - 1
If bf = 0
col_change = col_change + 1
EndIf
Else If col_change = 5
bf = bf + 1
gf = gf + 1
If bf = 5
col_change =  0
EndIf
EndIf
EndIf
End Function
Title: Re: Some particle FX
Post by: Ghost^BHT on January 01, 2007
Nice.  :clap: But to be honest I liked the the other effect better. It looked like tentacles
Title: Re: Some particle FX
Post by: Paul on January 02, 2007
I really like the second one better  :)
Title: Re: Some particle FX
Post by: taj on January 02, 2007
Thanks for posting an exe mike_g ... it helps lamers like me who dont have basic set up.
I felt like I was falling into an endless glass of champagne watching that. Too much New Year.
It'll make a really good addition to an underwater scene.

Nicely optimised now too.

Title: Re: Some particle FX
Post by: mike_g on January 02, 2007
To be honest I'm not sure which I like best. I might one longer demo that does both. At the moment I am thinking about writing a function to draw empty squares with rounded corners. If I can get that done I could then put a couple of extra parameters in it and have the circles morph into squares and back. Anyway thanks for the feedback guys.