QB64.org Forum

Active Forums => Programs => Topic started by: Cobalt on July 19, 2020, 12:23:49 pm

Title: The Cobalt Spinner
Post by: Cobalt on July 19, 2020, 12:23:49 pm
An animated spinner made from the image uploaded by @johnno56 on this topic: https://www.qb64.org/forum/index.php?topic=2818.0

Made using a very simple Brute Force approach by rotating the image by hand for a full rotation. This spins with a 4 degree rotation each frame, I thought about a 1 degree rotation but the overall sheet size would have been massive! even at 4 degrees there are 90 images covering 3600x3240 pixels resulting in a 34meg Bitmap, even JPG is over 4megs. (oddly enough PNG was 17megs!) so I don't even want to think what 360 images would have wound up being.

though using JPG wont work, so the spinners are saved as GIF. Not my favorite format for something like this but ah well.

Press ESC to stop the spinner.

Code: QB64: [Select]
  1. 'The Cobalt Spinner
  2. 'A World War 2 "Substitute Die Spinner" Animation simulator
  3. 'July 19, 2020
  4. 'Cobalt
  5.  
  6. DIM SHARED Layer(4) AS LONG
  7. CONST TRUE = -1, FALSE = NOT TRUE
  8. SCREEN _NEWIMAGE(640, 525, 32)
  9. Layer(0) = _DISPLAY
  10. Layer(1) = _NEWIMAGE(640, 525, 32)
  11. Layer(2) = _LOADIMAGE("BoardGameSpinner_MonopolyWW2era_BaseA.jpg", 32) 'I like this base better!
  12. 'Layer(3) = _LOADIMAGE("BoardGameSpinner_MonopolyWW2era_Base.bmp", 32)
  13. Layer(4) = _LOADIMAGE("BoardGameSpinner_MonopolyWW2era.GIF", 32) '90 Hand Rotated Images!!!!
  14. _CLEARCOLOR _RGB32(5), Layer(4)
  15.  
  16. Frame%% = 0 'Start at base rotation
  17. Speed%% = 90 'speed of rotation(~1rps at 90)
  18.  _PUTIMAGE (0, 0), Layer(2), Layer(1) 'place the board
  19.  'Place the spinner image using a bit of math
  20.  _PUTIMAGE (13, 85)-STEP(359, 359), Layer(4), Layer(1), (0 + 360 * (Frame%% MOD 10), 0 + 360 * INT(Frame%% \ 10))-STEP(359, 359)
  21.  _PUTIMAGE , Layer(1), Layer(0) 'copy the mix layer to the display
  22.  _LIMIT Speed%% 'control how fast things go. This is not a good way but it works
  23.  Frame%% = Frame%% + 1 'change the spinner image
  24.  IF Frame%% = 90 THEN Frame%% = 0 'reset spinner image when we get to the end of animation
  25.  IF INKEY$ = CHR$(27) THEN Trigger%% = TRUE 'start the slowing process
  26.  IF Trigger%% THEN Speed%% = Speed%% - 1 'Slow the spinner down
  27.  IF Speed%% = 2 THEN ExitFlag%% = TRUE 'stop the spinner!
  28. LOOP UNTIL ExitFlag%%
  29.  
  30. 'At this point you could check which frame it is on and know what number(s) were spun!

the BaseA background I think works a bit better due to the slightly off round spinner due to the angle of the photo, which was VERY close but not perfect. As such there is a slight wobble to the spin. I also didn't adjust the light reflection off the center rivet, so if your watching it and thinking something is just not right that would probably be whats bugging you.
Title: Re: The Cobalt Spinner
Post by: Cobalt on July 19, 2020, 02:28:09 pm
Okay, added the result side of things. Now my numbers say I should be off somewhere because I'm missing a 1,5 result somewhere but
I haven't seen it yet.

Code: QB64: [Select]
  1. 'The Cobalt Spinner
  2. 'A World War 2 "Substitute Die Spinner" Animation simulator
  3. 'July 19, 2020
  4. 'Cobalt
  5.  
  6. TYPE Results
  7.  Small AS _BYTE
  8.  Large AS _BYTE
  9.  
  10. DIM SHARED Layer(4) AS LONG, Result(89) AS Results
  11.  
  12. CONST TRUE = -1, FALSE = NOT TRUE
  13.  
  14. SCREEN _NEWIMAGE(640, 525, 32)
  15. Layer(0) = _DISPLAY
  16. Layer(1) = _NEWIMAGE(640, 525, 32)
  17. Layer(2) = _LOADIMAGE("BoardGameSpinner_MonopolyWW2era_BaseA.jpg", 32) 'I like this base better!
  18. Layer(4) = _LOADIMAGE("BoardGameSpinner_MonopolyWW2era.gif", 32) '90 Hand Rotated Images!!!!
  19. _CLEARCOLOR _RGB32(5), Layer(4)
  20.  
  21. DATA 1,5,5,3,3,4,4,4,2,2,6,6,6,1,1,1,5,5,3,3,3,4,4,2,2,2,6,6,1,1,1,5,5,3,3,3,4,4,2,2,2,6,6,1,1,1
  22. DATA 5,5,3,3,3,4,4,4,2,2,6,6,1,1,1,5,5,3,3,3,4,4,2,2,2,6,6,6,1,1,1,5,5,3,3,4,4,4,2,2,6,6,6,1: ',1  there is a number off somewhere here
  23. DATA 5,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
  24. DATA 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5
  25. FOR i%% = 0 TO 89
  26.  READ Result(i%%).Small
  27. NEXT i%%
  28. FOR i%% = 0 TO 89
  29.  READ Result(i%%).Large
  30. NEXT i%%
  31.  
  32. frame%% = 0 'Start at base rotation
  33. Speed%% = 90 'speed of rotation(~1rps at 90)
  34. Start! = TIMER
  35. tim! = RND * 5 + 1
  36.  _PUTIMAGE (0, 0), Layer(2), Layer(1) 'place the board
  37.  'Place the spinner image using a bit of math
  38.  _PUTIMAGE (13, 85)-STEP(359, 359), Layer(4), Layer(1), (1 + 360 * (frame%% MOD 10), 0 + 360 * INT(frame%% \ 10))-STEP(359, 359)
  39.  _PUTIMAGE (0, 0), Layer(1), Layer(0) 'copy the mix layer to the display
  40.  _LIMIT Speed%% 'control how fast things go. This is not a good way but it works
  41.  frame%% = frame%% + 1 'change the spinner image
  42.  IF frame%% = 90 THEN frame%% = 0 'reset spinner image when we get to the end of animation
  43.  IF INKEY$ = CHR$(27) THEN ExitFlag%% = TRUE ' In case something somewhere goes wrong ESC to quit
  44.  IF (NOT trigger) AND TIMER >= Start + tim! THEN trigger%% = TRUE 'start the slowing process
  45.  IF trigger%% THEN Speed%% = Speed%% - 1 'Slow the spinner down
  46.  IF Speed%% = 2 THEN ExitFlag%% = TRUE 'stop the spinner!
  47. LOOP UNTIL ExitFlag%%
  48.  
  49. '----------------------Final frame update---------------------
  50. _PUTIMAGE (0, 0), Layer(2), Layer(1) 'place the board
  51. 'Place the spinner image using a bit of math
  52. _PUTIMAGE (13, 85)-STEP(359, 359), Layer(4), Layer(1), (1 + 360 * (frame%% MOD 10), 0 + 360 * INT(frame%% \ 10))-STEP(359, 359)
  53. _PUTIMAGE (0, 0), Layer(1), Layer(0) 'copy the mix layer to the display
  54. '-------------------------------------------------------------
  55.  
  56. 'At this point you could check which frame it is on and know what number(s) were spun!
  57. LOCATE 1, 55: PRINT "Spin Time"; INT(tim! * 1000) / 1000
  58. LOCATE 2, 55: PRINT "Frame:"; frame%%
  59. LOCATE 3, 55: PRINT "Large:"; Result(frame%%).Large
  60. LOCATE 4, 55: PRINT "Small"; Result(frame%%).Small
  61. LOCATE 5, 55: PRINT "Total:"; Result(frame%%).Large + Result(frame%%).Small
  62.  
Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 02:45:48 pm
Very nice Cobalt! You might want to keep it going though and let people spin as many times as they want with the mouse or space bar. I like how you made frames for the animation. I think there's a way to turn the pictures without using frames. I think B+ found a way awhile back when he made it so an image would turn 90 degrees before it prints on the printer. But I'm not sure if that would be a good spinner or not. I just saw his animation a couple times last year.
Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 02:47:48 pm
This also makes me wonder if QB64 can animate an animated GIF?
Title: Re: The Cobalt Spinner
Post by: FellippeHeitor on July 19, 2020, 02:57:22 pm
Yes http://www.qb64.org/wiki/GIF_Images
Title: Re: The Cobalt Spinner
Post by: bplus on July 19, 2020, 03:30:08 pm
Very nice Cobalt! You might want to keep it going though and let people spin as many times as they want with the mouse or space bar. I like how you made frames for the animation. I think there's a way to turn the pictures without using frames. I think B+ found a way awhile back when he made it so an image would turn 90 degrees before it prints on the printer. But I'm not sure if that would be a good spinner or not. I just saw his animation a couple times last year.

Yes with Rotozoom you would only need one snapshot of the wheel.

The calendar thing just used a _MAPTRIANGLE flip as I recall and would not be enough for spinning.
Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 03:52:29 pm
Thanks B+! The genius of QB64 strikes again! :)

Cobalt, here is a RotoZoom example I just made using my spinner2.png. It rotates non-stop on a DO/LOOP. Here is how to use the SUB:
RotoZoom 200, 200, Image&, 1, angle  'x = 200, y = 200 which will be the center point of the image. Image& is your picture. 1 is the zoom amount I have it set on here 2 would be twice zoomed in. And angle is the angle of rotation. Then put the SUB which is in my code example. 
B+ this is really awesome! I can think of all kinds of things now!

I found the code on the Wiki.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(400, 400, 32)
  2. i& = _NEWIMAGE(400, 400)
  3. i& = _LOADIMAGE("spinner2.png", 32)
  4. PAINT (1, 1), _RGB32(255, 255, 255)
  5.     FOR spin = 1 TO 360
  6.         RotoZoom 200, 200, i&, 1, spin 'Angle
  7.         _DELAY .02
  8.     NEXT spin
  9.  
  10.  
  11. SUB RotoZoom (X AS LONG, Y AS LONG, Image AS LONG, Scale AS SINGLE, Rotation AS SINGLE)
  12.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  13.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  14.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  15.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  16.     sinr! = SIN(-Rotation / 57.2957795131): cosr! = COS(-Rotation / 57.2957795131)
  17.     FOR i& = 0 TO 3
  18.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * Scale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * Scale + Y
  19.         px(i&) = x2&: py(i&) = y2&
  20.     NEXT
  21.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  22.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  23.  
Title: Re: The Cobalt Spinner
Post by: bplus on July 19, 2020, 04:04:00 pm
There are so many ways to spin a cat!

Has anyone thought how much simpler it would be to just spin an arrow / pointer around the image?

I seem to recall a spinner like that for some childhood game.

BTW nice one Ken, specially speed and simplicity. Just pick a random number for it to stop maybe from 360 to some multiple of 360 say 10*360. Use an arrow to point at selection at True North?
Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 04:32:58 pm
Wow good idea B+, you saw my spinner thread right? Cobalt got this idea from my thread. Yeah I can make like Wheel of Fortune or some game to try and guess a number. :)
Title: Re: The Cobalt Spinner
Post by: SMcNeill on July 19, 2020, 05:16:36 pm
How about a spinner of various die-sidedness?  In many games today, you need 4, 6, 8, 10, 12, 20, 100-sided dice.  One circle, of various rings, with a clockhand in the center, like a compass, could be used for all those results at once.
Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 05:33:30 pm
B+, for some reason it doesn't want to use transparent images, which I would need for the arm to circle around the circle with. At first I tried just a graphic arm but it's a bit beyond me in math.
Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 05:35:55 pm
Steve, that sounds pretty simple using my Game Board Spinner. It would just need a lot of work making various spinner graphics. Anyone is free to check that out. I suggest using the ones it comes with and going on from there so it stays with the same center point.
Title: Re: The Cobalt Spinner
Post by: bplus on July 19, 2020, 07:05:03 pm
B+, for some reason it doesn't want to use transparent images, which I would need for the arm to circle around the circle with. At first I tried just a graphic arm but it's a bit beyond me in math.

I got it working fine but your wheel axle is a little off ;-))

Title: Re: The Cobalt Spinner
Post by: SMcNeill on July 19, 2020, 08:04:01 pm
A Steve Spinner:

Code: QB64: [Select]
  1.  
  2. DIM Numbers(1 TO 100) AS INTEGER
  3.  
  4. SCREEN _NEWIMAGE(640, 640, 32)
  5.  
  6. Texture = _LOADIMAGE("wood.jpg", 32)
  7.  
  8. CircleFill 320, 320, 320, -1
  9.  
  10. FOR x = 0 TO 639: FOR y = 0 TO 639 'Paint the clock our wooden texture to make it pretty...
  11.         IF POINT(x, y) THEN _SOURCE Texture: PSET (x, y), POINT(x, y): _SOURCE 0
  12. NEXT y, x
  13.  
  14.  
  15. Minute = _NEWIMAGE(500, 80, 32)
  16. _DEST Minute
  17. FOR x = 250 TO 450: FOR y = 35 TO 45: PSET (x, y), Black: NEXT y, x
  18. LINE (450, 35)-STEP(0, -5), Black
  19. LINE -STEP(50, 11), Black
  20. LINE -STEP(-50, 10), Black
  21. LINE -STEP(0, -10), Black
  22. PAINT (451, 35), Black
  23. CircleFill 250, 40, 20, Black
  24.  
  25.  
  26. FOR i = 1 TO 100: Numbers(i) = TextToImage(_TRIM$(STR$(i)), 16, Black, 0, 0): NEXT
  27. Numbers(100) = TextToImage("00", 16, Black, 0, 0)
  28.  
  29. COLOR Red, 0
  30. FOR i = 320 TO 75 STEP -35
  31.     FOR j = 0 TO 2 STEP .5 'thickness
  32.         CIRCLE (320, 320), i - j, Black
  33.     NEXT
  34.     SELECT CASE i
  35.         CASE 320: sides = 100
  36.         CASE 285: sides = 20
  37.         CASE 250: sides = 12
  38.         CASE 215: sides = 10
  39.         CASE 180: sides = 8
  40.         CASE 145: sides = 6
  41.         CASE 110: sides = 4
  42.         CASE 75: sides = 2
  43.     END SELECT
  44.     n = 0
  45.     FOR j = 0 TO 359.99 STEP 360 / sides
  46.         n = n + 1
  47.         x = 320 + (i - 15) * COS(_D2R(j - 90))
  48.         y = 320 + (i - 15) * SIN(_D2R(j - 90))
  49.         DisplayImage Numbers(n), x, y, 0, 0
  50.     NEXT
  51. Spinner = ScaleImage(Minute, 1.3, 1)
  52.  
  53.  
  54. PCOPY 0, 1
  55. x = INT(RND * 360)
  56. DisplayImage Spinner, 320, 320, x, 0
  57.  
  58.     DO UNTIL move <= 0
  59.         PCOPY 1, 0
  60.         x = x + move
  61.         move = move - 1
  62.         DisplayImage Spinner, 320, 320, x, 0
  63.         _LIMIT 360 'one full rotation per second
  64.         _DISPLAY
  65.     LOOP
  66.     IF _MOUSEBUTTON(1) OR _KEYDOWN(32) THEN move = INT(RND * 360 * 5) 'up to 5 whole rotations per flick
  67.  
  68.     _LIMIT 30 'no need to use CPU power while just idling for a mouse click
  69.  
  70.  
  71.  
  72.  
  73. SUB DisplayImage (Image AS LONG, x AS INTEGER, y AS INTEGER, angle AS SINGLE, mode AS _BYTE)
  74.     'Image is the image handle which we use to reference our image.
  75.     'x,y is the X/Y coordinates where we want the image to be at on the screen.
  76.     'angle is the angle which we wish to rotate the image.
  77.     'mode determines HOW we place the image at point X,Y.
  78.     'Mode 0 we center the image at point X,Y
  79.     'Mode 1 we place the Top Left corner of oour image at point X,Y
  80.     'Mode 2 is Bottom Left
  81.     'Mode 3 is Top Right
  82.     'Mode 4 is Bottom Right
  83.  
  84.  
  85.     DIM px(3) AS INTEGER, py(3) AS INTEGER, w AS INTEGER, h AS INTEGER
  86.     DIM sinr AS SINGLE, cosr AS SINGLE, i AS _BYTE
  87.     w = _WIDTH(Image): h = _HEIGHT(Image)
  88.     SELECT CASE mode
  89.         CASE 0 'center
  90.             px(0) = -w \ 2: py(0) = -h \ 2: px(3) = w \ 2: py(3) = -h \ 2
  91.             px(1) = -w \ 2: py(1) = h \ 2: px(2) = w \ 2: py(2) = h \ 2
  92.         CASE 1 'top left
  93.             px(0) = 0: py(0) = 0: px(3) = w: py(3) = 0
  94.             px(1) = 0: py(1) = h: px(2) = w: py(2) = h
  95.         CASE 2 'bottom left
  96.             px(0) = 0: py(0) = -h: px(3) = w: py(3) = -h
  97.             px(1) = 0: py(1) = 0: px(2) = w: py(2) = 0
  98.         CASE 3 'top right
  99.             px(0) = -w: py(0) = 0: px(3) = 0: py(3) = 0
  100.             px(1) = -w: py(1) = h: px(2) = 0: py(2) = h
  101.         CASE 4 'bottom right
  102.             px(0) = -w: py(0) = -h: px(3) = 0: py(3) = -h
  103.             px(1) = -w: py(1) = 0: px(2) = 0: py(2) = 0
  104.     END SELECT
  105.     sinr = SIN(angle / 57.2957795131): cosr = COS(angle / 57.2957795131)
  106.     FOR i = 0 TO 3
  107.         x2 = (px(i) * cosr + sinr * py(i)) + x: y2 = (py(i) * cosr - px(i) * sinr) + y
  108.         px(i) = x2: py(i) = y2
  109.     NEXT
  110.     _MAPTRIANGLE (0, 0)-(0, h - 1)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  111.     _MAPTRIANGLE (0, 0)-(w - 1, 0)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  112.  
  113. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  114.     ' CX = center x coordinate
  115.     ' CY = center y coordinate
  116.     '  R = radius
  117.     '  C = fill color
  118.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  119.     DIM X AS INTEGER, Y AS INTEGER
  120.     Radius = ABS(R)
  121.     RadiusError = -Radius
  122.     X = Radius
  123.     Y = 0
  124.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  125.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  126.     WHILE X > Y
  127.         RadiusError = RadiusError + Y * 2 + 1
  128.         IF RadiusError >= 0 THEN
  129.             IF X <> Y + 1 THEN
  130.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  131.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  132.             END IF
  133.             X = X - 1
  134.             RadiusError = RadiusError - X * 2
  135.         END IF
  136.         Y = Y + 1
  137.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  138.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  139.     WEND
  140.  
  141. FUNCTION ScaleImage (Image AS LONG, xscale AS SINGLE, yscale AS SINGLE)
  142.     w = _WIDTH(Image): h = _HEIGHT(Image)
  143.     w2 = w * xscale: h2 = h * yscale
  144.     NewImage& = _NEWIMAGE(w2, h2, 32)
  145.     _PUTIMAGE (0, 0)-(w2 - 1, h2 - 1), Image&, NewImage&, (0, 0)-(w - 1, h - 1)
  146.     ScaleImage = NewImage&
  147.  
  148.  
  149. FUNCTION TextToImage& (text$, font&, fc&, bfc&, mode AS _BYTE)
  150.     'text$ is the text that we wish to transform into an image.
  151.     'font& is the handle of the font we want to use.
  152.     'fc& is the color of the font we want to use.
  153.     'bfc& is the background color of the font.
  154.  
  155.     'Mode 1 is print forwards
  156.     'Mode 2 is print backwards
  157.     'Mode 3 is print from top to bottom
  158.     'Mode 4 is print from bottom up
  159.     'Mode 0 got lost somewhere, but it's OK.  We check to see if our mode is < 1 or > 4 and compensate automatically if it is to make it one (default).
  160.  
  161.     IF mode < 1 OR mode > 4 THEN mode = 1
  162.     dc& = _DEFAULTCOLOR: bgc& = _BACKGROUNDCOLOR
  163.     D = _DEST
  164.     F = _FONT
  165.     IF font& <> 0 THEN _FONT font&
  166.     IF mode < 3 THEN
  167.         'print the text lengthwise
  168.         w& = _PRINTWIDTH(text$): h& = _FONTHEIGHT
  169.     ELSE
  170.         'print the text vertically
  171.         FOR i = 1 TO LEN(text$)
  172.             IF w& < _PRINTWIDTH(MID$(text$, i, 1)) THEN w& = _PRINTWIDTH(MID$(text$, i, 1))
  173.         NEXT
  174.         h& = _FONTHEIGHT * (LEN(text$))
  175.     END IF
  176.  
  177.     TextToImage& = _NEWIMAGE(w&, h&, 32)
  178.     _DEST TextToImage&
  179.     IF font& <> 0 THEN _FONT font&
  180.     COLOR fc&, bfc&
  181.  
  182.     SELECT CASE mode
  183.         CASE 1
  184.             'Print text forward
  185.             _PRINTSTRING (0, 0), text$
  186.         CASE 2
  187.             'Print text backwards
  188.             temp$ = ""
  189.             FOR i = 0 TO LEN(text$) - 1
  190.                 temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
  191.             NEXT
  192.             _PRINTSTRING (0, 0), temp$
  193.         CASE 3
  194.             'Print text upwards
  195.             'first lets reverse the text, so it's easy to place
  196.             temp$ = ""
  197.             FOR i = 0 TO LEN(text$) - 1
  198.                 temp$ = temp$ + MID$(text$, LEN(text$) - i, 1)
  199.             NEXT
  200.             'then put it where it belongs
  201.             FOR i = 1 TO LEN(text$)
  202.                 fx = (w& - _PRINTWIDTH(MID$(temp$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  203.                 _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(temp$, i, 1)
  204.             NEXT
  205.         CASE 4
  206.             'Print text downwards
  207.             FOR i = 1 TO LEN(text$)
  208.                 fx = (w& - _PRINTWIDTH(MID$(text$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  209.                 _PRINTSTRING (fx, _FONTHEIGHT * (i - 1)), MID$(text$, i, 1)
  210.             NEXT
  211.     END SELECT
  212.     _DEST D
  213.     COLOR dc&, bgc&
  214.     _FONT F
  215.  
  216.  
  217.  


With a wood-burnt style theme, and no bright color division, so your family can argue over whether the number is actually closer to the 3 or the 4 for the spin result!

Use <SPACE> or <LEFT MOUSE BUTTON> to spin the spinner.
Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 08:47:42 pm
Great B+. I'll have to look at yours Steve.

B+, here is the Edge Spinner you were talking about with the arrow going along the edge of the circle round and round until it stops. :) I been working on this for awhile today.



Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 08:50:30 pm
Very nice Steve! I like the unique old fashioned feeling to it.
Title: Re: The Cobalt Spinner
Post by: bplus on July 19, 2020, 09:34:57 pm
Here is the spinner without an image file!
Code: QB64: [Select]
  1. _TITLE "Bplus Spinner 2020-07-19"
  2. RANDOMIZE TIMER 'B+ spinner 2020-07-19
  3. CONST xmax = 600
  4. CONST ymax = 600
  5. TYPE vectorType
  6.     x AS SINGLE
  7.     y AS SINGLE
  8. DIM SHARED wheel&
  9. SCREEN _NEWIMAGE(xmax, ymax, 32)
  10. _DELAY .25
  11. ca = _PI(2 / 36): wheelOffset = 6: dir = 1
  12. makeWheel
  13.     FOR a = 0 TO _PI(2) STEP _PI(2 / 36) ' give it a right quick start
  14.         CLS
  15.         RotoZoom2 _WIDTH / 2, _HEIGHT / 2, wheel&, 1, 1, -dir * a
  16.         LINE (295, 85)-STEP(10, 30), &HFFFFFF00, BF
  17.         _DISPLAY
  18.         _LIMIT 50
  19.     NEXT
  20.     stopAt = INT(RND * 36): i1 = 2: i2 = 1
  21.     FOR a = 0 TO _PI(2) + stopAt * ca STEP _PI(2 / 36)
  22.         CLS
  23.         PRINT i1, i2
  24.         RotoZoom2 _WIDTH / 2, _HEIGHT / 2, wheel&, 1, 1, -dir * a
  25.         LINE (295, 85)-STEP(10, 30), &HFFFFFF00, BF
  26.         'INPUT "OK ..."; w$
  27.         IF dir = 1 THEN
  28.             i2 = i2 + 1
  29.             IF i2 = 7 THEN i2 = 1: i1 = i1 + 1
  30.             IF i1 = 7 THEN i1 = 1
  31.         ELSE
  32.             i2 = i2 - 1
  33.             IF i2 = 0 THEN i2 = 6: i1 = i1 - 1
  34.             IF i1 = 0 THEN i1 = 6
  35.         END IF
  36.         _DISPLAY
  37.         _LIMIT stopAt + _PI(2) / ca - a / ca + 3
  38.     NEXT
  39.     IF RND < .5 THEN dir = -1 ELSE dir = 1
  40.     _DELAY 2
  41.  
  42. SUB makeWheel
  43.     ca = _PI(2 / 36)
  44.     DIM vdigit(0 TO 35) AS vectorType
  45.     DIM outer(0 TO 35) AS vectorType
  46.     x0 = 190: y0 = 190: radius = 150
  47.     'CIRCLE (x0, y0), radius
  48.     COLOR &HFFFFFFEE
  49.     CIRCLE (x0, y0), 187
  50.     CIRCLE (x0, y0), 150
  51.     ca = _PI(2 / 36)
  52.     FOR i = 0 TO 35
  53.         xe = x0 + 187 * COS(i * ca + .5 * ca): ye = y0 + 187 * SIN(i * ca + .5 * ca)
  54.         IF i MOD 6 = 2 THEN
  55.             x = x0: y = y0
  56.         ELSE
  57.             x = x0 + 150 * COS(i * ca + .5 * ca): y = y0 + 150 * SIN(i * ca + .5 * ca)
  58.         END IF
  59.         px = x0 + 160 * COS(i * ca + .25 * ca)
  60.         py = y0 + 160 * SIN(i * ca + .25 * ca)
  61.         LINE (x, y)-(xe, ye)
  62.         IF i > 0 THEN
  63.             IF i MOD 2 THEN PAINT (px, py), &HFFFF0000, &HFFFFFFEE ELSE PAINT (px, py), &HFFFFFFFF, &HFFFFFFEE
  64.         END IF
  65.         IF INT(i / 6) > 0 THEN
  66.             px1 = x0 + 100 * COS(i * ca + .25 * ca)
  67.             py1 = y0 + 100 * SIN(i * ca + .25 * ca)
  68.             IF INT(i / 6) MOD 2 THEN
  69.                 PAINT (px1, py1), &HFFFF0000, &HFFFFFFEE
  70.             ELSE
  71.                 PAINT (px1, py1), &HFFFFFFFF, &HFFFFFFEE
  72.             END IF
  73.         END IF
  74.         '_LIMIT 5
  75.     NEXT
  76.     px = x0 + 160 * COS(i * ca + .25 * ca)
  77.     py = y0 + 160 * SIN(i * ca + .25 * ca)
  78.     IF i > 0 THEN
  79.         IF i MOD 2 THEN PAINT (px, py), &HFFFF0000, &HFFFFFFEE ELSE PAINT (px, py), &HFFFFFFFF, &HFFFFFFEE
  80.     END IF
  81.     px1 = x0 + 100 * COS(i * ca + .25 * ca)
  82.     py1 = y0 + 100 * SIN(i * ca + .25 * ca)
  83.     IF INT(i / 6) MOD 2 THEN
  84.         PAINT (px1, py1), &HFFFF0000, &HFFFFFFEE
  85.     ELSE
  86.         PAINT (px1, py1), &HFFFFFFFF, &HFFFFFFEE
  87.     END IF
  88.     FOR i = 0 TO 35
  89.         vdigit(i).x = x0 + radius * COS(ca * i - 2 * ca)
  90.         vdigit(i).y = y0 + radius * SIN(ca * i - 2 * ca)
  91.         'CIRCLE (vdigit(i).x, vdigit(i).y), 2
  92.         x = x0 + (radius + 18) * COS(ca * i - 2 * ca)
  93.         y = y0 + (radius + 18) * SIN(ca * i - 2 * ca)
  94.         IF i MOD 2 THEN c~& = &HFFFFFFFF ELSE c~& = &HFFFF0000
  95.         drwChar LTRIM$(STR$((i + 1) MOD 6 + 1)), c~&, x, y, 2, 2, ca * i - 2 * ca - _PI(1.5)
  96.         outer(i).x = x0 + (radius + r2) * COS(ca * i - 2 * ca)
  97.         outer(i).y = y0 + (radius + r2) * SIN(ca * i - 2 * ca)
  98.     NEXT
  99.     ca = _PI(2 / 6): radius = 80
  100.     FOR i = 0 TO 5
  101.         vdigit(i).x = x0 + radius * COS(ca * i - 2 * ca)
  102.         vdigit(i).y = y0 + radius * SIN(ca * i - 2 * ca)
  103.         'CIRCLE (vdigit(i).x, vdigit(i).y), 2
  104.         x = x0 + (radius + 18) * COS(ca * i - 2 * ca)
  105.         y = y0 + (radius + 18) * SIN(ca * i - 2 * ca)
  106.         IF i MOD 2 THEN c~& = &HFFFFFFFF ELSE c~& = &HFFFF0000
  107.         drwChar LTRIM$(STR$(i MOD 6 + 1)), c~&, x, y, 6, 6, ca * i - 2 * ca - _PI(1.5)
  108.         outer(i).x = x0 + (radius + r2) * COS(ca * i - 2 * ca)
  109.         outer(i).y = y0 + (radius + r2) * SIN(ca * i - 2 * ca)
  110.     NEXT
  111.     wheel& = _NEWIMAGE(380, 380, 32)
  112.     _PUTIMAGE (0, 0)-(380, 380), 0, wheel&, (0, 0)-(380, 380)
  113.  
  114. SUB drwChar (char$, c AS _UNSIGNED LONG, midX, midY, xScale, yScale, Rotation) 'what ever the present color is set at
  115.     I& = _NEWIMAGE(8, 16, 32)
  116.     _DEST I&
  117.     COLOR c, &H00000000
  118.     _PRINTSTRING (0, 0), char$
  119.     _DEST 0
  120.     RotoZoom2 midX, midY, I&, xScale, yScale, Rotation
  121.     _FREEIMAGE I&
  122.  
  123.  
  124. SUB RotoZoom2 (X AS LONG, Y AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, Rotation AS SINGLE)
  125.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  126.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  127.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  128.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  129.     sinr! = SIN(-Rotation): cosr! = COS(-Rotation)
  130.     FOR i& = 0 TO 3
  131.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + Y
  132.         px(i&) = x2&: py(i&) = y2&
  133.     NEXT
  134.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  135.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  136.  
  137.  
Title: Re: The Cobalt Spinner
Post by: SierraKen on July 19, 2020, 09:42:31 pm
Very cool B+. In the beginning I tried to make everything without files but I had no idea that PAINT could have a start and end color, until you just showed yours. LOL
Title: Re: The Cobalt Spinner
Post by: Cobalt on July 19, 2020, 10:09:49 pm
And to think I was just goofing off! Wow this topic went farther than I had anticipated! XD


Well here have an animated gif I made with me own pics!

how odd, it doesn't act like an animated gif... should be.. is on my hard drive...???
not sure whats going on that should be 9 frames but its acting like a single frame when I test downloaded it. not sure whats up with that.

 
Title: Re: The Cobalt Spinner
Post by: johnno56 on July 20, 2020, 04:59:12 am
Here's a wacky thought... What about using 'both' types of rotation. Disc in one direction and the arrow in the other... Talk about random...
Title: Re: The Cobalt Spinner
Post by: FellippeHeitor on July 20, 2020, 12:32:18 pm
Testing...

  [ This attachment cannot be displayed inline in 'Print Page' view ]  

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: The Cobalt Spinner
Post by: FellippeHeitor on July 20, 2020, 12:35:02 pm
Final test...

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: The Cobalt Spinner
Post by: FellippeHeitor on July 20, 2020, 12:35:34 pm
Here, I used this corrupted GIF repair utility: https://ezgif.com/repair
Title: Re: The Cobalt Spinner
Post by: bplus on July 20, 2020, 12:39:08 pm
The gif is cool! but that comet doesn't look right?
Title: Re: The Cobalt Spinner
Post by: Cobalt on July 20, 2020, 05:30:36 pm
The gif is cool! but that comet doesn't look right?

How so?

I have over 100 images I took Thursday. I'm going to try and gif together, but I will probably turn it into a video and upload it to YT instead. as for some reason the forum don't like my gifs. and it will be several megs in size.
Title: Re: The Cobalt Spinner
Post by: bplus on July 20, 2020, 05:35:42 pm
I was expecting comet tail to follow the direction it's going (why else call it a tail?) but I guess it always points away from the sun. Learn something new...

Title: Re: The Cobalt Spinner
Post by: johnno56 on July 20, 2020, 06:44:02 pm
Comets usually follow long elliptical orbits. The "tail" does not normally show until it nears the Sun. Although the "body" of the comet follows the orbit, the tail, being less in mass, is influenced by 'Solar Wind' and as a result, the 'tail' will point away from the Sun. So therefore, when you see a comet, the 'tail' will indicate the direction of the Sun and not the direction that the comet is traveling. I hope this helps.
Title: Re: The Cobalt Spinner
Post by: bplus on July 20, 2020, 06:50:38 pm
OK now about the UFO in one frame?

What's the scientific explanation for that? Elmo's Fire?

Title: Re: The Cobalt Spinner
Post by: Cobalt on July 20, 2020, 07:45:10 pm
Lightning Bug. :D

Several of my Thursday batch have nice glowing trails cause the exposure time was ~20 seconds so any light that happens to flash in the sky gets caught to some degree. have some satellite trails too. missed the shooting star I saw Thursday, go figure! Supposed to be a bit of a meteor shower next week around the 28th I believe to be the highlight night.

Camera will only take up to 10 consecutive shots at a time, which takes just around 4-4 1/2 mins to complete so depending on conditions I might just catch one. but the comet was my highlight this year.
In 2024 when the solar eclipse passes over head I will be in the path of totality, for about 3:33 secs, or I could drive about 15 miles north and be in the center of the path! Hoping to have a telephoto lens for that one and catch the corona.

As for the static red, white, and blue dots, I'm not sure. Something tells me the sensor in my camera may be slightly damaged maybe? they don't really show in daylight photos, mainly just night shots.
Title: Re: The Cobalt Spinner
Post by: bplus on July 20, 2020, 10:15:55 pm
LOL a lightning bug! Of course.