BBC BASIC
General >> Support and Promote >> Snow Scene animation
http://bbcbasic.conforums.com/index.cgi?board=support&action=display&num=1478877704

Snow Scene animation
Post by Richard Russell on Nov 11th, 2016, 2:21pm

A simple but effective animation. One interesting feature is the drawing of a realistic-looking fractal tree using random parameters; the tree is different every time you run the program. The code is optimised for BBCSDL but will run (rather slowly) in BB4W; it was adapted from a program I wrote for Just BASIC and Liberty BASIC (I find myself increasingly writing LB code and then adapting LBB's automatic translation to BBC BASIC).



Code:
      REM Snow Scene for BBC BASIC for Windows, Linux and Mac OS
      REM (C) 2016  Richard Russell, http://www.rtrussell.co.uk/

      VDU 23,22,800;600;8,8,16,0
      COLOUR 128+4
      CLS
      OFF

      Flakes% = 500
      DIM flake(Flakes%,2), flag%(Flakes%)
      floor = 1.0

      GCOL 0
      IF GET(0,0) : REM SDL Thread sync
      PROCbranch(@vdu%!208 / 3, 0, @vdu%!212 / 5, 1.6, 10)
      bmp% = FNgetbmp
      GCOL 4,0
      VDU 23,23,1|
      PROCinitflakes
      REPEAT
        WAIT 4
        winda += RND(1) / 10
        IF winda >= 2*PI winda -= 2*PI
        wind = SIN(winda)

        FOR i% = 1 TO Flakes%
          IF flag%(i%) THEN
            GCOL 15
            PROCflake(i%)
            GCOL 4,0
            flake(i%,0) = RND(@vdu%!208 * 2 + 200) - 100
            flake(i%,1) = @vdu%!212 * 2 - RND(4)
          ELSE
            PROCflake(i%)
          ENDIF
          flake(i%,0) += wind*flake(i%,2)
          flake(i%,1) -= 2*flake(i%,2)
          flag%(i%) = flake(i%,1) <= floor
          IF RND(1) < 0.02 IF FNgetpixel(bmp%,flake(i%,0),flake(i%,1)) = 0 flag%(i%) = TRUE
          IF NOT flag%(i%) PROCflake(i%)
        NEXT
        floor += 0.02
      UNTIL FALSE
      END

      DEF PROCinitflakes
      LOCAL i%
      FOR i% = 1 TO Flakes%
        flake(i%,0) = RND(@vdu%!208 * 2 + 200) - 100
        flake(i%,1) = RND(@vdu%!212 * 2)
        flake(i%,2) = RND(4)
        PROCflake(i%)
      NEXT
      ENDPROC

      DEF PROCbranch(x1, y1, size, angle, depth%)
      LOCAL x2, y2
      x2 = x1 + size * COS(angle)
      y2 = y1 + size * SIN(angle)
      VDU 23,23,1.4^depth%|
      LINE x1*2,y1*2,x2*2,y2*2
      IF depth% THEN
        PROCbranch(x2, y2, size * (RND(1) / 5 + 0.64), angle - 0.1 - RND(1) / 2, depth% - 1)
        PROCbranch(x2, y2, size * (RND(1) / 5 + 0.64), angle + 0.1 + RND(1) / 2, depth% - 1)
        IF depth% > 2 THEN
          PROCbranch((x1 + x2) / 2, (y1 + y2) / 2, size * 0.4, angle + RND(1) - 0.5, depth% - 3)
        ENDIF
      ENDIF
      ENDPROC

      DEF PROCflake(I%)
      LOCAL X%,Y%
      X% = flake(I%,0)
      Y% = flake(I%,1)
      CASE flake(I%,2) OF
        WHEN 1: MOVE X%-2,Y% : PLOT 9,4,0 : PLOT X%,Y%-2 : PLOT X%,Y%+2
        WHEN 2: RECTANGLE FILL X%-2,Y%-2,4,4
        WHEN 3: MOVE X%-4,Y%-2 : MOVE X%+4,Y%-2 : PLOT 85,X%,Y%+4
        WHEN 4: MOVE X%-4,Y%-2 : MOVE X%+4,Y%-2 : PLOT 85,X%,Y%+4
          PLOT X%,Y%-4 : PLOT X%-4,Y%+2 : PLOT X%+4,Y%+2
      ENDCASE
      ENDPROC

      DEF FNgetbmp
      LOCAL F%, P%
      OSCLI "GSAVE """ + @tmp$ + "tmp.bmp"""
      F% = OPENIN(@tmp$ + "tmp.bmp")
      DIM P% EXT#F%
      CLOSE #F%
      OSCLI "LOAD """ + @tmp$ + "tmp.bmp"" " + STR$~P%
      OSCLI "ERASE """ + @tmp$ + "tmp.bmp"""
      = P%

      DEF FNgetpixel(P%, X%, Y%)
      LOCAL B%, O%, W%, H%
      X% DIV= 2
      Y% DIV= 2
      O% = P%!10
      W% = P%!18
      H% = P%!22
      B% = P%?28 >> 3
      W% = ((W% * B%) + 3) AND -4
      IF H% < 0 Y% = - H% - Y% - 1
      = P%?(O% + B%*X% + W%*Y%) 

Re: Snow Scene animation
Post by DDRM on Nov 15th, 2016, 1:21pm

Hi Richard,

I think that's very cute - I particularly like your tree routine. The idea of having some small branches coming off mid-branch is very effective, and gives nice realistic-looking trees.

Best wishes,

D
Re: Snow Scene animation
Post by treehouse on Jan 8th, 2018, 8:47pm

Great stuff. At first I thought I'd got the measure of this program in the first few seconds. Tree, snow. It was only by studying the program I realised the wind is drifting the snowflakes about, and they're settling on the ground and tree.

Quote:
The code is optimised for BBCSDL but will run (rather slowly) in BB4W
There's a WAIT 4 in there, which it seems it can do without. A bit faster.
Re: Snow Scene animation
Post by Richard Russell on Jan 8th, 2018, 9:24pm

on Jan 8th, 2018, 8:47pm, treehouse wrote:
There's a WAIT 4 in there, which it seems it can do without.

Without a WAIT, the program will consume 100% CPU (100% of one core anyway) which isn't generally acceptable. In the old days (for example on the BBC Micro) it was quite normal to run the CPU 'flat out', and indeed doing so would probably have little effect either on power consumption or temperature.

But modern CPUs aren't like that: running a core at 100% will cause the battery in a laptop to run down much faster than is desirable, and is also likely to result in so much heat production that the cooling fan(s) ramp up.

So a WAIT of some kind is desirable, and a WAIT 4 will cause the animation to max out at about 25 frames a second which is fast enough to be fairly smooth. In a more sophisticated program it may well be necessary to take steps to ensure that the frame rate is constant irrespective of the CPU speed.

Many graphics programs rely on *REFRESH (snowscene is an exception) and then you must take special care. In BB4W it simply sets a flag telling Windows to redraw the window when it next gets an opportunity, whereas in BBCSDL it actively synchronises with the display's refresh rate by waiting until the next vertical sync.

Therefore you can often end up wanting to use code similar to the following to match the program's performance on the two platforms:

Code:
      IF INKEY$(-256) = "W" THEN WAIT 2
      *REFRESH 

Richard.

P.S. I should perhaps add that, these days, I generally develop programs under BBCSDL and their performance when running under BB4W (if they work at all) is not something I pay much attention to.
Re: Snow Scene animation
Post by treehouse on Jan 9th, 2018, 12:28am

Ah yes, I remember now! I looked up a fair few things in the help as I went through the code, but I didn't bother to look up WAIT.

That issue of constant frame rate is just what I've come across in my biggest BB4W project, a game that I suddenly realised ran crazy fast on a different machine. As usual, not sure I'll ever finish it anyway!

And I probably need to introduce at least a WAIT 0 into a few others.
Thanks
John