Author Topic: Screensaver: Super Simple Snowfall (with accumulation)  (Read 4322 times)

0 Members and 1 Guest are viewing this topic.

Offline Dustinian

  • Newbie
  • Posts: 2
    • View Profile
Screensaver: Super Simple Snowfall (with accumulation)
« on: December 20, 2021, 08:57:56 pm »
Here is my own, simple snowfall program (with accumulation)! This was my first attempt at animation in QBasic. I heavily commented it, in case it helps others. I'm also very open to feedback!

Code: QB64: [Select]
  1. 'SNOWFALL.BAS
  2. '============
  3.  
  4. 'DESCRIPTION
  5. '-----------
  6. '   A holiday screensaver for QBasic.
  7.  
  8. 'AUTHOR
  9. '------
  10. '   Dustinian Camburides
  11.  
  12. 'PLATFORM
  13. '--------
  14. '   Written in QB64.
  15. '   But designed to be QBasic/QuickBasic compatible.
  16. '       Although, I haven't tested QBasic / QuickBasic compatability yet.
  17.  
  18. 'VERSION
  19. '-------
  20. '1.0, 2021-12-18: First working version.
  21. '1.1, 2021-12-19: I was excited to keep working!
  22. '   Added page flipping to reduce flicker!
  23. '   Added background snowflakes at a smaller speed and dimmer color!
  24. '   Set the formula to advance snowflakes to actually use the FALLSPEED constant.
  25. '   Also started the timer before calculating all the snowflakes to smooth out the animation.
  26.  
  27. 'PLANNED ENHANCEMENTS
  28. '--------------------
  29. 'Maybe next year I will add...
  30. '   - Actual, tested QBasic compatability (need to to a DosBox install and find a copy of QBasic).
  31. '   - A more complex data structure for snowflakes that can store both X and Y coordinates in a dynamic array of user-defined types... so it can support more than one snowflake per column... and mabe some drift back-and-forth in the X-axis.
  32.  
  33. 'HOLIDAY MESSAGE
  34. '---------------
  35. 'But for now, I'm happy that I have my first QB64 program that has animation. Happy Holidays!
  36.  
  37. 'SUBS
  38. Declare Sub CalculateSnowflakeColumn (SnowFlake As Integer, Accumulation As Integer, Rows As Integer, FallSpeed As Integer, Odds As Single)
  39. Declare Sub DrawSnowflakeColumn (Snowflake As Integer, Accumulation As Integer, Column As Integer, Rows As Integer, SnowColor As Integer)
  40.  
  41. 'CONSTANTS
  42. Const FALLSPEED = 1 'Snow falls this many pixels at a time.
  43. Const COLUMNS = 319 'The screen is 320 pixels across (0-319) in Screen 7.
  44. Const ROWS = 199 'The screen is 200 pixels tall (0-199) in Screen 7.
  45. Const DELAY = 0.04 'The number of seconds between snowflake recalculation / re-draw... QBasic can't detect less than 0.04 seconds...
  46. Const ODDS = 0.7 'The % chance a snowflake will be added to a column that doesn't have a snowflake... anything over 1% will results in "waves" of snowflakes.
  47.  
  48. 'VARIABLES
  49. Dim intSnowflakes(COLUMNS) As Integer 'Array that holds the current Y-coordinate for a snowflake in this column... this means there can only be one snowflake per column at any given time.
  50. Dim intBackgroundSnowflakes(COLUMNS) As Integer 'Same as above, but for the background.
  51. Dim intAccumulation(COLUMNS) As Integer 'Array that holds the current accumulated pixels of snow in this column.
  52. Dim intBackgroundAccumulation(COLUMNS) As Integer ' Same as above, but for the background.
  53. Dim intColumn As Integer 'The current column in the loop.
  54. Dim sngStart As Single 'The timer at the start of the delay loop.
  55. Dim intBackgroundFrame As Integer 'Used to track whether the current frame will move the background snow...
  56. Dim intFullColumns As Integer 'Used to track the number of columns that are full of snow...
  57.  
  58. 'INITIALIZE VARIABLES
  59. 'For each column...
  60. For intColumn = 0 To COLUMNS
  61.     'Set all snowflakes to -1, indicating there is no snowflake in this column.
  62.     intSnowflakes(intColumn) = -1
  63.     intBackgroundSnowflakes(intColumn) = -1
  64.     'Set all accumulation to 0, indicating there is no accumulation in this column.
  65.     intAccumulation(intColumn) = 0
  66.     intBackgroundAccumulation(intColumn) = 0
  67. Next intColumn
  68. intBackgroundFrame = 0
  69.  
  70. 'INITIALIZE SCREEN
  71. 'Set the screen to mode 7 with an active page (where the cls, pset, and line commands occur) of 0 and a visible page (that the user sees) of 1.
  72. Screen 7, , 0, 1
  73. Color 15, 0
  74.  
  75. 'PROGRAM
  76. 'While no key has been pressed...
  77. While InKey$ = "" And intFullColumns < COLUMNS
  78.     'Set the delay timer...
  79.     Timer On
  80.     sngStart = Timer
  81.     'Reset the number of full columns...
  82.     intFullColumns = 0
  83.     'Flip whether the background snow will move on or off...
  84.     intBackgroundFrame = Not intBackgroundFrame
  85.     'For each column... calculate the changes to the snowfall...
  86.     For intColumn = 0 To COLUMNS
  87.         'If this is a background frame...
  88.         If intBackgroundFrame Then
  89.             'Recalculate background snow...
  90.             Call CalculateSnowflakeColumn(intBackgroundSnowflakes(intColumn), intBackgroundAccumulation(intColumn), ROWS, FALLSPEED, ODDS)
  91.             'Ensure background accumulation keeps up with foreground accumulation to smooth out the accumulation...
  92.             If intAccumulation(intColumn) > intBackgroundAccumulation(intColumn) Then intBackgroundAccumulation(intColumn) = intAccumulation(intColumn)
  93.         End If
  94.         'Draw the background snow first...
  95.         Call DrawSnowflakeColumn(intBackgroundSnowflakes(intColumn), intBackgroundAccumulation(intColumn), intColumn, ROWS, 7)
  96.         'Recalculate the foreground snow...
  97.         Call CalculateSnowflakeColumn(intSnowflakes(intColumn), intAccumulation(intColumn), ROWS, FALLSPEED, ODDS)
  98.         'Draw the foreground snow next, on top of the background snow...
  99.         Call DrawSnowflakeColumn(intSnowflakes(intColumn), intAccumulation(intColumn), intColumn, ROWS, 15)
  100.         'Track whether or not this column is full of snow (program will terminate when all columns are full)...
  101.         If intAccumulation(intColumn) = ROWS Then intFullColumns = intFullColumns + 1
  102.     Next intColumn
  103.     'Copy the active page (where we just drew the snow) to the visible page...
  104.     PCopy 0, 1
  105.     'Clear the active page for the next frame...
  106.     Cls
  107.     'Wait for the delay to pass before starting over...
  108.     Do
  109.     Loop Until Timer > sngStart + DELAY
  110.     Timer Off
  111.  
  112. Sub CalculateSnowflakeColumn (Snowflake As Integer, Accumulation As Integer, Rows As Integer, FallSpeed As Integer, Odds As Single)
  113.     'If there is a snowflake in the column (i.e. any value > -1) then...
  114.     If Snowflake > -1 Then
  115.         'If the snowflake has not fallen to the accumulation...
  116.         If (Snowflake + FallSpeed) < (Rows - Accumulation) Then
  117.             'Advance the snowflake...
  118.             Snowflake = Snowflake + FallSpeed
  119.         Else
  120.             'Eliminate the flake...
  121.             Snowflake = -1
  122.             'Add to the accumulation...
  123.             Accumulation = Accumulation + 1
  124.         End If
  125.     Else
  126.         'If accumulation hasn't filled up the column...
  127.         If Accumulation < Rows Then
  128.             'Maybe add a flake...
  129.             If (Rnd * 100) < Odds Then
  130.                 Snowflake = 0
  131.             End If
  132.         End If
  133.     End If
  134.  
  135. Sub DrawSnowflakeColumn (Snowflake As Integer, Accumulation As Integer, Column As Integer, Rows As Integer, SnowColor As Integer)
  136.     'If there is a snowflake in this column...
  137.     If Snowflake > -1 Then
  138.         'Draw the snowflake...
  139.         PSet (Column, Snowflake), SnowColor
  140.     End If
  141.     'If there is accumulation in this column...
  142.     If Accumulation > 0 Then
  143.         'Draw the accumulation...
  144.         Line (Column, Rows)-(Column, (Rows - Accumulation + 1)), SnowColor
  145.     End If

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #1 on: December 20, 2021, 09:01:42 pm »
Welcome to the forum @Dustinian!

This is a lovely and timely program for the season we're in! (It's cold here, at least.)

 
sssss.png


As you may have discovered, QB64 does a little bit more than the original QB. It's possible to modernize this demo for full screen, 32-bit colors - whatever you can imagine. (I'll wait for guys like bplus to jump on this thread.)

Show us more!
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #2 on: December 21, 2021, 12:05:46 am »
First I'd like to say, welcome to the forum.

You have labeled variables with good names and have well documented code.

The QB techniques are a bit old, eg for this
Code: QB64: [Select]
  1.     Do
  2.     Loop Until Timer > sngStart + DELAY
  3.     Timer Off
  4.  

You could simply use _Limit for a steady loop around timer, _Limit 30 will do at most 30 loops in 1 sec if the code runs that fast, if not the speed is limited by the processing time.

I removed the timer for fast drawing to see if you get hairy snow like I:
 
Hairy snow.PNG

yeah, so

to do same I went this way:
Code: QB64: [Select]
  1. _Title "Accumulating snow"
  2.  
  3. Const sw = 1024, sh = 700, nSnow = 80000 ' screen width and height, number of snow particles
  4. Screen _NewImage(sw, sh, 32) ' 32 for _RGB32(red, green, blue)
  5. _ScreenMove 100, 40
  6. Type snow
  7.     As Single x, y, falling
  8. ReDim Shared s(1 To nSnow) As snow ' snow fall array
  9. snowTop = 1200
  10. 'init snow
  11. For i = 1 To snowTop
  12.     newSnow i, -1
  13. While _KeyDown(27) = 0 ' until escape pressed
  14.     ' show snow
  15.     Cls
  16.     For i = 1 To snowTop
  17.         PSet (s(i).x, s(i).y), _RGB32(255, 255, 255) ' draw
  18.         If s(i).falling Then
  19.             If s(i).y >= sh - 1 Then
  20.                 s(i).falling = 0
  21.                 snowTop = snowTop + 1
  22.                 newSnow snowTop, 0
  23.             ElseIf Point(s(i).x, s(i).y + 1) <> _RGB32(255, 255, 255) Then ' continue falling
  24.                 s(i).y = s(i).y + 1
  25.             ElseIf Point(s(i).x, s(i).y + 1) = _RGB32(255, 255, 255) Then
  26.                 If snowTop < nSnow Then ' start another particle
  27.                     s(i).falling = 0
  28.                     snowTop = snowTop + 1
  29.                     newSnow snowTop, 0
  30.                 End If
  31.             End If
  32.         End If
  33.     Next
  34.     _Display 'prevents blinking
  35.     '_Limit 500 'controls snow fall speed
  36.  
  37. Sub newSnow (i, init)
  38.     If init Then s(i).y = Rnd * 2 * sh - sh Else s(i).y = Rnd * -sh
  39.     s(i).x = Rnd * sw
  40.     s(i).falling = -1
  41.  
  42.  
  43.  

except mine gets slower because it redraws all particles which increase during run.

I think there is way to get snow to lay flat without tall and short columns and keep snowfall constant rate.

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #3 on: December 21, 2021, 12:07:30 am »
I've never seen SCREEN 7 used before. Perhaps because you can do
page flipping with 9, and it has more dots to play with (640*350).

The TIMER ON and TIMER OFF are not necessary to use TIMER in the
way you are.  And your CPU might melt when the program crosses
midnite - a loop with no limit (lines 110 and 111). A better end
of loop condition would be:

    Loop Until Timer > ((sngStart + DELAY) mod 86400)

86400 = 24 hours * 60 minutes * 60 seconds, the duration of a day
on this planet. 

Are you aware that LONGs are generally faster then INTEGERs with
QB64?  Goes against the theory I learned, but such is the case.
But since you want backwards compatibility and the ultimate in
speed probably isn't required, INTEGERs are fine.

Nice demo.  I'll call Mr. Plow.


It works better if you plug it in.

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #4 on: December 21, 2021, 12:18:52 am »
My old attempt at snow - could use upgrading to the capabilities of QB64.

Arrow keys control the direction and speed of the snow.

Code: QB64: [Select]
  1. DefInt A-Z
  2.  
  3. _Title "Xmas Tree"
  4.  
  5. q = 22000
  6. q2 = 5000
  7. z = 15
  8. x = 640
  9. sn = Val(Command$): If sn = 0 Then sn = 5000
  10.  
  11. Dim x(q), y(q), garr(q2), sarr(q2), p&(z), f(z)
  12. Dim sd(x), sdm(x), bx(x), by(x), sx(sn), sy(sn), wp(sn)
  13.  
  14. begin:
  15. GoSub init
  16.     t# = Timer
  17.     GoSub snow
  18.     GoSub star
  19.     If t# > sparkat# Then GoSub sparkle
  20.     If t# > colorat# Then GoSub ccycle
  21.     If t# > drawbt# Then GoSub drawballs
  22.     i$ = InKey$
  23.     If Len(i$) = 2 Then
  24.         v = Asc(Right$(i$, 1))
  25.         yinc = yinc - (v = 80) + (v = 72)
  26.         xinc = xinc - (v = 77) + (v = 75)
  27.     End If
  28.     If i$ = Chr$(13) Then GoTo begin
  29. Loop Until i$ = Chr$(27)
  30. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  31. timeinc:
  32. tvar# = Timer + tinc!
  33. If tvar# > 86399 Then tvar# = var# - 86400
  34. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  35. ccycle:
  36. cs = cs + 1 + (cs = 2) * 3 '        turn a string of bulbs on/off
  37. i = cs * 4 + 3 '                    starting point for color
  38. f(cs) = 1 - f(cs) '                 flag as on/off
  39. For tc = 0 To 3 '                   4 shades per color
  40.     If f(cs) Then z& = p&(i) Else z& = p&(i + tc)
  41.     Palette i + tc, z& '            turn color on/off
  42. Next tc
  43. tinc! = .5: GoSub timeinc: colorat# = tvar#
  44. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  45. sparkle:
  46. sss = 1 - sss
  47. If sss = 0 Then
  48.     Put (spx, spy), sarr(), PSet '  restore area under sparkle
  49.     i = Rnd * (n - 1) + 1 '         pick random tree point
  50.     spx = x(i) - 12
  51.     spy = y(i)
  52.     ti = Int(Rnd * 10) * 200 '      pick random sparkle (of 10)
  53.     Get (spx, spy)-(spx + 25, spy + 25), sarr() ' save area to be plotted on
  54.     Put (spx, spy), garr(ti), Or ' merge sparkle
  55. tinc! = .1 - (sss = 0) * Rnd
  56. GoSub timeinc
  57. sparkat# = tvar#
  58. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  59. snow:
  60. For d& = 0 To sn
  61.     sf = sf + 1 + (sf = sn) * (sn + 1)
  62.     xi = sx(sf)
  63.     yi = sy(sf)
  64.     sd = sd(xi)
  65.     sdm = sdm(xi)
  66.     If yi = (479 - sd) Then
  67.         If (sd = 0) Or (Point(xi, yi + 1)) = 15 Then
  68.             If sd = sdm Then
  69.                 If Rnd > .7 Then wp(sf) = -15
  70.             Else
  71.                 sd(xi) = sd + 1
  72.                 wp(sf) = -15
  73.             End If
  74.             For tty = yi To 479
  75.                 PSet (xi, tty), -(Rnd > .3) * 15
  76.             Next tty
  77.         End If
  78.     End If
  79.     If wp(sf) < 15 Then PSet (sx(sf), sy(sf)), Abs(wp(sf))
  80.     If (sf Mod 30) = 0 Then
  81.         xdir = Rnd * xinc
  82.         ydir = Rnd * yinc
  83.     End If
  84.     sx(sf) = sx(sf) + xdir
  85.     sy(sf) = sy(sf) + ydir
  86.     okx = (sx(sf) >= 0) And (sx(sf) < xm)
  87.     oky = (sy(sf) >= 0) And (sy(sf) < ym)
  88.     If okx And oky Then
  89.         wp(sf) = Point(sx(sf), sy(sf))
  90.         PSet (sx(sf), sy(sf)), 15
  91.     Else
  92.         wp(sf) = 0
  93.         GoSub assign
  94.     End If
  95. Next d&
  96. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  97. assign:
  98. If Rnd > .5 Then
  99.     sx(sf) = Rnd * (xm - 1)
  100.     If yinc > 0 Then sy(sf) = 0 Else sy(sf) = 479
  101.     If xinc < 0 Then sx(sf) = xm - 1 Else sx(sf) = 0
  102.     sy(sf) = Rnd * 478 + 1
  103. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  104. init:
  105. xm = 640: ym = 480: q = 200: x1 = 12: y1 = 12
  106. n = 0: xp = 0: ta = 45: ts = 4: needles = 0: bi = 0
  107. For s = 0 To 9 ' make stars
  108.     GoSub star
  109.     Get (0, 0)-(25, 25), garr(s * q)
  110.     Line (0, 0)-(25, 25), 0, BF
  111. x1 = 320: y1 = 50: ta = 30: ts = 20 ' big treeptop star
  112. GoSub setcolor
  113. GoSub drawbase
  114. GoSub drawtree
  115. GoSub drawballs
  116. GoSub snowinit
  117. For i = 0 To 2
  118.     f(i) = -(Rnd < .5)
  119. q = 0
  120. y1 = y1 - 15
  121. ba# = Timer
  122. tinc! = 2: GoSub timeinc: colorat# = tvar#
  123. tinc! = 3: GoSub timeinc: sparkat# = tvar#
  124. tinc! = 1: GoSub timeinc: keyat# = tvar#
  125. If pn& = 0 Then
  126.     pn& = 4
  127.     pd& = 1
  128.     xinc = 2
  129.     yinc = 2
  130. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  131. snowinit:
  132. For i = 1 To sn '                   create snow
  133.     sx(i) = Rnd * xm
  134.     sy(i) = Rnd * ym
  135.     wp(i) = 0
  136. For i = 1 To sn '                   show snow
  137.     PSet (sx(i), sy(i)), 15
  138. z1 = Rnd * 8 + 8
  139. z2 = Rnd * 8 + 8
  140. For x = 0 To xm '                   set drift limits
  141.     ty1 = 6 * Sin(x / z1) + 10
  142.     ty2 = 6 * Sin(x / z2) + 10
  143.     If ty1 < ty2 Then y = ty2 Else y = ty1
  144.     sdm(x) = y: sd(x) = 0
  145. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  146. drawtree:
  147. k = 20
  148. For i! = 0 To 8.5 Step .1
  149.     For x0 = -k To k
  150.         x2 = 320 + i! * x0
  151.         y2 = y1 + i! * 45
  152.         For zz = 0 To 1
  153.             xe = Rnd * 30 - 15
  154.             ye = Rnd * 30 - 4
  155.             Line (x2, y2)-(x2 + xe, y2 + ye), 2
  156.             needles = needles + 1
  157.         Next zz
  158.         n = n + 1
  159.         x(n) = x2
  160.         y(n) = y2
  161.     Next x0
  162.     tk = k * 2
  163.     i = n - tk + Rnd * tk '         random point from y level
  164.     If i < 1 Then i = 1 '           bounds checking
  165.     If i > n Then i = n
  166.  
  167.     If y(i) < 500 Then dball = -(Rnd > .1)
  168.     If y(i) < 400 Then dball = -(Rnd > .1)
  169.     If y(i) < 300 Then dball = -(Rnd > .1)
  170.     If y(i) < 200 Then dball = -(Rnd > .5)
  171.     If y(i) < 100 Then dball = -(Rnd > .8)
  172.  
  173.     If dball Then '                 do ball
  174.         bi = bi + 1
  175.         bx(bi) = x(i)
  176.         by(bi) = y(i)
  177.     End If
  178.  
  179.     For vv = 0 To 3 '               garland
  180.         mr! = ma! * Atn(1) / 45
  181.         xp = 320 + i! * k * Sin(mr!)
  182.         Line (xp, y(i))-Step(1, 1), 15, BF
  183.         ma! = (ma! + 87) Mod 360
  184.     Next vv
  185. Next i!
  186. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  187. drawbase:
  188. p& = &H1315
  189. For y = 428 To 460
  190.     Line (300, y)-(340, y), 1, , p&
  191.     p& = (p& And &HFFF) * 8 + (p& And &HF000) / (2 ^ 12)
  192. xl = -0
  193. For y = 460 To 479 Step 1
  194.     For x = 286 - xl To 354 + xl
  195.         c = -(Rnd > .5) - (Rnd > .5)
  196.         PSet (x, y), c
  197.     Next x
  198.     xl = xl + 1
  199. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  200. drawballs:
  201. For i = 1 To bi
  202.     x = bx(i)
  203.     y = by(i)
  204.     c = (i Mod 3) * 4 + 6 '         light string
  205.     For zz = 6 To 0 Step -1 '       shading (4 shades per color)
  206.         tc = c - zz \ 2
  207.         For qq = zz To 0 Step -1
  208.             z1 = Rnd * 2
  209.             z2 = Rnd * 2
  210.             Circle (x + z1, y + z2), qq, tc
  211.             Circle (x, y), qq, tc
  212.         Next qq
  213.     Next zz
  214. 'tinc! = 600: GOSUB timeinc: drawbt# = tvar# ' redraw (snow covers balls)
  215. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  216. star:
  217. tsc = (tsc + 1) Mod 10
  218. For a = 0 To 180 Step ta
  219.     r! = a * Atn(1) / 45
  220.     zx = Rnd * ts + 2
  221.     zy = zx + 2
  222.     x3 = x1 + zx * Cos(r!): x4 = x1 - zx * Cos(r!)
  223.     y3 = y1 + zy * Sin(r!): y4 = y1 - zy * Sin(r!)
  224.     Line (x3, y3)-(x4, y4), (tsc > 5) * -15
  225. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  226. setcolor:
  227. For c = 0 To 15
  228.     Read gg, r, g, b
  229.     p&(c) = CDbl(b) * 65536 + CDbl(g) * 256 + r
  230.     Palette c, p&(c)
  231. ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  232. Data 0,0,0,0
  233. Data 1,30,12,14
  234. Data 2,22,34,22
  235. Data 3,32,0,0
  236. Data 4,50,10,10
  237. Data 5,60,16,16
  238. Data 6,63,20,20
  239. Data 7,7,7,30
  240. Data 8,10,10,50
  241. Data 9,21,21,58
  242. Data 10,31,31,63
  243. Data 11,32,32,4
  244. Data 12,42,42,10
  245. Data 13,55,55,12
  246. Data 14,63,63,20
  247. Data 15,60,60,60
  248.  
« Last Edit: December 21, 2021, 12:24:08 am by Richard Frost »
It works better if you plug it in.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #5 on: December 21, 2021, 10:07:06 am »
Pretty cool.

Now take it to the next level, instead of 2 layers of snow, multiple layers of snow moving in different directions, with different accumulation layers. With small 'gusts' of wind that blow some of the accumulation off the screen from time to time so it doesn't fill the whole screen.

Make this the creme de la creme of Snowfall Screen Savers!
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #6 on: December 21, 2021, 12:29:29 pm »
Yeah if don't want to worry about accumulation:
Code: QB64: [Select]
  1. _Title "Snowjob, drawn flakes" ' B+ mod 2018-12-5  <<<<<<<<<<<< 2021-12-21 tinkered with numbers
  2.  
  3. ' screen
  4. Const XMAX = 1000
  5. Const YMAX = 600
  6. Screen _NewImage(XMAX, YMAX, 32)
  7. '_ScreenMove 200, 100
  8. _FullScreen ' <<<<<<<<<<<<<<<<< for screen saver
  9.  
  10. 'snow making machine
  11. Type PARTICLE
  12.     x As Single
  13.     y As Single
  14.     dx As Single
  15.     dy As Single
  16.     size As Single
  17.     density As Single
  18.     angle As Single
  19.     dir As Single
  20.     maxy As Single
  21.  
  22. '  background, try 3 backgrounds
  23. wallpaper& = _NewImage(XMAX, YMAX, 32)
  24. _Dest wallpaper&
  25. drawLandscape
  26.  
  27. nLayers = 15
  28. flakes = 2 ^ (nLayers + 1) - 1
  29. Dim snow(flakes) As PARTICLE
  30. horizon = .5 * YMAX
  31. For layer = nLayers To 1 Step -1
  32.     For flake = 0 To 2 ^ layer
  33.         snow(flake).x = Rnd * 2 * XMAX - .5 * XMAX
  34.         snow(flake).y = Rnd * 2 * YMAX - YMAX ' <<<<<<<<<<<<<< fix clear clearing when first start by spreading over 2 screens
  35.         snow(flake).dx = .1 * (nLayers + 1 - layer) * Cos(Rnd * _Pi(.6666) + _Pi(.0833))
  36.         If snow(flake).dx < -.2 Then snow(flake).dx = -snow(flake).dx '              <<<<<<<<<<<<< add a little wind
  37.         snow(flake).dy = .1 * (nLayers + 1 - layer) * Sin(Rnd * _Pi(.6666) + _Pi(.0833))
  38.         If snow(flake).dy < .2 Then snow(flake).dy = .2 '                       <<<<<<<<<<<<<< make sure everything is falling
  39.         snow(flake).size = .5 * (nLayers - layer)
  40.         snow(flake).density = 2.3 + Rnd * .5
  41.         snow(flake).angle = Rnd * _Pi
  42.         If Rnd < .5 Then snow(flake).dir = -1 Else snow(flake).dir = 1
  43.         snow(flake).maxy = horizon + (nLayers + 1 - layer) * 30
  44.     Next
  45.  
  46. While _KeyDown(27) = 0 ' <<<<<<<<<<<<< allow escape from full screen
  47.     _PutImage , wallpaper&, 0
  48.     For flake = flakes To 0 Step -1
  49.         If Rnd < .2 Then
  50.             snow(flake).x = snow(flake).x + snow(flake).dx + Rnd * 2 - 1
  51.             snow(flake).y = snow(flake).y + snow(flake).dy + Rnd * 2 - 1
  52.         Else
  53.             snow(flake).x = snow(flake).x + snow(flake).dx
  54.             snow(flake).y = snow(flake).y + snow(flake).dy
  55.         End If
  56.         If snow(flake).size <= 1 Then
  57.             PSet (snow(flake).x, snow(flake).y), _RGBA32(255, 255, 255, 80)
  58.         ElseIf snow(flake).size <= 2 Then
  59.             Circle (snow(flake).x, snow(flake).y), 1, _RGBA32(255, 255, 255, 100)
  60.         Else
  61.             snow(flake).angle = snow(flake).angle + snow(flake).dir * _Pi(1 / 100) ' <<<<<< turn flakes more
  62.             rFlake snow(flake).x, snow(flake).y, snow(flake).size, snow(flake).density, snow(flake).angle
  63.         End If
  64.         If snow(flake).y > snow(flake).maxy Or snow(flake).x < -.5 * XMAX Or snow(flake).x > 1.5 * XMAX Then
  65.             snow(flake).x = Rnd * 2 * XMAX - .5 * XMAX
  66.             snow(flake).y = Rnd * YMAX - 1.1 * YMAX
  67.         End If
  68.     Next
  69.     _Display
  70.     _Limit 60
  71.  
  72. Sub rFlake (x, y, r, DV, rAng)
  73.     'DV = flake density
  74.     Color _RGBA32(225, 225, 245, r ^ 2 * 30)
  75.     For a = 0 To 5
  76.         armX = x + r * Cos(a * _Pi(1 / 3) + rAng)
  77.         armY = y + r * Sin(a * _Pi(1 / 3) + rAng)
  78.         Line (x, y)-(armX, armY)
  79.         If r > 2.5 Then rFlake armX, armY, r / DV, DV, rAng
  80.     Next
  81.  
  82. Sub midInk (r1%, g1%, b1%, r2%, g2%, b2%, fr##)
  83.     Color _RGB(r1% + (r2% - r1%) * fr##, g1% + (g2% - g1%) * fr##, b1% + (b2% - b1%) * fr##)
  84.  
  85. Function rand% (lo%, hi%)
  86.     rand% = Int(Rnd * (hi% - lo% + 1)) + lo%
  87.  
  88. Sub drawLandscape
  89.     'needs midInk, rand
  90.     'the sky
  91.     For i = 0 To YMAX
  92.         midInk 0, 0, 28, 220, 120, 128, i / YMAX '<<<<<<<<<<<<  dark on top lighter redder lower
  93.         Line (0, i)-(XMAX, i)
  94.     Next
  95.     'the land
  96.     startH = YMAX - 300
  97.     rgb = 135 ' <<<<<<<<<<<<<<<<<<<<<< less white
  98.     For mountain = 1 To 6
  99.         Xright = 0
  100.         y = startH
  101.         While Xright < XMAX
  102.             ' upDown = local up / down over range, change along Y
  103.             ' range = how far up / down, along X
  104.             upDown = (Rnd * .8 - .35) * (mountain * .5)
  105.             range = Xright + rand%(15, 35) * 3.5 / mountain
  106.             lastx = Xright - 1
  107.             Color _RGB32(rgb + 40, rgb - 30, rgb)
  108.             For X = Xright To range
  109.                 y = y + upDown
  110.                 Line (lastx, y)-(X, YMAX), , BF 'just lines weren't filling right
  111.                 lastx = X
  112.             Next
  113.             Xright = range
  114.         Wend
  115.         '_DELAY 1
  116.         rgb = rand%(rgb, rgb + 20)
  117.         startH = startH + rand%(5, 20)
  118.     Next
  119.  
  120.  
  121.  

Edit: tinkered with numbers

Edit again for full screen saver.
« Last Edit: December 21, 2021, 01:21:27 pm by bplus »

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #7 on: December 21, 2021, 05:26:08 pm »
As usual, Bplus' effort is the prettiest.  But it's a bit slow.
And the near flakes are so large that when they hit the ground,
the planet should spit in two, or aliens jump out and demand
cheese products.
It works better if you plug it in.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #8 on: December 22, 2021, 08:30:20 pm »
Slow?! Oh you're from Canada!
Code: QB64: [Select]
  1. _Title "Snowjob, drawn flakes" ' B+ mod 2018-12-5  <<<<<<<<<<<< 2021-12-21 tinkered with numbers
  2.  
  3. ' screen
  4. Const XMAX = 1000
  5. Const YMAX = 600
  6. Screen _NewImage(XMAX, YMAX, 32)
  7. '_ScreenMove 200, 100
  8. _FullScreen ' <<<<<<<<<<<<<<<<< for screen saver
  9.  
  10. 'snow making machine
  11. Type PARTICLE
  12.     x As Single
  13.     y As Single
  14.     dx As Single
  15.     dy As Single
  16.     size As Single
  17.     density As Single
  18.     angle As Single
  19.     dir As Single
  20.     maxy As Single
  21.  
  22. '  background, try 3 backgrounds
  23. wallpaper& = _NewImage(XMAX, YMAX, 32)
  24. _Dest wallpaper&
  25. drawLandscape
  26.  
  27. nLayers = 15
  28. flakes = 2 ^ (nLayers + 1) - 1
  29. Dim snow(flakes) As PARTICLE
  30. horizon = .5 * YMAX
  31. For layer = nLayers To 1 Step -1
  32.     For flake = 0 To 2 ^ layer
  33.         snow(flake).x = Rnd * 2 * XMAX - .5 * XMAX
  34.         snow(flake).y = Rnd * 2 * YMAX - YMAX ' <<<<<<<<<<<<<< fix clear clearing when first start by spreading over 2 screens
  35.         snow(flake).dx = 3 * (nLayers + 1 - layer) * Cos(Rnd * _Pi(.6666) + _Pi(.0833))
  36.         If snow(flake).dx < -.2 Then snow(flake).dx = -snow(flake).dx '              <<<<<<<<<<<<< add a little wind
  37.         snow(flake).dy = 3 * (nLayers + 1 - layer) * Sin(Rnd * _Pi(.6666) + _Pi(.0833))
  38.         If snow(flake).dy < .2 Then snow(flake).dy = .2 '                       <<<<<<<<<<<<<< make sure everything is falling
  39.         snow(flake).size = .5 * (nLayers - layer)
  40.         snow(flake).density = 2.3 + Rnd * .5
  41.         snow(flake).angle = Rnd * _Pi
  42.         If Rnd < .5 Then snow(flake).dir = -1 Else snow(flake).dir = 1
  43.         snow(flake).maxy = horizon + (nLayers + 1 - layer) * 30
  44.     Next
  45.  
  46. While _KeyDown(27) = 0 ' <<<<<<<<<<<<< allow escape from full screen
  47.     _PutImage , wallpaper&, 0
  48.     For flake = flakes To 0 Step -1
  49.         If Rnd < .2 Then
  50.             snow(flake).x = snow(flake).x + snow(flake).dx + Rnd * 2 - 1
  51.             snow(flake).y = snow(flake).y + snow(flake).dy + Rnd * 2 - 1
  52.         Else
  53.             snow(flake).x = snow(flake).x + snow(flake).dx
  54.             snow(flake).y = snow(flake).y + snow(flake).dy
  55.         End If
  56.         If snow(flake).size <= 1 Then
  57.             PSet (snow(flake).x, snow(flake).y), _RGBA32(255, 255, 255, 80)
  58.         ElseIf snow(flake).size <= 2 Then
  59.             Circle (snow(flake).x, snow(flake).y), 1, _RGBA32(255, 255, 255, 100)
  60.         Else
  61.             snow(flake).angle = snow(flake).angle + snow(flake).dir * _Pi(1 / 100) ' <<<<<< turn flakes more
  62.             rFlake snow(flake).x, snow(flake).y, snow(flake).size, snow(flake).density, snow(flake).angle
  63.         End If
  64.         If snow(flake).y > snow(flake).maxy Or snow(flake).x < -.5 * XMAX Or snow(flake).x > 1.5 * XMAX Then
  65.             snow(flake).x = Rnd * 2 * XMAX - .5 * XMAX
  66.             snow(flake).y = Rnd * YMAX - 1.1 * YMAX
  67.         End If
  68.     Next
  69.     _Display
  70.     '_Limit 60
  71.  
  72. Sub rFlake (x, y, r, DV, rAng)
  73.     'DV = flake density
  74.     Color _RGBA32(225, 225, 245, r ^ 2 * 30)
  75.     For a = 0 To 5
  76.         armX = x + r * Cos(a * _Pi(1 / 3) + rAng)
  77.         armY = y + r * Sin(a * _Pi(1 / 3) + rAng)
  78.         Line (x, y)-(armX, armY)
  79.         If r > 2.5 Then rFlake armX, armY, r / DV, DV, rAng
  80.     Next
  81.  
  82. Sub midInk (r1%, g1%, b1%, r2%, g2%, b2%, fr##)
  83.     Color _RGB(r1% + (r2% - r1%) * fr##, g1% + (g2% - g1%) * fr##, b1% + (b2% - b1%) * fr##)
  84.  
  85. Function rand% (lo%, hi%)
  86.     rand% = Int(Rnd * (hi% - lo% + 1)) + lo%
  87.  
  88. Sub drawLandscape
  89.     'needs midInk, rand
  90.     'the sky
  91.     For i = 0 To YMAX
  92.         midInk 0, 0, 28, 220, 120, 128, i / YMAX '<<<<<<<<<<<<  dark on top lighter redder lower
  93.         Line (0, i)-(XMAX, i)
  94.     Next
  95.     'the land
  96.     startH = YMAX - 300
  97.     rgb = 135 ' <<<<<<<<<<<<<<<<<<<<<< less white
  98.     For mountain = 1 To 6
  99.         Xright = 0
  100.         y = startH
  101.         While Xright < XMAX
  102.             ' upDown = local up / down over range, change along Y
  103.             ' range = how far up / down, along X
  104.             upDown = (Rnd * .8 - .35) * (mountain * .5)
  105.             range = Xright + rand%(15, 35) * 3.5 / mountain
  106.             lastx = Xright - 1
  107.             Color _RGB32(rgb + 40, rgb - 30, rgb)
  108.             For X = Xright To range
  109.                 y = y + upDown
  110.                 Line (lastx, y)-(X, YMAX), , BF 'just lines weren't filling right
  111.                 lastx = X
  112.             Next
  113.             Xright = range
  114.         Wend
  115.         '_DELAY 1
  116.         rgb = rand%(rgb, rgb + 20)
  117.         startH = startH + rand%(5, 20)
  118.     Next
  119.  
  120.  
  121.  

O Canada our home and native land...

Actually this code was made for image backgrounds for Christmas challenge a few years back.

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #9 on: December 22, 2021, 09:37:25 pm »
Much faster, therefore more convincing.  I tinkered with it a little to
try and get more speed (fewer layers and flakes), but just crashed it.

You qualify to put a pom-pom on your hat.  Eh?
« Last Edit: December 22, 2021, 09:49:20 pm by Richard Frost »
It works better if you plug it in.

Offline Dustinian

  • Newbie
  • Posts: 2
    • View Profile
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #10 on: December 23, 2021, 01:16:54 am »
Wow! A lot of great feedback on my first post! I've taken a lot of the feedback to heart.
  • Hairy Snow @bplus, great feedback! I added a "settle" function that gives spikey accumulation an increasingly likely chance to settle left or right when the delta is 2 pixels or more.
  • Screen 9 @Richard Frost, great feedback! I've made this change!
  • Timer Crossing Midnight @Richard Frost, great feedback, I had not considered midnight! I've made a similar change to the one you suggested (your exact suggestion didn't work for me... using MOD to get the remainder after seconds causes a 1 second delay every other second... the same problem you pointed out would occur after midnight, but every second now. So I just added another condition to the loop that sngStart had to be >= Timer for the loop to continue.

Code: QB64: [Select]
  1. 'SNOWFALL.BAS
  2. '============
  3.  
  4. 'DESCRIPTION
  5. '-----------
  6. '   A holiday screensaver for QBasic.
  7.  
  8. 'AUTHOR
  9. '------
  10. '   Dustinian Camburides
  11.  
  12. 'PLATFORM
  13. '--------
  14. '   Written in QB64.
  15. '   But designed to be QBasic/QuickBasic compatible.
  16. '       Although, I haven't tested QBasic / QuickBasic compatability yet.
  17.  
  18. 'VERSION
  19. '-------
  20. '1.0, 2021-12-18: First working version.
  21. '1.1, 2021-12-19: I was excited to keep working!
  22. '   Added page-flipping to reduce flicker!
  23. '   Added background snowflakes at a smaller speed and dimmer color!
  24. '   Set the formula to advance snowflakes to actually use the FALLSPEED constant.
  25. '   Also started the timer before calculating all the snowflakes to smooth out the animation.
  26. '1.2, 2021-12-23: Updates with encouragement from the great folks at qb64.org/forum!
  27. '   Added a "settle" function to let "spiky" snow accumulation settle. (Thank you for the suggestion bplus!)
  28. '   Updated the delay so it doesn't break when it starts before midnight and ends after midnight. (Thank you for the suggestion Richard Frost!)
  29. '   Shifted to screen 9 to keep page-flipping, but at a higher resolution. (Thank you for the suggestion Richard Frost!)
  30.  
  31. 'PLANNED ENHANCEMENTS
  32. '--------------------
  33. 'Maybe next year I will add...
  34. '   - Actual, tested QBasic compatability (need to to a DosBox install and find a copy of QBasic).
  35. '   - A more complex data structure for snowflakes that can store both X and Y coordinates in a dynamic array of user-defined types... so it can support more than one snowflake per column... and mabe some drift back-and-forth in the X-axis.
  36.  
  37. 'HOLIDAY MESSAGE
  38. '---------------
  39. 'But for now, I'm happy that I have my first QB64 program that has animation. Happy Holidays!
  40.  
  41. 'SUBS
  42. Declare Sub CalculateSnowflakeColumn (SnowFlake As Integer, Accumulation As Integer, Rows As Integer, FallSpeed As Integer, Odds As Single)
  43. Declare Sub DrawSnowflakeColumn (Snowflake As Integer, Accumulation As Integer, Column As Integer, Rows As Integer, SnowColor As Integer)
  44. Declare SettleAccumulation (LeftAccumulation As Integer, Accumulation As Integer, RightAccumulation As Integer)
  45.  
  46. 'CONSTANTS
  47. Const FALLSPEED = 1 'Snow falls this many pixels per frame.
  48. Const COLUMNS = 639 'The screen is 640 pixels across (0-639) in Screen 9.
  49. Const ROWS = 349 'The screen is 350 pixels tall (0-349) in Screen 9.
  50. Const DELAY = 0.04 'The number of seconds between snowflake recalculation / re-draw... QBasic can't detect less than 0.04 seconds...
  51. Const ODDS = 0.7 'The % chance a snowflake will be added to a column that doesn't have a snowflake... anything over 1% will results in "waves" of snowflakes.
  52.  
  53. 'VARIABLES
  54. Dim intSnowflakes(COLUMNS) As Integer 'Array that holds the current Y-coordinate for a snowflake per column... this means there can only be one snowflake per column at any given time.
  55. Dim intBackgroundSnowflakes(COLUMNS) As Integer 'Same as above, but for the background.
  56. Dim intAccumulation(COLUMNS) As Integer 'Array that holds the current accumulated pixels of snow per column.
  57. Dim intBackgroundAccumulation(COLUMNS) As Integer ' Same as above, but for the background.
  58. Dim intColumn As Integer 'The current column in the loop.
  59. Dim sngStart As Single 'The timer at the start of the delay loop.
  60. Dim intBackgroundFrame As Integer 'Whether the current frame will move the background snow...
  61. Dim intFullColumns As Integer 'Used to track the number of columns that are full of snow...
  62.  
  63. 'INITIALIZE VARIABLES
  64. 'For each column...
  65. For intColumn = 0 To COLUMNS
  66.     'Set all snowflakes to -1, indicating there is no snowflake in this column.
  67.     intSnowflakes(intColumn) = -1
  68.     intBackgroundSnowflakes(intColumn) = -1
  69.     'Set all accumulation to 0, indicating there is no accumulation in this column.
  70.     intAccumulation(intColumn) = 0
  71.     intBackgroundAccumulation(intColumn) = 0
  72. Next intColumn
  73. intBackgroundFrame = 0
  74.  
  75. 'INITIALIZE SCREEN
  76. 'Set the screen to mode 9 with an active page (where the cls, pset, and line commands occur) of 0 and a visible page (that the user sees) of 1.
  77. Screen 9, , 0, 1
  78. Color 15, 0
  79.  
  80. 'PROGRAM
  81. 'While no key has been pressed...
  82. While InKey$ = "" And intFullColumns < COLUMNS
  83.     'Set the delay timer...
  84.     sngStart = Timer
  85.     'Reset the number of full columns...
  86.     intFullColumns = 0
  87.     'Flip whether the background snow will move on or off...
  88.     intBackgroundFrame = Not intBackgroundFrame
  89.     'For each column... calculate the changes to the snowfall...
  90.     For intColumn = 0 To COLUMNS
  91.         'Settle the accumulation...
  92.         If intColumn > 0 And intColumn < COLUMNS Then
  93.             Call SettleAccumulation(intAccumulation(intColumn - 1), intAccumulation(intColumn), intAccumulation(intColumn + 1))
  94.             Call SettleAccumulation(intBackgroundAccumulation(intColumn - 1), intBackgroundAccumulation(intColumn), intBackgroundAccumulation(intColumn + 1))
  95.         End If
  96.         'If this is a background frame...
  97.         If intBackgroundFrame Then
  98.             'Recalculate background snow...
  99.             Call CalculateSnowflakeColumn(intBackgroundSnowflakes(intColumn), intBackgroundAccumulation(intColumn), ROWS, FALLSPEED, ODDS)
  100.             'Ensure background accumulation keeps up with foreground accumulation to smooth out the accumulation...
  101.             If intAccumulation(intColumn) > intBackgroundAccumulation(intColumn) Then intBackgroundAccumulation(intColumn) = intAccumulation(intColumn)
  102.         End If
  103.         'Draw the background snow first...
  104.         Call DrawSnowflakeColumn(intBackgroundSnowflakes(intColumn), intBackgroundAccumulation(intColumn), intColumn, ROWS, 7)
  105.         'Recalculate the foreground snow...
  106.         Call CalculateSnowflakeColumn(intSnowflakes(intColumn), intAccumulation(intColumn), ROWS, FALLSPEED, ODDS)
  107.         'Draw the foreground snow next, on top of the background snow...
  108.         Call DrawSnowflakeColumn(intSnowflakes(intColumn), intAccumulation(intColumn), intColumn, ROWS, 15)
  109.         'Track whether or not this column is full of snow (program will terminate when all columns are full)...
  110.         If intAccumulation(intColumn) = ROWS Then intFullColumns = intFullColumns + 1
  111.     Next intColumn
  112.     'Copy the active page (where we just drew the snow) to the visible page...
  113.     PCopy 0, 1
  114.     'Clear the active page for the next frame...
  115.     Cls
  116.     'Wait for the delay to pass before starting over...
  117.     While (Timer < (sngStart + DELAY)) And (Timer >= sngStart)
  118.     Wend
  119. PCopy 0, 1
  120.  
  121. Sub CalculateSnowflakeColumn (Snowflake As Integer, Accumulation As Integer, Rows As Integer, FallSpeed As Integer, Odds As Single)
  122.     'If there is a snowflake in the column (i.e. any value > -1) then...
  123.     If Snowflake > -1 Then
  124.         'If the snowflake has not fallen to the accumulation...
  125.         If (Snowflake + FallSpeed) < (Rows - Accumulation) Then
  126.             'Advance the snowflake...
  127.             Snowflake = Snowflake + FallSpeed
  128.         Else
  129.             'Eliminate the flake...
  130.             Snowflake = -1
  131.             'Add to the accumulation...
  132.             Accumulation = Accumulation + 1
  133.         End If
  134.     Else
  135.         'If accumulation hasn't filled up the column...
  136.         If Accumulation < Rows Then
  137.             'Maybe add a flake...
  138.             If (Rnd * 100) < Odds Then
  139.                 Snowflake = 0
  140.             End If
  141.         End If
  142.     End If
  143.  
  144. Sub DrawSnowflakeColumn (Snowflake As Integer, Accumulation As Integer, Column As Integer, Rows As Integer, SnowColor As Integer)
  145.     'If there is a snowflake in this column...
  146.     If Snowflake > -1 Then
  147.         'Draw the snowflake...
  148.         PSet (Column, Snowflake), SnowColor
  149.     End If
  150.     'If there is accumulation in this column...
  151.     If Accumulation > 0 Then
  152.         'Draw the accumulation...
  153.         Line (Column, Rows)-(Column, (Rows - Accumulation + 1)), SnowColor
  154.     End If
  155.  
  156. Sub SettleAccumulation (LeftAccumulation As Integer, Accumulation As Integer, RightAccumulation As Integer)
  157.     'If accumulation should settle left...
  158.     If ((Rnd * (Accumulation - LeftAccumulation)) > 2) Then
  159.         'Shift accumulation to the left
  160.         LeftAccumulation = LeftAccumulation + 1
  161.         Accumulation = Accumulation - 1
  162.         'If accumulation should settle right...
  163.     ElseIf ((Rnd * (Accumulation - RightAccumulation)) > 2) Then
  164.         'Shift accumulation to the right
  165.         RightAccumulation = RightAccumulation + 1
  166.         Accumulation = Accumulation - 1
  167.     End If
  168.  

Offline DANILIN

  • Forum Regular
  • Posts: 128
    • View Profile
    • Danilin youtube
Re: Screensaver: Super Simple Snowfall (with accumulation)
« Reply #11 on: December 23, 2021, 01:17:49 am »
I forgot to turn off my computer

 
RussianRoof.jpg
Russia looks world from future. big data is peace data.
https://youtube.com/playlist?list=PLBBTP9oVY7IagpH0g9FNUQ8JqmHwxDDDB
i never recommend anything to anyone and always write only about myself