Over on a BBC BASIC forum, some guy calling himself 'Repton' posted the following:
Quote
using draw commands how would this example be replicated
Here, he's referring to BBC BASIC native graphics commands (MOVE, DRAW, LINE, etc.).
Anyway, I took up his little challenge - it was easy enough, and the result looks kinda nice:
Here's the code (for completeness):
*HEX 64
WinW% = 800
WinH% = 600
VDU 23, 22, WinW%; WinH%; 8, 16, 16, 0 : OFF
VDU 23,23,8| : REM set line thickness
IF POS
delay% = 32
min_d% = 8
max_d% = 24
chgColTime% = 0
DIM line{(1) x1, y1, x2, y2, dx1, dy1, dx2, dy2}
FOR I% = 0 TO 1
line{(I%)}.x1 = WinW% * FNrnd(I%)
line{(I%)}.y1 = WinH% * FNrnd(I%)
line{(I%)}.x2 = WinW% * FNrnd(I%)
line{(I%)}.y2 = WinH% * FNrnd(I%)
line{(I%)}.dx1 = FNd(I%)
line{(I%)}.dy1 = FNd(I%)
line{(I%)}.dx2 = FNd(I%)
line{(I%)}.dy2 = FNd(I%)
NEXT I%
TIME = 0
*REFRESH OFF
REPEAT
IF TIME >= chgColTime% THEN
PROCSetRandomColour
chgColTime% = TIME + 100 + RND(400)
ENDIF
FOR I% = 0 TO 1
IF I% = 0 OR (I% = 1 AND delay% = 0) THEN
IF I% = 0 THEN GCOL 3,1 ELSE GCOL 0
LINE 2*line{(I%)}.x1, 2*line{(I%)}.y1, 2*line{(I%)}.x2, 2*line{(I%)}.y2
LINE 2*line{(I%)}.y1, 2*line{(I%)}.x1, 2*line{(I%)}.y2, 2*line{(I%)}.x2
LINE 2*(WinW%-line{(I%)}.x1), 2*line{(I%)}.y1, 2*(WinW%-line{(I%)}.x2), 2*line{(I%)}.y2
LINE 2*(WinW%-line{(I%)}.y1), 2*line{(I%)}.x1, 2*(WinW%-line{(I%)}.y2), 2*line{(I%)}.x2
LINE 2*line{(I%)}.x1, 2*(WinH%-line{(I%)}.y1), 2*line{(I%)}.x2, 2*(WinH%-line{(I%)}.y2)
LINE 2*line{(I%)}.y1, 2*(WinH%-line{(I%)}.x1), 2*line{(I%)}.y2, 2*(WinH%-line{(I%)}.x2)
LINE 2*(WinW%-line{(I%)}.x1), 2*(WinH%-line{(I%)}.y1), 2*(WinW%-line{(I%)}.x2), 2*(WinH%-line{(I%)}.y2)
LINE 2*(WinW%-line{(I%)}.y1), 2*(WinH%-line{(I%)}.x1), 2*(WinW%-line{(I%)}.y2), 2*(WinH%-line{(I%)}.x2)
line{(I%)}.x1 += line{(I%)}.dx1
line{(I%)}.y1 += line{(I%)}.dy1
line{(I%)}.x2 += line{(I%)}.dx2
line{(I%)}.y2 += line{(I%)}.dx2
IF line{(I%)}.x1 < 0 line{(I%)}.x1 = 0 : line{(I%)}.dx1 = -FNd(I%) * SGNline{(I%)}.dx1
IF line{(I%)}.x1 > WinW% line{(I%)}.x1 = WinW% : line{(I%)}.dx1 = -FNd(I%) * SGNline{(I%)}.dx1
IF line{(I%)}.x2 < 0 line{(I%)}.x2 = 0 : line{(I%)}.dx2 = -FNd(I%) * SGNline{(I%)}.dx2
IF line{(I%)}.x2 > WinW% line{(I%)}.x2 = WinW% : line{(I%)}.dx2 = -FNd(I%) * SGNline{(I%)}.dx2
IF line{(I%)}.y1 < 0 line{(I%)}.y1 = 0 : line{(I%)}.dy1 = -FNd(I%) * SGNline{(I%)}.dy1
IF line{(I%)}.y1 > WinH% line{(I%)}.y1 = WinH% : line{(I%)}.dy1 = -FNd(I%) * SGNline{(I%)}.dy1
IF line{(I%)}.y2 < 0 line{(I%)}.y2 = 0 : line{(I%)}.dy2 = -FNd(I%) * SGNline{(I%)}.dy2
IF line{(I%)}.y2 > WinH% line{(I%)}.y2 = WinH% : line{(I%)}.dy2 = -FNd(I%) * SGNline{(I%)}.dy2
ENDIF
NEXT I%
IF delay% > 0 delay% -= 1
*REFRESH
WAIT 8
UNTIL FALSE
END
DEF PROCSetRandomColour
CASE RND(14) OF
WHEN 1 : COLOUR 1, 255, 0, 0
WHEN 2 : COLOUR 1, 0, 255, 0
WHEN 3 : COLOUR 1, 0, 0, 255
WHEN 4 : COLOUR 1, 255, 0, 255
WHEN 5 : COLOUR 1, 255, 255, 0
WHEN 6 : COLOUR 1, 0, 255, 255
WHEN 7 : COLOUR 1, 255, 127, 0
WHEN 8 : COLOUR 1, 255, 0, 127
WHEN 9 : COLOUR 1, 127, 255, 0
WHEN 10 : COLOUR 1, 127, 0, 255
WHEN 11 : COLOUR 1, 0, 127, 255
WHEN 12 : COLOUR 1, 255, 127, 127
WHEN 13 : COLOUR 1, 127, 255, 127
WHEN 14 : COLOUR 1, 127, 127, 255
ENDCASE
ENDPROC
DEF FNd(I%) = min_d% + (max_d% - min_d%) * FNrnd(I%)
DEF FNrnd(I%)
PRIVATE F%, S%%() : DIM S%%(1)
IF NOT F% THEN
S%%(0) = RND OR (RND << 31)
S%%(1) = S%%(0)
F% = TRUE
ENDIF
S%%(I%) EOR= S%%(I%) << 13
S%%(I%) EOR= S%%(I%) >>> 17
S%%(I%) EOR= S%%(I%) << 5
= (S%%(I%) AND &FFFFFFFF) / &FFFFFFFF
Notice the 'custom' Xorshift RNG at the end (courtesy of the late George Marsaglia).
BasicBoy.
--
Good old kaleidoscope line effect in action ;D
Lol, I was going to comment that the 1st video was more like a C64 until I looked at the YouTube title :P - Yours run faster and looks more fancy.
Nice I am fan of this kind of stuff and Richard Russell :)
Since kaleidoscopes have been mentioned, here's a
semi-realistic one (done rather inefficiently it must be said) :D
The program runs faster/smoother than the video would suggest, but recording stuff at 60 fps on my laptop doesn't work too well due to on-the-fly system encryption which slows HD writes a bit.
REM Semi-Realistic Kaleidoscope
REM Requires BB4W & GfxLib2
REM
REM Note that this program uses a *very* inefficient means of achieving a kaleidoscope effect!
*ESC OFF
MODE 8 : OFF
ScrW% = 640
ScrH% = 512
INSTALL @lib$ + "GFXLIB2.BBC"
PROCInitGFXLIB(g{}, 0)
DIM g2{} = g{}
g2{} = g{}
INSTALL @lib$+"GFXLIB_modules\ClrLG.bbc" : PROCInitModule(0)
INSTALL @lib$+"GFXLIB_modules\DrawFilledCircle.bbc" : PROCInitModule(0)
INSTALL @lib$+"GFXLIB_modules\BPlotRotateScale2.bbc" : PROCInitModule(0)
INSTALL @lib$+"GFXLIB_modules\PlotRotateScale2.bbc" : PROCInitModule(0)
INSTALL @lib$+"GFXLIB_modules\Copy.bbc" : PROCInitModule(0)
INSTALL @lib$+"GFXLIB_modules\BPlotFlip.bbc" : PROCInitModule(0)
INSTALL @lib$+"GFXLIB_modules\PlotFlip.bbc" : PROCInitModule(0)
INSTALL @lib$+"GFXLIB_modules\ReplaceColour.bbc" : PROCInitModule(0)
nDiscs% = 100
DIM disc{( nDiscs%-1 ) move%, x, y, r, x2, y2, dx, dy, rgb}
imgSz% = 512
img% = FNmalloc(4 * imgSz%^2)
maskSz% = 256
maskBm% = FNmalloc(4 * maskSz%^2)
bm1Sz% = 256
bm1% = FNmalloc(4 * bm1Sz%^2)
bm2Sz% = 256
bm2% = FNmalloc(4 * bm2Sz%^2)
REM Create equilateral triangle mask bitmap:
SYS GFXLIB_SaveAndSetDispVars%, g{}, maskBm%, maskSz%, maskSz%
FOR Y% = 0 TO maskSz%-1
w = Y%*TANRAD30
IF w <= maskSz%/2 THEN
SYS GFXLIB_Line%, g{}, 0, Y%, maskSz%/2-w, Y%, &808080
SYS GFXLIB_Line%, g{}, maskSz%/2+w, Y%, maskSz%-1, Y%, &808080
ELSE
SYS GFXLIB_Line%, g{}, 0, Y%, maskSz%-1, Y%, &808080
ENDIF
NEXT Y%
SYS GFXLIB_RestoreDispVars%, g{}
REM Initialise discs:
FOR I% = 0 TO nDiscs%-1
disc{(I%)}.move% = FALSE
disc{(I%)}.x = RND(ScrW%)
disc{(I%)}.y = RND(ScrH%)
disc{(I%)}.r = 8 + RND(20)
CASE RND(12) OF
WHEN 1 : disc{(I%)}.rgb = &FF0000
WHEN 2 : disc{(I%)}.rgb = &00FF00
WHEN 3 : disc{(I%)}.rgb = &0000FF
WHEN 4 : disc{(I%)}.rgb = &FF00FF
WHEN 5 : disc{(I%)}.rgb = &FFFF00
WHEN 6 : disc{(I%)}.rgb = &00FFFF
WHEN 7 : disc{(I%)}.rgb = &FF8000
WHEN 8 : disc{(I%)}.rgb = &0080FF
WHEN 9 : disc{(I%)}.rgb = &00FF80
WHEN 10 : disc{(I%)}.rgb = &80FF00
WHEN 11 : disc{(I%)}.rgb = &8080FF
WHEN 12 : disc{(I%)}.rgb = &FFFFFF
ENDCASE
NEXT I%
TIME = 0
moveDiscsTime% = 500
*REFRESH OFF
REPEAT
T% = TIME
REM Rotational angle of discs bitmap:
angle = 720*SIN(T%/1000 + PI/5*SIN(T%/1050+0.345))*SIN(T%/950 + PI/8*SIN(T%/800-1.25))
REM Draw discs and update their positions:
SYS GFXLIB_SaveAndSetDispVars%, g{}, img%, imgSz%, imgSz%
SYS GFXLIB_Clr%, g{}, 0
FOR I% = 0 TO nDiscs%-1
SYS GFXLIB_DrawFilledCircle%, g{}, disc{(I%)}.x, disc{(I%)}.y, disc{(I%)}.r+3, &010101
SYS GFXLIB_DrawFilledCircle%, g{}, disc{(I%)}.x, disc{(I%)}.y, disc{(I%)}.r, disc{(I%)}.rgb
IF disc{(I%)}.move% THEN
disc{(I%)}.x += disc{(I%)}.dx
disc{(I%)}.y += disc{(I%)}.dy
IF (disc{(I%)}.x - disc{(I%)}.x2)^2 + (disc{(I%)}.y - disc{(I%)}.y2)^2 < 0.5^2 THEN
disc{(I%)}.move% = FALSE
ENDIF
ENDIF
NEXT I%
SYS GFXLIB_RestoreDispVars%, g{}
REM If it's time to move the discs, then set new target positions:
IF TIME > moveDiscsTime% THEN
FOR I% = 0 TO nDiscs%-1
disc{(I%)}.move% = TRUE
disc{(I%)}.x2 = RND(ScrW%)
disc{(I%)}.y2 = RND(ScrH%)
dx = disc{(I%)}.x2 - disc{(I%)}.x
dy = disc{(I%)}.y2 - disc{(I%)}.y
len = SQR( dx^2 + dy^2 )
disc{(I%)}.dx = dx / len
disc{(I%)}.dy = dy / len
NEXT I%
moveDiscsTime% = TIME + 1000 + RND(1000)
ENDIF
REM Draw the rotating disc image bitmap:
SYS GFXLIB_BPlotRotateScale2%, g{}, img%, imgSz%, imgSz%, ScrW%/2, ScrH%/2, &10000*angle, &10000
REM Draw the equilateral triangle mask bitmap:
SYS GFXLIB_Plot%, g{}, maskBm%, maskSz%, maskSz%, (ScrW%-maskSz%)/2, ScrH%/2
REM Copy mask bitmap to a temp buffer (bm1%):
SYS GFXLIB_SaveAndSetDispVars%, g2{}, bm1%, bm1Sz%, bm1Sz%
SYS GFXLIB_Copy%, g{}, g2.bmBuffAddr%, g2.bmBuffW%, g2.bmBuffH%, (ScrW%-maskSz%)/2, ScrH%/2
SYS GFXLIB_RestoreDispVars%, g2{}
REM Replace the grey masking colour with black:
SYS GFXLIB_ReplaceColour%, bm1%, bm1Sz%, bm1Sz%, &808080, &000000
REM Copy a vertically flipped version of bm1 into bm2:
SYS GFXLIB_SaveAndSetDispVars%, g{}, bm2%, bm2Sz%, bm2Sz%
SYS GFXLIB_BPlotFlip%, g{}, bm1%, bm1Sz%, bm1Sz%, 0, 0, 1
SYS GFXLIB_RestoreDispVars%, g{}
REM Clear the window (actually fill it with a colour gradient):
SYS GFXLIB_ClrLG%, g{}, &208020, &202080
REM Draw top thee equilateral triangle bitmaps:
SYS GFXLIB_Plot%, g{}, bm1%, bm1Sz%, bm1Sz%, (ScrW%-maskSz%)/2, ScrH%/2
SYS GFXLIB_PlotRotateScale2%, g{}, bm2%, bm2Sz%, bm2Sz%, ScrW%/2+108, ScrH%/2+65, 60*&10000, &10000
SYS GFXLIB_PlotRotateScale2%, g{}, bm2%, bm2Sz%, bm2Sz%, ScrW%/2-109, ScrH%/2+65,-60*&10000, &10000
REM Draw the bottom three:
SYS GFXLIB_PlotFlip%, g{}, bm1%, bm1Sz%, bm1Sz%, (ScrW%-maskSz%)/2, 5, 2
SYS GFXLIB_PlotRotateScale2%, g{}, bm1%, bm1Sz%, bm1Sz%, ScrW%/2+108, ScrH%/2-60, (180-60)*&10000, &10000
SYS GFXLIB_PlotRotateScale2%, g{}, bm1%, bm1Sz%, bm1Sz%, ScrW%/2-109, ScrH%/2-60, (180+60)*&10000, &10000
REM Draw enclosing hexagon:
FOR R% = 256 TO 258
FOR I% = 0 TO 5
x1 = 319 + R%*COSRAD(60 * I%)
y1 = 258 + R%*SINRAD(60 * I%)
x2 = 319 + R%*COSRAD(60 * (I%+1))
y2 = 258 + R%*SINRAD(60 * (I%+1))
SYS GFXLIB_Line%, g{}, x1, y1, x2, y2, &000001
NEXT I%
NEXT R%
PROCdisplay
UNTIL FALSE
BasicBoy.
--
Ah! seems like you are a step away from a snowflake generator. :)