Simulation, Draw to a window and update window immediatly

Just starting out? Need help? Post your questions and find answers here.
HajoEhlers
New User
New User
Posts: 8
Joined: Fri Aug 13, 2010 5:49 pm
Location: Germany
Contact:

Simulation, Draw to a window and update window immediatly

Post by HajoEhlers »

Sorry can not post real code , My PB on my Linux system is not working.

Task:
I would like to plot to a window and would like to see each plot immediately.

Problem:
I am able to plot to a window BUT only the result is shown


Code logic example:

Code: Select all

...
OpenWindow
StartDrawing
for x = 1 to 100
	plot x-1 , x-1 , black
	plot x , x , white
        wait 1 ; wait 1 second for each plot
next x
StopDrawing
...
The windows will be created but the output will be shown AFTER all plots have been drawn thus i see a single dot at position 100,100 but i would like to see the dot moving from 1,1 to 100,100

So could somebody give me a very simple code example of how to update a window right away.

tia
Hajo
Enlightenment is a state of knowledge but even infinite knowledge does not lead to enlightenment.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Simulation, Draw to a window and update window immediatl

Post by Demivec »

Pseudo-code:

Code: Select all

OpenWindow
For x = 1 To 100
  StartDrawing
   plot x-1 , x-1 , black
   plot x , x , white
 StopDrawing      
 
 Repeat: Until WindowEvent() = 0 ;or #PB_Event_CloseWindow
 wait 1 ; wait 1 second for each plot
 
Next x
The result of all drawing within a single StartDrawing()/EndDrawing() is only committed to the output when the EndDrawing() is reached. The window is redrawn in the event loop. If you don't read the window events in-between the plots you will only seen the end result in a quick series (faster than can be seen) when you finally do retrieve all the events.

Actual code:

Code: Select all

OpenWindow (0, 0, 0, 101, 101, "Draw Test", #PB_Window_SystemMenu)
For x = 1 To 100
  StartDrawing(WindowOutput(0))
    Plot( x-1 , x-1 , #Black)
    Plot( x , x , #White)
  StopDrawing ()  
  
  Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      Break 2
    EndIf 
  Until event = 0
  Delay(1000) ; wait 1 second for each plot
  
Next

Repeat:event = WaitWindowEvent(10): Until event = #PB_Event_CloseWindow
And one more code sample just for fun demonstrating the use of a window timer instead of a For/Next loop:

Code: Select all

OpenWindow (0, 0, 0, 101, 101, "Draw Test with timer", #PB_Window_SystemMenu)

AddWindowTimer(0, 1, 10) ;1/100 second, so we don't fall asleep ;)

Repeat 
  
  Repeat
    event = WindowEvent()
    Select event
      Case #PB_Event_CloseWindow
        quit = #True
        event = 0
      Case #PB_Event_Timer
        If EventTimer() = 1
          StartDrawing(WindowOutput(0))
            Plot( x-1, x-1, c)
            Plot( x, x, RGB(255, 255, 255))
          StopDrawing()
          x + 1
          If x > 100
            x = 0
            c = RGB(Random(255), Random(255), Random(255))
          EndIf 
        EndIf 
    EndSelect
  Until event = 0

Until quit
Last edited by Demivec on Wed Aug 15, 2012 12:14 am, edited 1 time in total.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Simulation, Draw to a window and update window immediatl

Post by IdeasVacuum »

Code: Select all

Enumeration
#Win
EndEnumeration

Procedure Win()
;--------------

       If OpenWindow(#Win, 0, 0, 200, 200, "Test",#PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)

              SetWindowColor(#Win,RGB(255,255,255))
       EndIf

EndProcedure

Procedure WaitForUser()
;---------------------

     Repeat

           iEvent = WaitWindowEvent(1)

     Until iEvent = #PB_Event_CloseWindow

EndProcedure

;###Main Entry Point
Win()
Delay(1000)
             If StartDrawing(WindowOutput(#Win))

                    DrawingMode(#PB_2DDrawing_Default)

                    For x = 1 To 100

                             Plot(x,x,RGB(0,0,0))
                            Delay(100)
                             Plot(x,x,RGB(255,255,255))

                            While WindowEvent() : Wend
                    Next x

                    StopDrawing()
             EndIf

WaitForUser()

End
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
HajoEhlers
New User
New User
Posts: 8
Joined: Fri Aug 13, 2010 5:49 pm
Location: Germany
Contact:

Re: Simulation, Draw to a window and update window immediatl

Post by HajoEhlers »

My current code is like the following. I skipped the timer. The final code will be a multi particle simulation with a few hundred particles interacting with each other thus i see no need to slow down the simulation.

Thanks to both for your support. I was really lost with the PB GUI handling ( I am a PB newbe )

Code: Select all


OpenWindow (0, 0, 0, 101, 101, "Draw Test without timer", #PB_Window_SystemMenu)
x=0

; get white backgroud
StartDrawing(WindowOutput(0))
Box(0,0,101,101,RGB(255,255,255))
StopDrawing()

Repeat

  ; Event handling - End Program on CloseWindow.
  event = WindowEvent()
  Select event
    Case #PB_Event_CloseWindow
      quit = #True
  EndSelect
  
  x + 1
  
  StartDrawing(WindowOutput(0))
  Plot( x-1, x-1, RGB(255,255,255))
  Plot( x, x, RGB(0, 0,0))
  StopDrawing()
  
  Delay(10) ; So we can see the moving dot. Not required 
  
  If x > 99
    x = 0
  EndIf
  
Until quit
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 539
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Simulation, Draw to a window and update window immediatl

Post by BasicallyPure »

You can use SetWindowColor() to get your white background.

Code: Select all

OpenWindow (0, 0, 0, 101, 101, "Draw Test without timer", #PB_Window_SystemMenu)

SetWindowColor(0, RGB(255,255,255))

x = 0

Repeat
   
   x + 1
   
   StartDrawing(WindowOutput(0))
      Plot( x-1, x-1, RGB(255, 255, 255))
      If x > 99 : x = 0 : EndIf
      Plot( x, x, RGB(0, 0, 0))
   StopDrawing()
   
   ; So we can see the moving dot.
   ; also so we don't use 100% of CPU time
   Delay(20)
   
Until WindowEvent() = #PB_Event_CloseWindow
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 539
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Simulation, Draw to a window and update window immediatl

Post by BasicallyPure »

HajoEhlers wrote:The final code will be a multi particle simulation with a few hundred particles interacting with each other thus i see no need to slow down the simulation.
You might want to consider using a screen or windowedScreen for your simulation.
You can use SetFrameRate to control the speed.

Code: Select all

; 100ParticleAnimation.pb

EnableExplicit

#WindowColor   = $D5B92D ; window background color
#ScreenColor   = $000000 ; screen background color
#ParticleColor = $FFFFFF
#ParticleCount = 99 ; number of particles -1

Define Event, n
Define text.s = "100 particle animation with WindowedScreen"

If Not OpenWindow (0, 0, 0, 800, 600, text, #PB_Window_ScreenCentered) : End : EndIf
SetWindowColor(0, #WindowColor)
If Not InitSprite() : End : EndIf
If Not OpenWindowedScreen(WindowID(0),200,0,600,600,0,0,0) : End : EndIf

Define ButtonQuit    = ButtonGadget(#PB_Any,50,500,100,30,"Quit")
Define ButtonRestart = ButtonGadget(#PB_Any,50,460,100,30,"Restart")

Structure particleParameters
   x.f ; x location
   y.f ; y location
   xVel.f ; x velocity
   yVel.f ; y velocity
EndStructure

Dim Particle.particleParameters(#ParticleCount)

Macro RndFloat
   ; produce a random float number (0 < number < 1)
   ((Random(2147483645)+1) / 2147483647)
EndMacro

Procedure Restart(Array Particle.particleParameters(1))
   Protected n
   For n = 0 To #ParticleCount
      Particle(n)\x = 299
      Particle(n)\y = 299
      Particle(n)\xVel = ((RndFloat * 20)-10)/10.0
      Particle(n)\yVel = ((RndFloat * 20)-10)/10.0
   Next
EndProcedure

Restart(Particle())

SetFrameRate(30) ; controls animation speed

Repeat
   
   Repeat ; process all events until queue is empty
      Event = WindowEvent()
      Select Event
         Case #PB_Event_CloseWindow
            End
         Case #PB_Event_Gadget
            Select EventGadget()
               Case ButtonQuit
                  End
               Case ButtonRestart
                  Restart(Particle())
            EndSelect
      EndSelect
   Until Not Event
      
   ClearScreen(#ScreenColor) ; erase old
   
   StartDrawing(ScreenOutput())
      For n = 0 To #ParticleCount
         With Particle(n)
            Plot(\x, \y, #ParticleColor) ; draw new
            \x + \xVel
            \y + \yVel
            If \x > 598 Or \x < 1 : \xVel * -1 : EndIf
            If \y > 598 Or \y < 1 : \yVel * -1 : EndIf
         EndWith
      Next n
   StopDrawing()
      
   FlipBuffers()
   
ForEver
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
HajoEhlers
New User
New User
Posts: 8
Joined: Fri Aug 13, 2010 5:49 pm
Location: Germany
Contact:

Re: Simulation, Draw to a window and update window immediatl

Post by HajoEhlers »

BasicallyPure wrote: You might want to consider using a screen or windowedScreen for your simulation.
You can use SetFrameRate to control the speed.
One step after another ;-) . I see in your example the usage of 'with'. Less writing.

And as always : Thanks for helping.

Code: Select all

Structure sPartikel
  ; Position
  x.f
  y.f
  z.f
  
  ; Geschwindigkeit
  Vx.f
  Vy.f
  Vz.f
  
  ; Masse
  m.l
  
  ; Ladung
  q.f
  
EndStructure

Structure sWindow
  ;  Ursprung
  x0.i
  y0.i
  
  ; Groesse
  x1.i
  y1.i
  
EndStructure

Structure sTrail
  ; Trail position
  x.f
  y.f
EndStructure

; Definitions
#WINDOW_MAIN = 0
#FLAGS = #PB_Window_SystemMenu | #PB_Window_ScreenCentered

#White = $ffffff
#Black = $000000

Global t.f=0
Global dT.f = 0.01
Global maxT.l = 100000000

Global maxPartikel.l = 50
Global maxTrail.i =50

Window.sWindow
Window\x0 = 0
Window\y0 = 0
Window\x1 = 800
Window\y1 = 800

Dim Partikel.sPartikel(maxPartikel)
Dim PartikelTrail.sTrail(maxPartikel,maxTrail)

; Value assignments
For i = 0 To maxPartikel Step 1
  
  Partikel(i)\x = Random(Window\x1-2 )+1
  Partikel(i)\y = Random(Window\y1-2 )+1
  Partikel(i)\Vx = Random(200)-Random(200)
  Partikel(i)\Vy = Random(200)-Random(200)
  
  ; Debug Partikel(i)\x
  ; Debug Partikel(i)\y
  
Next i


; Main Programm Start

OpenWindow(#WINDOW_MAIN, Window\x0, Window\y0, Window\x1, Window\y1, "Charged Particle Simulation", #FLAGS)
SetWindowColor(#WINDOW_MAIN, #White)

Repeat ; Main loop until Main Windows will be closed.
  Delay(5)  
  
  ;  Partikel Trail 
  For i = 0 To maxPartikel 
    For j = maxTrail To 1 Step -1
      PartikelTrail(i,j)\x=PartikelTrail(i,j-1)\x
      PartikelTrail(i,j)\y=PartikelTrail(i,j-1)\y
    Next j
    PartikelTrail(i,0)\x=Partikel(i)\x
    PartikelTrail(i,0)\y=Partikel(i)\y
  Next i
  
  ; Draw Particle
  StartDrawing(WindowOutput(#WINDOW_MAIN))
  For i = 0 To maxPartikel   
    Plot(PartikelTrail(i,maxTrail)\x, PartikelTrail(i,maxTrail)\y,#White)   ;   
    Plot(Partikel(i)\x, Partikel(i)\y,#Black)                 ;
  Next i ; 
  StopDrawing() 
  
  ; Calculate new position
  For i = 0 To maxPartikel
    
    Partikel(i)\x = Partikel(i)\x +  Partikel(i)\Vx * dT
    Partikel(i)\y = Partikel(i)\y +  Partikel(i)\Vy * dT
    Partikel(i)\z = Partikel(i)\z +  Partikel(i)\Vz * dT
    
    ; Rounding is required since we might try to plot at the border which is not allowed.
    If  Round(Partikel(i)\x,#PB_Round_Nearest) >= Window\x1  
      Partikel(i)\x = Window\x1-1  ; 
      Partikel(i)\Vx = Abs ( Partikel(i)\Vx ) *-1
    ElseIf Round(Partikel(i)\x,#PB_Round_Nearest)=< Window\x0  
      Partikel(i)\x = Window\x0+1  
      Partikel(i)\Vx = Abs ( Partikel(i)\Vx ) 
    EndIf
    
    If  Round(Partikel(i)\y , #PB_Round_Nearest)>= Window\y1  
      Partikel(i)\y = Window\y1-1  
      Partikel(i)\Vy = Abs ( Partikel(i)\Vy ) *-1
    ElseIf Round(Partikel(i)\y ,#PB_Round_Nearest) =< Window\y0  
      Partikel(i)\y = Window\y0+1  
      Partikel(i)\Vy = Abs ( Partikel(i)\Vy ) 
    EndIf
    
    
  Next i
  
  t.f = t + dT
  
Until WindowEvent() = #PB_Event_CloseWindow

Enlightenment is a state of knowledge but even infinite knowledge does not lead to enlightenment.
Post Reply