2D water fluid

Share your advanced PureBasic knowledge/code with the community.
threedslider
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Feb 12, 2022 7:15 pm

2D water fluid

Post by threedslider »

Another interesting for my code with the help of AI :) :shock: :mrgreen:

Code: Select all

EnableExplicit

#Width  = 800
#Height = 400

; --- PHYSICS PARAMETERS ---
#Segments = 200                  ; number of water points
#Stiffness = 0.025               ; main spring stiffness
#Spread = 0.25                   ; lateral propagation
#Damping = 0.025                 ; wave damping
#RestHeight = #Height / 2        ; water rest height

Dim Height.f(#Segments)          ; current height
Dim Velocity.f(#Segments)        ; vertical speed
Dim LeftDelta.f(#Segments)
Dim RightDelta.f(#Segments)

Define i, x, mx.f, my.f
Define dx.f, dy.f
Define event

; Function to draw the circle cursor
Procedure DrawCircleCursor()
  Shared mx.f 
  Shared my.f
  Protected r = 8  ; cursor radius
  
  mx = MouseX()
  my = MouseY()

  ; Draw a transparent light-blue circle
  ;Circle(mx, my, r, RGBA(0, 180, 255, 180))
  
  ; White border for visibility
  Circle(mx, my, r, RGBA(255, 255, 255, 200))
EndProcedure


InitSprite()
InitMouse()
InitKeyboard()

If OpenWindow(0, 0, 0, #Width, #Height, "2D Water Fluid", #PB_Window_ScreenCentered)
  If OpenWindowedScreen(WindowID(0), 0, 0, #Width, #Height)
    
    ; Initialization
    For i = 0 To #Segments
      Height(i) = #RestHeight
    Next

    ; --- Main loop ---
    Repeat
      
      event = WindowEvent()

      ; --- CLICK INTERACTION ---
      If ExamineMouse()
        If MouseButton(#PB_MouseButton_Left)
          
          Define idx = mx * #Segments / #Width
          If idx >= 0 And idx <= #Segments
            Velocity(idx) - 12      ; vertical splash impact
          EndIf
        EndIf
      EndIf

      ; --- PHYSICS : MAIN SPRING ---
      For i = 0 To #Segments
        dy = #RestHeight - Height(i)
        Velocity(i) + dy * #Stiffness
        Velocity(i) * (1 - #Damping)
        Height(i) + Velocity(i)
      Next

      ; --- PHYSICS : LATERAL PROPAGATION ---
      For i = 0 To #Segments - 1
        LeftDelta(i)  = #Spread * (Height(i) - Height(i+1))
        Velocity(i+1) + LeftDelta(i)

        RightDelta(i) = #Spread * (Height(i+1) - Height(i))
        Velocity(i)   + RightDelta(i)
      Next

      ; --- DRAWING ---
      StartDrawing(ScreenOutput())
      Box(0, 0, #Width, #Height, RGB(0, 0, 50)) ; dark blue background

      ; Water color
      Define blue = RGB(0, 140, 255)

      ; Convert segments → screen
      For i = 0 To #Segments-2
        x  = i * #Width / #Segments
        dx = (i+1) * #Width / #Segments
        
        LineXY(x, Height(i), dx, Height(i+1), blue)
        
        ; Fill under the water surface
        LineXY(x, Height(i), x, #Height, RGB(0, 60, 120))
        LineXY(dx, Height(i+1), dx, #Height, RGB(0, 60, 120))
      Next
      
      ; --- Custom circle cursor ---
      DrawCircleCursor()

      StopDrawing()
      FlipBuffers()
      
      ExamineKeyboard()
      
      
    Until event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
     
  EndIf
EndIf
The cursor is too way slow, i have put the float but i can make more fast, not precise though....
threedslider
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Feb 12, 2022 7:15 pm

Re: 2D water fluid

Post by threedslider »

Click to left to change for water on line
threedslider
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Feb 12, 2022 7:15 pm

Re: 2D water fluid

Post by threedslider »

change to that :

Code: Select all

  mx = MouseX()*5.0
  my = MouseY()*5.0
Maybe it is more near to realtime
miso
Enthusiast
Enthusiast
Posts: 578
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: 2D water fluid

Post by miso »

Thanks for sharing, it's cool.

One important thing though: please process all the events at the beginning of the loop when using screens. (it will be instantly realtime, the pending events causes the delay for the mouse.)

Code: Select all

Repeat :Until Not WindowEvent()
ricardo_sdl
Enthusiast
Enthusiast
Posts: 145
Joined: Sat Sep 21, 2019 4:24 pm

Re: 2D water fluid

Post by ricardo_sdl »

miso wrote: Wed Dec 03, 2025 7:47 pm Thanks for sharing, it's cool.

One important thing though: please process all the events at the beginning of the loop when using screens. (it will be instantly realtime, the pending events causes the delay for the mouse.)

Code: Select all

Repeat :Until Not WindowEvent()
Thanks for the tip miso! I changed threedslider code to see what you are talking about:

Code: Select all

EnableExplicit

#Width  = 800
#Height = 400

; --- PHYSICS PARAMETERS ---
#Segments = 200                  ; number of water points
#Stiffness = 0.025               ; main spring stiffness
#Spread = 0.25                   ; lateral propagation
#Damping = 0.025                 ; wave damping
#RestHeight = #Height / 2        ; water rest height

Dim Height.f(#Segments)          ; current height
Dim Velocity.f(#Segments)        ; vertical speed
Dim LeftDelta.f(#Segments)
Dim RightDelta.f(#Segments)

Define i, x, mx.f, my.f
Define dx.f, dy.f
Define event
Define Exit = #False

; Function to draw the circle cursor
Procedure DrawCircleCursor()
  Shared mx.f 
  Shared my.f
  Protected r = 8  ; cursor radius
  
  mx = MouseX()
  my = MouseY()
  
  ; Draw a transparent light-blue circle
  ;Circle(mx, my, r, RGBA(0, 180, 255, 180))
  
  ; White border for visibility
  Circle(mx, my, r, RGBA(255, 255, 255, 200))
EndProcedure


InitSprite()
InitMouse()
InitKeyboard()

If OpenWindow(0, 0, 0, #Width, #Height, "2D Water Fluid", #PB_Window_ScreenCentered)
  If OpenWindowedScreen(WindowID(0), 0, 0, #Width, #Height)
    
    ; Initialization
    For i = 0 To #Segments
      Height(i) = #RestHeight
    Next
    
    ; --- Main loop ---
    Repeat
      
      ;process all events here before the logic loop
      While #True
        event = WindowEvent()
        If event = 0
          Break
        EndIf
        
        If event = #PB_Event_CloseWindow
          Exit = #True
          Break
        EndIf
        
        
      Wend
      
      
      
      
      ; --- CLICK INTERACTION ---
      If ExamineMouse()
        If MouseButton(#PB_MouseButton_Left)
          
          Define idx = mx * #Segments / #Width
          If idx >= 0 And idx <= #Segments
            Velocity(idx) - 12      ; vertical splash impact
          EndIf
        EndIf
      EndIf
      
      ; --- PHYSICS : MAIN SPRING ---
      For i = 0 To #Segments
        dy = #RestHeight - Height(i)
        Velocity(i) + dy * #Stiffness
        Velocity(i) * (1 - #Damping)
        Height(i) + Velocity(i)
      Next
      
      ; --- PHYSICS : LATERAL PROPAGATION ---
      For i = 0 To #Segments - 1
        LeftDelta(i)  = #Spread * (Height(i) - Height(i+1))
        Velocity(i+1) + LeftDelta(i)
        
        RightDelta(i) = #Spread * (Height(i+1) - Height(i))
        Velocity(i)   + RightDelta(i)
      Next
      
      ; --- DRAWING ---
      StartDrawing(ScreenOutput())
      Box(0, 0, #Width, #Height, RGB(0, 0, 50)) ; dark blue background
      
      ; Water color
      Define blue = RGB(0, 140, 255)
      
      ; Convert segments → screen
      For i = 0 To #Segments-2
        x  = i * #Width / #Segments
        dx = (i+1) * #Width / #Segments
        
        LineXY(x, Height(i), dx, Height(i+1), blue)
        
        ; Fill under the water surface
        LineXY(x, Height(i), x, #Height, RGB(0, 60, 120))
        LineXY(dx, Height(i+1), dx, #Height, RGB(0, 60, 120))
      Next
      
      ; --- Custom circle cursor ---
      DrawCircleCursor()
      
      StopDrawing()
      FlipBuffers()
      
      ExamineKeyboard()
      
      
    Until Exit = #True Or KeyboardPushed(#PB_Key_Escape)
    
  EndIf
EndIf

And the mouse handling works now! Now it willbe easier to implement mouse input on games and interactive applications!
You can check my games at:
https://ricardo-sdl.itch.io/
PeDe
Enthusiast
Enthusiast
Posts: 331
Joined: Sun Nov 26, 2017 3:13 pm

Re: 2D water fluid

Post by PeDe »

PB v6.30b4 64-bit, Raspberry Pi OS (Trixie, Wayland)

I only see a black window here. The program only works if I use ‘ClearScreen(#Black)’ before ‘StartDrawing(ScreenOutput())’.

Peter
miso
Enthusiast
Enthusiast
Posts: 578
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: 2D water fluid

Post by miso »

PeDe wrote: Thu Dec 04, 2025 6:18 pm PB v6.30b4 64-bit, Raspberry Pi OS (Trixie, Wayland)

I only see a black window here. The program only works if I use ‘ClearScreen(#Black)’ before ‘StartDrawing(ScreenOutput())’.

Peter
Thanks, this is a valuable information.
ebs
Enthusiast
Enthusiast
Posts: 564
Joined: Fri Apr 25, 2003 11:08 pm

Re: 2D water fluid

Post by ebs »

@threeslider,

This is very cool - thanks for posting it!

I made some changes to simplify calculations in the drawing loop and eliminate the need for the
LeftDelta.f() and RightDelta.f() arrays.

Everything seems to work as expected, but let me know if there are any mistakes.

Code: Select all

EnableExplicit

#Width  = 800
#Height = 400

; --- PHYSICS PARAMETERS ---
#Segments = 200                  ; number of water points
#Stiffness = 0.025               ; main spring stiffness
#Spread = 0.25                   ; lateral propagation
#Damping = 0.025                 ; wave damping
#RestHeight = #Height / 2        ; water rest height


Dim Height.f(#Segments)          ; current height
Dim Velocity.f(#Segments)        ; vertical speed
;;Dim LeftDelta.f(#Segments)
;;Dim RightDelta.f(#Segments)

Define i, x, mx.f, my.f
Define dx.f, dy.f
Define Event
Define Exit = #False

; Water color
Define Blue = RGB(0, 140, 255)

; Function to draw the circle cursor
Procedure DrawCircleCursor()
  Shared mx.f 
  Shared my.f
  Protected r = 8  ; cursor radius
  
  mx = MouseX()
  my = MouseY()
  
  ; Draw a transparent light-blue circle
  ;Circle(mx, my, r, RGBA(0, 180, 255, 180))
  
  ; White border for visibility
  Circle(mx, my, r, RGBA(255, 255, 255, 200))
EndProcedure


InitSprite()
InitMouse()
InitKeyboard()

If OpenWindow(0, 0, 0, #Width, #Height, "2D Water Fluid", #PB_Window_ScreenCentered)
  If OpenWindowedScreen(WindowID(0), 0, 0, #Width, #Height)
    
    ; Initialization
    For i = 0 To #Segments
      Height(i) = #RestHeight
    Next
    
    ; --- Main loop ---
    Repeat
      
      ;process all events here before the logic loop
      While #True
        Event = WindowEvent()
        If Event = 0
          Break
        EndIf
        
        If Event = #PB_Event_CloseWindow
          Exit = #True
          Break
        EndIf
        
        
      Wend
      
      
      
      
      ; --- CLICK INTERACTION ---
      If ExamineMouse()
        If MouseButton(#PB_MouseButton_Left)
          
          Define Idx = mx * #Segments / #Width
          If Idx >= 0 And Idx <= #Segments
            Velocity(Idx) - 12      ; vertical splash impact
          EndIf
        EndIf
      EndIf
      
      ; --- PHYSICS : MAIN SPRING ---
      For i = 0 To #Segments
        Velocity(i) + (#RestHeight - Height(i)) * #Stiffness
        ;; dy = #RestHeight - Height(i)
        ;; Velocity(i) + dy * #Stiffness
        Velocity(i) * (1 - #Damping)
        Height(i) + Velocity(i)
      Next
      
      ; --- PHYSICS : LATERAL PROPAGATION ---
      For i = 0 To #Segments - 1
        Velocity(i+1) + #Spread * (Height(i) - Height(i+1))
        ;; LeftDelta(i)  = #Spread * (Height(i) - Height(i+1))
        ;; Velocity(i+1) + LeftDelta(i)
        
        Velocity(i) + #Spread * (Height(i+1) - Height(i))
        ;; RightDelta(i) = #Spread * (Height(i+1) - Height(i))
        ;; Velocity(i)   + RightDelta(i)
      Next
      
      ; --- DRAWING ---
      StartDrawing(ScreenOutput())
        Box(0, 0, #Width, #Height, RGB(0, 0, 50)) ; dark blue background
        
        ;; ; Water color
        ;; Define Blue = RGB(0, 140, 255)
        
        FrontColor(RGB(0, 60, 120))
        
        ; Convert segments ? screen
        For i = 0 To #Segments-2
          x  = i * #Width / #Segments
          dx = (i+1) * #Width / #Segments
          
          LineXY(x, Height(i), dx, Height(i+1), Blue)
          ; Fill under the water surface
          LineXY(x, Height(i), x, #Height)
          LineXY(dx, Height(i+1), dx, #Height)
          ;; LineXY(x, Height(i), x, #Height, RGB(0, 60, 120))
          ;; LineXY(dx, Height(i+1), dx, #Height, RGB(0, 60, 120))
        Next
        
        ; --- Custom circle cursor ---
        DrawCircleCursor()
        
      StopDrawing()
      FlipBuffers()
      
      ExamineKeyboard()
      
      
    Until Exit = #True Or KeyboardPushed(#PB_Key_Escape)
    
  EndIf
EndIf
threedslider
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Feb 12, 2022 7:15 pm

Re: 2D water fluid

Post by threedslider »

Thanks to all and your contribution, nice work ! :shock: :mrgreen:
Post Reply