Page 1 of 2

Snow - Simple but fine (New extended code :-) Jan.09.14

Posted: Thu Dec 12, 2013 10:54 pm
by walbus
---------For the extended Code looking the latest posting´s below !!!!------------

Code: Select all

; Snow - by Werner Albus - www.nachtoptik.de

Procedure timer_events()
  Global time_event=EventTimer()
EndProcedure

ExamineDesktops()
OpenWindow(0,DesktopWidth(0)/2-100,DesktopHeight(0)/2-300,600,400,"Simple Snow")

If InitSprite() = 0 Or InitKeyboard() = 0 Or OpenWindowedScreen(WindowID(0),0,0,600,400,0,0,0,#PB_Screen_WaitSynchronization) = 0
  MessageRequester("Error", "Can not init Spritesystem",0)
  End
EndIf

AddWindowTimer(0,1,90)
BindEvent(#PB_Event_Timer, @timer_events())

CreateImage (0,600,400) ; Create Background
StartDrawing(ImageOutput (0))
DrawingMode ( #PB_2DDrawing_Gradient )
BackColor (0)
FrontColor ($FF901E)
LinearGradient (0,-300,0,1500)
Box (0,0,600,400)
StopDrawing()

Dim snow_x(1400) : Dim snow_y(1400); Create Snow Field

Dim settle(600)      ;  Addon - settle a little Snow
Dim settle_hat(200)  ; Addon - settle a little Snow on the Hat

For i=1 To 1400
  snow_x(i)=Random(598)+1 ; X Range -2
  snow_y(i)=-Random(1400)
Next i

Repeat
  
  If time_event=1
    FlipBuffers ()
    time_event=0
    StartDrawing(ScreenOutput())
    DrawImage(ImageID(0),0,0)
    
    Circle(450,325,15,$EFEFEF) ; Addon - Simple Snowman :-)
    Circle(450,350,20,$EFEFEF) : Circle(450,328,6,0)
    Circle(450,325,7, $EFEFEF) : Circle(450,325,2,$0045FF)
    Circle(450,385,30,$EFEFEF) : Circle(450,345,1,0)
    Circle(443,320,1, 0)       : Circle(457,320,1,0)
    Circle(450,350,1, 0)       : Circle(450,355,1,0)
    Circle(450,370,1, 0)       : Circle(450,375,1,0) ; ----

    For ix=1 To 1400  ; Let it snow
      go=snow_y(ix)+snow_add_y
      If go>0 And go<400
        If Not Random(2)
          Plot(snow_x(ix)+Random(1)-1,snow_y(ix)+snow_add_y)
        Else
          Circle(snow_x(ix)+Random(1)-1,snow_y(ix)+snow_add_y,Random(1))
        EndIf
      EndIf
    Next ix
    
    snow_add_y+1
    If snow_add_y>1400
      snow_add_y=400
    EndIf
    
    For ii=1 To 599 ; Addon - settle a little Snow ---
      If Point(ii,398)=$FFFFFF
        settle(ii)=1
      EndIf
      If settle(ii)
        Circle(ii,399,1)
      EndIf
    Next ii
    settle(Random(600))=0
    settle(Random(600))=0
    settle(Random(600))=0 ;----------------------------
    
    For ii=1 To 26 ; Addon - settle a little Snow on the Hat --
      If Point(ii+436,300)=$FFFFFF
        settle_hat(ii)=1
      EndIf
      If settle_hat(ii)
        Circle(ii+436,301,1)
      EndIf
    Next ii
    settle_hat(Random(200))=0 ;---------------------------------
    
    Box(437,302,26,15,$828282) ;-- Addon Snowman´s Hat --
    
    StopDrawing()
  EndIf
  
  Repeat 
    event=WindowEvent()
    Select event
      Case #PB_Event_CloseWindow
        quit=1
    EndSelect
  Until event=0
  
Until quit

Re: A Simple but fine Snow Simulation :-)

Posted: Fri Dec 13, 2013 12:26 am
by IdeasVacuum
nice - but it doesn't settle on the ground and where is the snowman? :D

Re: A Simple but fine Snow Simulation :-)

Posted: Fri Dec 13, 2013 7:59 am
by walbus
Yep, settle snow, you can simple add.
With the Snowman, unfortunately, we have here to time Fog and it is to warm !
regards from Germany - Werner

Re: Simple but fine Snow Simulation :-)

Posted: Fri Dec 13, 2013 3:47 pm
by Demivec
I tried the code but got no snow until I changed line 22:

Code: Select all

;replace
If ElapsedMilliseconds()>timer_0+90

;with
If ElapsedMilliseconds()>timer_0+90 Or timer_0 - ElapsedMilliseconds() > 100
In the original code if the computer has been on long enough for ElapsedMilliseconds() to return a negative number it may be 21 or more days before you see snow. :)


The snow is nice but I agree it needs something more. Maybe something will come along . . .

Re: Simple but fine Snow Simulation :-)

Posted: Fri Dec 13, 2013 9:01 pm
by walbus
Yep, this is correct, after code test i have forgotten to set a timer ,now it´s OK; THANKS.

Re: Simple but fine Snow Simulation :-)

Posted: Fri Dec 13, 2013 11:56 pm
by luis
@walbus

I like the twinkle effect obtained in a so simple way, consider it stolen. :)

@demivec

Right ! It's that time of year again ! Going to find my hat.

Re: Simple but fine Snow Simulation :-)

Posted: Sat Dec 14, 2013 12:33 am
by netmaestro
Ha, you're right! Now where is that thing, time to dust it off..

Re: Simple but fine Snow Simulation :-)

Posted: Sat Dec 14, 2013 3:15 am
by flaith
Nice effect :)
But when I move my mouse on the screen, it freezes the animation.

Re: Simple but fine Snow Simulation :-)

Posted: Sat Dec 14, 2013 9:28 am
by walbus
I am very glad that you like it
It´s colder to day.
To evening, or Sunday morning, (i must working today & Christmas party (Beer :-)
I make a Snowman and a little more :-)

@ flaith (a mouse issue ??? hmm)

best regards Werner

Re: Simple but fine Snow Simulation :-)

Posted: Sat Dec 14, 2013 10:25 am
by Fred
walbus wrote:@ flaith (a mouse issue ??? hmm)
No, it's not a mouse issue. You need to process all the events at every loop (WaitWindowEvent() only process the last one, you need to have another loop until WindowEvent() returns 0.

Re: Simple but fine Snow Simulation :-)

Posted: Sat Dec 14, 2013 12:13 pm
by walbus
Many thanks Fred !
The code is changed now

More new Things added :-)

Re: Snow - Simple but fine

Posted: Thu Jan 02, 2014 7:38 pm
by em_uk
Hi, very nice - however, your loop WaitEvent loop consumes a lot of CPU resources :

if you take this :

Code: Select all

ExamineDesktops()
OpenWindow(0,DesktopWidth(0)/2-100,DesktopHeight(0)/2-300,600,400,"Simple Snow")

If InitSprite() = 0 Or InitKeyboard() = 0 Or OpenWindowedScreen(WindowID(0),0,0,600,400,0,0,0,#PB_Screen_WaitSynchronization) = 0
  MessageRequester("Error", "Can not init Spritesystem",0)
  End
EndIf

Repeat

  Repeat 
    event=WindowEvent()
    Select event
      Case #PB_Event_CloseWindow
        quit=1
    EndSelect
  Until event=0
  
Until quit
And check taskmanager, on my system with 4 cores, it immeditaly takes up 25% seeming doing nothing. I have added a delay(1) in to the final loop which reduces the CPU consumption by almost all of it.

Code: Select all

; Snow - by Werner Albus - www.nachtoptik.de

Procedure timer_events()
  Global time_event=EventTimer()
EndProcedure

ExamineDesktops()
OpenWindow(0,DesktopWidth(0)/2-100,DesktopHeight(0)/2-300,600,400,"Simple Snow")

If InitSprite() = 0 Or InitKeyboard() = 0 Or OpenWindowedScreen(WindowID(0),0,0,600,400,0,0,0,#PB_Screen_WaitSynchronization) = 0
  MessageRequester("Error", "Can not init Spritesystem",0)
  End
EndIf

AddWindowTimer(0,1,20)
BindEvent(#PB_Event_Timer, @timer_events())

CreateImage (0,600,400) ; Create Background
StartDrawing(ImageOutput (0))
DrawingMode ( #PB_2DDrawing_Gradient )
BackColor (0)
FrontColor ($FF901E)
LinearGradient (0,-300,0,1500)
Box (0,0,600,400)
StopDrawing()

Dim snow_x(1400) : Dim snow_y(1400); Create Snow Field

Dim settle(600)      ;  Addon - settle a little Snow
Dim settle_hat(200)  ; Addon - settle a little Snow on the Hat

For i=1 To 1400
  snow_x(i)=Random(598)+1 ; X Range -2
  snow_y(i)=-Random(1400)
Next i

Repeat
  
  If time_event=1
    FlipBuffers ()
    time_event=0
    StartDrawing(ScreenOutput())
   DrawImage(ImageID(0),0,0)
    
    Circle(450,325,15,$EFEFEF) ; Addon - Simple Snowman :-)
    Circle(450,350,20,$EFEFEF) : Circle(450,328,6,0)
    Circle(450,325,7, $EFEFEF) : Circle(450,325,2,$0045FF)
    Circle(450,385,30,$EFEFEF) : Circle(450,345,1,0)
    Circle(443,320,1, 0)       : Circle(457,320,1,0)
    Circle(450,350,1, 0)       : Circle(450,355,1,0)
    Circle(450,370,1, 0)       : Circle(450,375,1,0) ; ----

    For ix=1 To 1400  ; Let it snow
      go=snow_y(ix)+snow_add_y
      If go>0 And go<400
        If Not Random(2)
          Plot(snow_x(ix)+Random(1)-1,snow_y(ix)+snow_add_y)
        Else
          Circle(snow_x(ix)+Random(1)-1,snow_y(ix)+snow_add_y,Random(1))
        EndIf
      EndIf
    Next ix
    
    snow_add_y+1
    If snow_add_y>1400
      snow_add_y=400
    EndIf
    
    For ii=1 To 599 ; Addon - settle a little Snow ---
      If Point(ii,398)=$FFFFFF
        settle(ii)=1
      EndIf
      If settle(ii)
        Circle(ii,399,1)
      EndIf
    Next ii
    settle(Random(600))=0
    settle(Random(600))=0
    settle(Random(600))=0 ;----------------------------
    
    For ii=1 To 26 ; Addon - settle a little Snow on the Hat --
      If Point(ii+436,300)=$FFFFFF
        settle_hat(ii)=1
      EndIf
      If settle_hat(ii)
        Circle(ii+436,301,1)
      EndIf
    Next ii
    settle_hat(Random(200))=0 ;---------------------------------
    
    Box(437,302,26,15,$828282) ;-- Addon Snowman´s Hat --
    
    StopDrawing()
  EndIf
  
  Repeat 
    event=WindowEvent()
    Select event
      Case #PB_Event_CloseWindow
        quit=1
    EndSelect
    Delay(1)   ; Don't know if this is the best practice but it works! :)
  Until event=0
  
Until quit

Re: Snow - Simple but fine

Posted: Thu Jan 02, 2014 7:52 pm
by ts-soft
Better:

Code: Select all

  Repeat
    event=WaitWindowEvent(1)
    Select event
      Case #PB_Event_CloseWindow
        quit=1
    EndSelect
    ;Delay(1)   ; Don't know if this is the best practice but it works! :)
  Until event=0

Re: Snow - Simple but fine

Posted: Thu Jan 02, 2014 8:44 pm
by WilliamL
This is fun! The blinking snow is nice and the accumulation is great.

Yes, I see the cpu usage too. In fact, I find that Delay(10) works the best for me as far a cpu usage and temperature control (laptop begins to heat up). It looks the same to me...

Re: Snow - Simple but fine

Posted: Thu Jan 02, 2014 9:06 pm
by netmaestro
Best not to use a delay at all if you're already using a timer anyway. This has cpu load less than 1% and usually 0:

Code: Select all

; Snow - by Werner Albus - www.nachtoptik.de

Global Dim snow_x(1400) 
Global Dim snow_y(1400); Create Snow Field

Global Dim settle(600)      ;  Addon - settle a little Snow
Global Dim settle_hat(200)  ; Addon - settle a little Snow on the Hat

Procedure timer_events()
  Static snow_add_y
  FlipBuffers ()
  StartDrawing(ScreenOutput())
    DrawImage(ImageID(0),0,0)
    
    For ix=1 To 1400  ; Let it snow
      go=snow_y(ix)+snow_add_y
      If go>0 And go<400
        If Not Random(2)
          Plot(snow_x(ix)+Random(1)-1,snow_y(ix)+snow_add_y)
        Else
          Circle(snow_x(ix)+Random(1)-1,snow_y(ix)+snow_add_y,Random(1))
        EndIf
      EndIf
    Next ix
    
    snow_add_y+1
    If snow_add_y>1400
      snow_add_y=400
    EndIf
    
    For ii=1 To 599 ; Addon - settle a little Snow ---
      If Point(ii,398)=$FFFFFF
        settle(ii)=1
      EndIf
      If settle(ii)
        Circle(ii,399,1)
      EndIf
    Next ii
    settle(Random(600))=0
    settle(Random(600))=0
    settle(Random(600))=0 ;----------------------------
    
    For ii=1 To 26 ; Addon - settle a little Snow on the Hat --
      If Point(ii+436,300)=$FFFFFF
        settle_hat(ii)=1
      EndIf
      If settle_hat(ii)
        Circle(ii+436,301,1)
      EndIf
    Next ii
    settle_hat(Random(200))=0 ;---------------------------------

  StopDrawing()
  
EndProcedure

ExamineDesktops()
OpenWindow(0,DesktopWidth(0)/2-100,DesktopHeight(0)/2-300,600,400,"Simple Snow")

If InitSprite() = 0 Or InitKeyboard() = 0 Or OpenWindowedScreen(WindowID(0),0,0,600,400,0,0,0,#PB_Screen_WaitSynchronization) = 0
  MessageRequester("Error", "Can not init Spritesystem",0)
  End
EndIf

AddWindowTimer(0,1,90)
BindEvent(#PB_Event_Timer, @timer_events())

CreateImage (0,600,400) ; Create Background
StartDrawing(ImageOutput (0))
  DrawingMode ( #PB_2DDrawing_Gradient )
  BackColor (0)
  FrontColor ($FF901E)
  LinearGradient (0,-300,0,1500)
  Box (0,0,600,400)
  DrawingMode(#PB_2DDrawing_Default)
  Circle(450,325,15,$EFEFEF) ; Addon - Simple Snowman :-)
  Circle(450,350,20,$EFEFEF) : Circle(450,328,6,0)
  Circle(450,325,7, $EFEFEF) : Circle(450,325,2,$0045FF)
  Circle(450,385,30,$EFEFEF) : Circle(450,345,1,0)
  Circle(443,320,1, 0)       : Circle(457,320,1,0)
  Circle(450,350,1, 0)       : Circle(450,355,1,0)
  Circle(450,370,1, 0)       : Circle(450,375,1,0) ; ----
  Box(437,302,26,15,$828282) ;-- Addon Snowman´s Hat --
StopDrawing()

For i=1 To 1400
  snow_x(i)=Random(598)+1 ; X Range -2
  snow_y(i)=-Random(1400)
Next i

Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow