04-09-2024, 09:52 PM
Well, I went a little bit crazy with the DRAW statement.
Code: (Select All)
OPTION _EXPLICIT
'---------------------------------
' DRAW example - DrawClock.BAS
' Displays a working analog clock
' by Terry Ritchie - 04/07/24
'---------------------------------
' Note: The entire clock will auto adjust its size based on the SIZE value below
CONST SIZE% = 500 ' screen size (must be 200 or larger)
'+---------------+
'| Define colors |
'+---------------+
CONST WHITE~& = _RGB32(255, 255, 255) ' bright white
CONST BLACK~& = _RGB32(0, 0, 0) ' black
CONST GRAY~& = _RGB32(127, 127, 127) ' gray
CONST DARKGRAY~& = _RGB32(63, 63, 63) ' dark gray
CONST OFFWHITE1~& = _RGB32(255, 254, 255) ' slightly off bright white
CONST OFFWHITE2~& = _RGB32(254, 255, 255) ' slightly off bright white
CONST RED~& = _RGB32(255, 0, 0) ' bright red
CONST OFFRED~& = _RGB32(254, 0, 0) ' slightly off bright red
'+------------------------------+
'| Variable declaration section |
'+------------------------------+
DIM TOx%(360) ' outer tick mark x coordinate
DIM TOy%(360) ' outer tick mark y coordinate
DIM TIx%(360) ' inner tick mark x coordinate
DIM TIy%(360) ' inner tick mark y coordinate
DIM Hx%(360) ' hour and second hand x coordinate
DIM Hy%(360) ' hour and second hand y coordinate
DIM Mx%(360) ' minute hand x coordinate
DIM My%(360) ' minute hand y coordinate
DIM Ex%(360) ' hand opposite end x coordinate
DIM Ey%(360) ' hand opposite end y coordinate
DIM ClockFace& ' image of clock face
DIM Angle% ' 360 degree angle counter
DIM Aa% ' absolute value of a negative angle
DIM Center% ' center coordinate of clock face
DIM CenterPen$ ' pen center point of clock face
DIM OuterTick$ ' line extended out to outer tick mark
DIM HourTick$ ' line extended out to hour hand mark
DIM InnerTick$ ' line extended out to inner tick mark
DIM MinuteTick$ ' line extended out to minute and second hand mark
DIM EndTick$ ' line extended out to the hand opposite end amrk
DIM Square$ ' DRAW directive to draw a square
DIM Triangle$ ' DRAW directive to draw a triangle
DIM Aplus1% ' current angle plus 1
DIM Aminus1% ' current angle minus 1
DIM TickColor~& ' color of tick marks around the face perimeter
DIM Hour% ' the current hour value
DIM Minute% ' the current minute value
DIM Second% ' the current second value
DIM OldSecond% ' the previous second value
DIM Scount% ' the current 1/6th of a second
DIM Sdegree% ' degree the second hand points to
DIM Mdegree% ' degree the minute hand points to
DIM Hdegree% ' degree the hour hand points to
DIM Minus180% ' the opposite degree of any hand
DIM l% ' the standard length of a DRAW line
DIM L1$ ' string form of l%
DIM L2$ ' string form of l% * 2
IF SIZE% < 200 THEN ' clock window too small?
PRINT ' yes
PRINT " SIZE of clock must be 200 or greater" ' report error to user
END ' end program
END IF
ClockFace& = _NEWIMAGE(SIZE, SIZE, 32) ' an image to hold the clock's face
'+---------------------------------------------------------+
'| Calculate the DRAW line lengths based on SIZE of window |
'+---------------------------------------------------------+
l% = INT(SIZE / 100) ' standard length of DRAW line
L1$ = STR$(l%) ' string form of standard DRAW line length
L2$ = STR$(l% * 2) ' string form of twice the length of the draw line
'+------------------------------------------------+
'| Create the square and triangle DRAW directives |
'+------------------------------------------------+
Square$ = "U" + L1$ + "R" + L1$ + "D" + L2$ + "L" + L2$ + "U" + L2$ + "R" + L1$ + "BD" + STR$(l% + 1)
Triangle$ = "F" + L2$ + "L" + STR$(l% * 4) + "E" + L2$ + "BD" + L1$
'+------------------------------------------------------+
'| Create the coordinate locations using DRAW and POINT |
'| (No math! No trigonometry! COS and SIN be damned! |
'+------------------------------------------------------+
Center% = SIZE \ 2 - 1 ' calculate center of clock face coordinates
CenterPen$ = "BM" + STR$(Center%) + "," + STR$(Center%) ' DRAW directive to center pen on clock face
OuterTick$ = CenterPen$ + "U" + STR$(INT(SIZE * .45)) ' DRAW directive to extend outer tick line (90%)
HourTick$ = CenterPen$ + "U" + STR$(INT(SIZE * .30)) ' DRAW directive to extend hour hand line (60%)
InnerTick$ = CenterPen$ + "U" + STR$(INT(SIZE * .43)) ' DRAW directive to extend inner tick line (86%)
MinuteTick$ = CenterPen$ + "U" + STR$(INT(SIZE * .44)) ' DRAW directive to extend minute and second hand line (88%)
EndTick$ = CenterPen$ + "U" + STR$(INT(SIZE * .05)) ' DRAW directive to extend opposite hand endpoint line ( 5%)
_DEST ClockFace& ' draw on clock face image in background
_SOURCE ClockFace& ' get coordinates from clock face image
FOR Angle% = 0 TO -359 STEP -1 ' cycle clockwise through 360 degrees
Aa% = ABS(Angle%) ' the absolute value of the angle
DRAW "TA" + STR$(Angle%) ' rotate the pen by the current angle
DRAW OuterTick$ ' extend line to outer tick mark
TOx%(Aa%) = POINT(0) ' get the endpoint coordinates of the line
TOy%(Aa%) = POINT(1) ' these are the outer tick mark coordinates
DRAW HourTick$ ' extend line to hour and second hand mark
Hx%(Aa%) = POINT(0) ' get the endpoint coordinates of the line
Hy%(Aa%) = POINT(1) ' these are the hour and second hand coordinates
DRAW InnerTick$ ' extend line to inner tick mark
TIx%(Aa%) = POINT(0) ' get the endpoint coordinates of the line
TIy%(Aa%) = POINT(1) ' these are the inner tick mark coordinates
DRAW MinuteTick$ ' extend line to minute hand mark
Mx%(Aa%) = POINT(0) ' get the endpoint coordinates of the line
My%(Aa%) = POINT(1) ' these are the minute hand coordinates
DRAW EndTick$ ' extend line to opposite hand endpoint
Ex%(Aa%) = POINT(0) ' get the endpoint coordinates of the line
Ey%(Aa%) = POINT(1) ' these are the hand's opposite side coordinates
NEXT Angle% ' leave loop when angle is -359
CLS ' clear the clock face image
'+-----------------------------------------------+
'| Draw the clock face onto the clock face image |
'+-----------------------------------------------+
CIRCLE (Center%, Center%), SIZE * .46, GRAY ' draw outer edge of tick mark boundary (92%)
CIRCLE (Center%, Center%), SIZE * .42, GRAY ' draw inner edge of tick mark boundary (84%)
PAINT (Mx%(0), My%(0)), GRAY, GRAY ' paint the tick mark area
CIRCLE (Center%, Center%), SIZE * .46, WHITE ' draw the outer edge of the clock face (92%)
FOR Angle% = 0 TO 359 STEP 6 ' cycle through 360 degrees at one second intervals
IF Angle% MOD 30 = 0 THEN ' is this an hour mark?
TickColor~& = WHITE ' yes, make it white
ELSE ' no
TickColor~& = BLACK ' make it black
END IF
Aplus1% = Angle% + 1 ' get the angle just above
Aminus1% = Angle% - 1 ' get the angle just below
IF Aplus1% = 360 THEN Aplus1% = 0 ' correct for angle too high
IF Aminus1% = -1 THEN Aminus1% = 359 ' correct for angle too low
PSET (TOx%(Aminus1%), TOy%(Aminus1%)), TickColor~& ' set graphics cursor location
LINE -(TOx%(Aplus1%), TOy%(Aplus1%)), TickColor~& ' draw tick mark box
LINE -(TIx%(Aplus1%), TIy%(Aplus1%)), TickColor~&
LINE -(TIx%(Aminus1%), TIy%(Aminus1%)), TickColor~&
LINE -(TOx%(Aminus1%), TOy%(Aminus1%)), TickColor~&
PAINT (Mx%(Angle%), My%(Angle%)), TickColor~&, TickColor~& ' paint the tick mark box
NEXT Angle% ' leave loop when angle is 359
PAINT (Center%, Center%), DARKGRAY, GRAY ' paint the inner clock face
'+--------------------+
'| Begin main program |
'+--------------------+
SCREEN _NEWIMAGE(SIZE, SIZE, 32) ' enter a graphics screen
DO ' begin main program loop
_LIMIT 6 ' 6 degrees per second (1/6th of second)
_PUTIMAGE (0, 0), ClockFace& ' use clock face image to clear screen
'+-------------------------------------------------------+
'| Calculate hand rotation degrees from the current time |
'+-------------------------------------------------------+
OldSecond% = Second% ' record the previous second value
Hour% = VAL(LEFT$(TIME$, 2)) ' get the value of the current hour
Minute% = VAL(MID$(TIME$, 4, 2)) ' get the value of the current minute
Second% = VAL(RIGHT$(TIME$, 2)) ' get the value of the current second
IF Hour% >= 12 THEN Hour% = Hour% - 12 ' remove military time
Scount% = Scount% + 1 ' increment 1/6th second counter
IF OldSecond% <> Second% THEN ' has a second passed?
Scount% = 0 ' yes, reset counter
SOUND 1660, .05 ' tick sound
END IF
Sdegree% = Second% * 6 + Scount% ' calculate the second hand degree
Mdegree% = Minute% * 6 + INT(Second% / 12) ' calculate the minute hand degree
Hdegree% = Hour% * 30 + INT(Minute% / 2) ' calculate the hour hand degree
'+--------------------+
'| Draw the hour hand |
'+--------------------+
Minus180% = Hdegree% - 180 ' calculate the hour hand opposite degree
IF Minus180% < 0 THEN Minus180% = 360 + Minus180% ' keep the degree a positive value
LINE (Center%, Center%)-(Hx%(Hdegree%), Hy%(Hdegree%)), WHITE ' draw the hour hand
DRAW "TA" + STR$(-Hdegree%) ' rotate pen to same degree as hour hand
DRAW "C" + STR$(OFFWHITE1) + Triangle$ ' draw an off white triangle at end of hand
DRAW "P" + STR$(OFFWHITE1) + "," + STR$(OFFWHITE1) ' paint the triangle off white
LINE (Center%, Center%)-(Ex%(Minus180%), Ey%(Minus180%)), WHITE ' draw the hour hand opposite side
DRAW "TA" + STR$(-Hdegree%) ' rotate pen to same degree as hour hand
DRAW "C" + STR$(OFFWHITE1) + Square$ ' draw an off white square at opposite end
DRAW "P" + STR$(OFFWHITE1) + "," + STR$(OFFWHITE1) ' paint the square off white
'+----------------------+
'| Draw the minute hand |
'+----------------------+
Minus180% = Mdegree% - 180 ' calculate the minute hand opposite degree
IF Minus180% < 0 THEN Minus180% = 360 + Minus180% ' keep the degree a positive value
LINE (Center%, Center%)-(TIx%(Mdegree%), TIy%(Mdegree%)), WHITE ' draw the minute hand
DRAW "TA" + STR$(-Mdegree%) ' rotate pen to same degree as minute hand
DRAW "C" + STR$(OFFWHITE2) + Triangle$ ' draw an off white triangle at end of hand
DRAW "P" + STR$(OFFWHITE2) + "," + STR$(OFFWHITE2) ' paint the triangle off white
LINE (Center%, Center%)-(Ex%(Minus180%), Ey%(Minus180%)), WHITE ' draw the minute hand opposite side
DRAW "TA" + STR$(-Mdegree%) ' rotate pen to same degree as minute hand
DRAW "C" + STR$(OFFWHITE2) + Square$ ' draw an off white square at opposite end
DRAW "P" + STR$(OFFWHITE2) + "," + STR$(OFFWHITE2) ' paint the square off white
'+----------------------+
'| Draw the second hand |
'+----------------------+
Minus180% = Sdegree% - 180 ' calculate the second hand opposite degree
IF Minus180% < 0 THEN Minus180% = 360 + Minus180% ' keep the degree a positive value
LINE (Center%, Center%)-(TIx%(Sdegree%), TIy%(Sdegree%)), RED ' draw the second hand
DRAW "TA" + STR$(-Sdegree%) ' rotate pen to same degree as second hand
DRAW "C" + STR$(OFFRED) + Triangle$ ' draw an off red triangle at end of hand
DRAW "P" + STR$(OFFRED) + "," + STR$(OFFRED) ' paint the triangle off red
LINE (Center%, Center%)-(Ex%(Minus180%), Ey%(Minus180%)), RED ' draw the second hand opposite side
CIRCLE STEP(0, 0), l%, OFFRED ' draw an off red circle at opposite end
PAINT STEP(0, 0), OFFRED, OFFRED ' paint the circle off red
'+----------------------+
'| Draw the center post |
'+----------------------+
CIRCLE (Center%, Center%), l% * 2, BLACK ' draw a black circle at center of screen
PAINT (Center%, Center%), BLACK, BLACK ' paint the circle black
CIRCLE (Center%, Center%), l%, DARKGRAY ' draw a dark gray circle at center of screen
_DISPLAY ' update the screen with changes
LOOP UNTIL _KEYDOWN(27) ' leave main loop when ESC key pressed
_FREEIMAGE ClockFace& ' remove clock face image from RAM
SYSTEM ' return to the operating system