Dark Bit Factory & Gravity
PROGRAMMING => Other languages => Blitz => Topic started 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.
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
-
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
-
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)
-
Thanks for the exe :) And that is bloody good. I like the explosions :)
-
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.
-
Nice stuff but i get a MAV a few moments after clicking the mouse :( possibly something being drawn offscreen?
-
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
-
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:
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):
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: edit: I think you need to check y1 and y2 more carefully in the 2nd loop.
Will do. /EDIT
-
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
-
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.
-
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
-
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
-
It's next year now. Where is it!? :p :D :D
Jim
-
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:
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
-
Nice. :clap: But to be honest I liked the the other effect better. It looked like tentacles
-
I really like the second one better :)
-
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.
-
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.