l'effet est obtenu graphiquement en appliquant un filtre de niveau :
Code : Tout sélectionner
; ------------------------------------------------------------------------------------------
; MetaBalls 2D par G-Rom
; ------------------------------------------------------------------------------------------
Structure Pixel
Pixel.l
EndStructure
; ------------------------------------------------------------------------------------------
;
; ------------------------------------------------------------------------------------------
Structure sVector2
X.f
Y.f
EndStructure
; ------------------------------------------------------------------------------------------
;
; ------------------------------------------------------------------------------------------
Structure sParticle
mPosition.sVector2
mOldPosition.sVector2
mOrigin.sVector2
mAngle.f
mVitesse.f
mPhysic_Timer.f
EndStructure
Global NewList particle.sParticle()
; ------------------------------------------------------------------------------------------
;
; ------------------------------------------------------------------------------------------
#SURFACE_RENDERING_WIDTH = 640
#SURFACE_RENDERING_HEIGHT = 480
#GRAVITY = 9.8
#FRAME_RATE_RENDERING = 120
; ------------------------------------------------------------------------------------------
; initialisation
; ------------------------------------------------------------------------------------------
InitSprite() : InitKeyboard() : InitSprite3D()
If ExamineDesktops()
Global sWidth = DesktopWidth(0)
Global sHeight = DesktopHeight(0)
Global window = OpenWindow(#PB_Any,0,0,sWidth,sHeight,"MetaBalls2D par G-Rom")
; OpenWindowedScreen(WindowID(window),0,0,sWidth,sHeight,1,0,0,#PB_Screen_SmartSynchronization)
OpenScreen(sWidth,sHeight,DesktopDepth(0),"MetaBalls2D par G-Rom",#PB_Screen_SmartSynchronization)
Else
MessageRequester("Error","Error when examine desktop resolution")
End
EndIf
; ------------------------------------------------------------------------------------------
; Create target sprite
; ------------------------------------------------------------------------------------------
Global rtt_sprite = CreateSprite(#PB_Any,#SURFACE_RENDERING_WIDTH,#SURFACE_RENDERING_HEIGHT,#PB_Sprite_Texture)
If rtt_sprite = 0
MessageRequester("Error","Can't create sprite : "+Str(#SURFACE_RENDERING_WIDTH)+"x"+Str(#SURFACE_RENDERING_HEIGHT))
End
EndIf
Global rtt_sprite3d = CreateSprite3D(#PB_Any,rtt_sprite)
ZoomSprite3D(rtt_sprite3d,sWidth,sHeight)
; ------------------------------------------------------------------------------------------
; Create metaball image
; ------------------------------------------------------------------------------------------
Global metaball_image = CreateImage(#PB_Any,32,32,32)
StartDrawing(ImageOutput(metaball_image))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,32,32,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For r = 0 To 16
Circle(16,16,16-r,RGBA(255,255,255,8))
Next
StopDrawing()
; ------------------------------------------------------------------------------------------
;
; ------------------------------------------------------------------------------------------
SpriteID_tile = CreateSprite(#PB_Any,256,256)
StartDrawing(SpriteOutput(SpriteID_tile))
Box(0,0,256,256,$0A0A0A)
For y = 0 To 256 Step 64
For x = 0 To 256 Step 64
Box(x,y,32,32,$1A1A1A)
Box(x+32,y+32,32,32,$1A1A1A)
Next
Next
StopDrawing()
nbX = (sWidth / 256)+2
nbY = (sHeight / 256)+2
font = LoadFont(#PB_Any,"IMPACT",14,#PB_Font_HighQuality)
Declare updateParticle(image.i)
Declare createParticle(x.f,y.f,angle.f=90, randomAngle.f = 45,speed.f = 40)
; ------------------------------------------------------------------------------------------
; main loop
; ------------------------------------------------------------------------------------------
While 1
ExamineKeyboard()
If KeyboardPushed(#PB_Key_F1) And flag1 = 0
flag1 = 1
thresold+1
thresold%2
EndIf
If Not KeyboardPushed(#PB_Key_F1) And flag1 = 1
flag1 = 0
EndIf
If KeyboardPushed(#PB_Key_F2) And flag2 = 0
flag2 = 1
colorGradient+1
colorGradient%2
EndIf
If Not KeyboardPushed(#PB_Key_F2) And flag2 = 1
flag2 = 0
EndIf
If KeyboardPushed(#PB_Key_Escape)
Break
EndIf
; If WindowEvent() = #PB_Event_CloseWindow
; Break
; EndIf
If timer < ElapsedMilliseconds()
timer = ElapsedMilliseconds() + 50
emitterX.f = ((#SURFACE_RENDERING_WIDTH / 2) - 16) + (((#SURFACE_RENDERING_WIDTH / 2) - 16)/2) * Cos(ElapsedMilliseconds()/1000)
If ListSize(particle())<50
For i = 0 To 5
createParticle(emitterX,(#SURFACE_RENDERING_HEIGHT / 2) - 16,90,30,20)
Next
EndIf
EndIf
If (ElapsedMilliseconds() > CheckTime + 1000 / #FRAME_RATE_RENDERING)
CheckTime = ElapsedMilliseconds()
; ----------------------------------------------------------------------------------------
; Draw metaballs
; ----------------------------------------------------------------------------------------
StartDrawing(SpriteOutput(rtt_sprite))
DrawingMode(#PB_2DDrawing_Default)
Box(0,0,#SURFACE_RENDERING_WIDTH,#SURFACE_RENDERING_HEIGHT,RGBA(0,0,0,255))
updateParticle(metaball_image)
StopDrawing()
; ----------------------------------------------------------------------------------------
; apply thresold on all metaball for hard edge
; ----------------------------------------------------------------------------------------
StartDrawing(SpriteOutput(rtt_sprite))
DrawingMode(#PB_2DDrawing_Default)
Buffer = DrawingBuffer()
Pitch = DrawingBufferPitch()
PixelFormat = DrawingBufferPixelFormat()
If thresold = 0
For y = 0 To #SURFACE_RENDERING_HEIGHT-1
*Line.Pixel = Buffer+Pitch*y ; next line
For x = 0 To #SURFACE_RENDERING_WIDTH-1
color.i = *Line\Pixel
r = Red(color)
g = Green(color)
b = Blue(color)
gray = (r+g+b) / 3
If colorGradient = 0
If gray > 107
*Line\Pixel = RGBA(255,255,255,255)
ElseIf gray > 54 And gray < 108
*Line\Pixel = RGBA(180, 84, 4,255)
ElseIf gray > 50 And gray < 55
*Line\Pixel = RGBA(255, 64, 64,255)
Else
*Line\Pixel = RGBA(0,0,0,0)
EndIf
Else
If gray > 50
*Line\Pixel = RGBA(255, 255, 255,255)
Else
*Line\Pixel = RGBA(0,0,0,0)
EndIf
EndIf
*Line + 4 ; next pixel
Next
Next
EndIf
StopDrawing()
ClearScreen(0)
offset + 1
offset%256
For y = 0 To nbY
For x = 0 To nbX
DisplaySprite(Spriteid_tile,(x*256)-offset,(y*256)-offset)
Next
Next
Start3D()
DisplaySprite3D(rtt_sprite3d,0,0,200)
Stop3D()
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(font))
DrawText(10,10,"METABALLS 2D BY G-ROM")
DrawText(10,30,"F1 FOR THRESOLD : "+Str(1-thresold))
DrawText(10,50,"F2 FOR COLOR GRADIENT : "+Str(1-colorGradient))
DrawText(10,70,"PARTICLES : "+Str(ListSize(particle())))
StopDrawing()
FlipBuffers()
Else
Delay(1)
EndIf
Wend
End
; ------------------------------------------------------------------------------------------
;
; ------------------------------------------------------------------------------------------
Procedure createParticle(x.f,y.f,angle.f=90, randomAngle.f = 45,speed.f = 40)
AddElement(particle())
With particle()
\mOrigin\X = x
\mOrigin\Y = y
\mAngle = angle - Random(randomAngle) + Random(randomAngle)
\mVitesse = speed+Random(speed)
EndWith
EndProcedure
; ------------------------------------------------------------------------------------------
;
; ------------------------------------------------------------------------------------------
Procedure updateParticle(image.i)
ForEach particle()
With particle()
\mPosition\X = \mOrigin\X + (\mVitesse*Cos((360-\mAngle)*#PI/180)*\mPhysic_Timer)
\mPosition\Y = \mOrigin\Y + (\mVitesse*Sin((360-\mAngle)*#PI/180)*\mPhysic_Timer)+(0.5*#GRAVITY*(\mPhysic_Timer*\mPhysic_Timer))
\mPhysic_Timer + 0.1
DrawAlphaImage(ImageID(image),\mPosition\X,\mPosition\Y)
If \mPosition\X < -64 Or \mPosition\X>#SURFACE_RENDERING_WIDTH Or \mPosition\Y > #SURFACE_RENDERING_HEIGHT
DeleteElement(particle(),1)
EndIf
EndWith
Next
EndProcedure