Welcome Guest. Please Login or Register. Mar 31st, 2018, 10:40pm
ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018. We apologize Conforums does not have any export functions to migrate data. Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.
Thank you Conforums members.
Cross-platform BBC BASIC (Windows, Linux x86, Mac OS-X, Android, iOS, Raspberry Pi)
Snow Scene animation
« Thread started 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
« Reply #1 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.
Re: Snow Scene animation
« Reply #2 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.
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
« Reply #4 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