Author Topic: Air Hockey  (Read 5285 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Air Hockey
« on: March 11, 2020, 06:24:13 pm »
Beats Pong, you can control where you hit the puck if you are fast and accurate enough.

Code: QB64: [Select]
  1. 'Air hockey 2.bas for QB64 fork (B+=MGA) 2017-09-05  (started)
  2. ' the first version was a direct translation from SmallBASIC
  3. ' now add some more graphic image handling, try new things
  4.  
  5.  
  6. CONST xmax = 1200
  7. CONST ymax = 700
  8.  
  9. SCREEN _NEWIMAGE(xmax, ymax, 32)
  10. _TITLE "Air Hockey by bplus"
  11. _SCREENMOVE 100, 20
  12.  
  13. CONST pr = 16 'puck radius
  14. CONST pr2 = 2 * pr 'puck diameter = bumper width = radius of strikers
  15. CONST tl = xmax 'table length
  16. CONST tw = tl / 2 'table width
  17. CONST tw13 = .3333 * tw \ 1 'goal end point
  18. CONST tw23 = .6667 * tw \ 1 'goal end point
  19. CONST speed = 30 'puck speed also see _limit in main loop
  20. CONST midC = 316 '(tl - 2 * pr2) \ 4 + pr2   'mid line of computer's sin field
  21. CONST rangeC = 252 ' 316 - 252 = 64 (bumper + pr2)  316 + 252 = 568 (mid screen - pr2)
  22.  
  23. COMMON SHARED computer, player, px, py, pa, psx, psy, c1, csx, csy, strkr&
  24.  
  25. f& = _LOADFONT("C:\Windows\Fonts\arial.ttf", 25) 'normal style
  26.  
  27. table& = _NEWIMAGE(xmax, tw, 32)
  28. _DEST table&
  29. drawTable
  30. strkr& = _NEWIMAGE(2 * pr2, 2 * pr2, 32)
  31. _DEST strkr&
  32. striker pr2, pr2
  33. cp 7, "Air Hockey, first to score 21 goals wins!"
  34. cp 9, "Player you will be defending the goal on the right (a black slot)."
  35. cp 10, "Your goal is on the left, defended by the computer."
  36. cp 12, "Press any when ready..."
  37. computer = 0 'score
  38. player = 0 'score
  39. initball
  40. WHILE player < 21 AND computer < 21
  41.     CLS
  42.     updateScore
  43.     _PUTIMAGE (0, 0), table&, 0
  44.     drawComputerStriker
  45.         psx = _MOUSEX
  46.         psy = _MOUSEY
  47.     LOOP
  48.     drawPlayerStriker
  49.     drawPuck
  50.     _DISPLAY
  51.     _LIMIT 20 'slow down, speeed up as needed for good game
  52.  
  53. IF computer > player THEN
  54.     s$ = "Game Won by Computer."
  55.     tx = 450
  56.     s$ = "Game Won by Player!"
  57.     tx = 470
  58. COLOR _RGB(200, 240, 140)
  59. _PRINTSTRING (tx, tw + 30), s$
  60.  
  61. SUB initball
  62.     px = tl / 2: py = tw / 2: pa = _PI(1) + RND * _PI(.1)
  63.     rnddir = (RND * 2) \ 1: IF rnddir THEN pa = _PI(1) - pa
  64.  
  65. SUB updateScore
  66.     COLOR _RGB(40, 255, 255)
  67.     s$ = "Computer: " + STR$(computer) + SPACE$(67) + "Player: " + STR$(player)
  68.     _PRINTSTRING (200, tw + 30), s$
  69.  
  70. SUB drawTable
  71.     FOR i = 0 TO pr2 STEP 4
  72.         shade = 64 + i / pr2 * 100
  73.         COLOR _RGB(shade, shade, shade)
  74.         LINE (i, i)-(tl - i, tw - i), , BF
  75.     NEXT
  76.     LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB(190, 230, 255), BF 'field
  77.     LINE (pr, tw13)-(pr2, tw23), _RGB(60, 60, 60), BF
  78.     LINE (tl - pr2, tw13)-(tl - pr, tw23), _RGB(60, 60, 60), BF
  79.     LINE (tl \ 2 - 1, pr2)-(tl \ 2 + 1, tw - pr2), _RGB(128, 128, 128), BF
  80.  
  81. SUB drawPlayerStriker
  82.     IF psx - pr2 < tl / 2 THEN psx = tl / 2 + pr2
  83.     IF psx + pr2 > tl - pr2 THEN psx = tl - 2 * pr2
  84.     IF psy - pr2 < pr2 THEN psy = 2 * pr2
  85.     IF psy + pr2 > tw - pr2 THEN psy = tw - 2 * pr2
  86.     _PUTIMAGE (psx - pr2, psy - pr2), strkr&, 0
  87.  
  88. SUB drawComputerStriker
  89.     c1 = c1 + _PI(1 / 80)
  90.     csx = midC + rangeC * SIN(c1)
  91.     IF px > csx THEN csy = py + pr2 * 1.5 * SIN(c1)
  92.     IF csy - pr2 < pr2 THEN csy = 2 * pr2
  93.     IF csy + pr2 > tw - pr2 THEN csy = tw - 2 * pr2
  94.     _PUTIMAGE (csx - pr2, csy - pr2), strkr&, 0
  95.  
  96. SUB drawPuck
  97.     'update ball x, y and see if hit anything
  98.     px = px + speed * COS(pa)
  99.     py = py + speed * SIN(pa)
  100.  
  101.     IF px - pr < pr2 THEN
  102.         IF tw13 < py - pr AND py + pr < tw23 THEN
  103.             player = player + 1
  104.             CLS
  105.             updateScore
  106.             drawTable
  107.             striker csx, csy
  108.             striker psx, psy
  109.             puck pr, py
  110.             FOR i = 0 TO pr STEP 4
  111.                 shade = 64 + i / pr2 * 100
  112.                 COLOR _RGB(shade, shade, shade)
  113.                 LINE (i, t13)-(pr, tw23), , BF
  114.             NEXT
  115.             snd 1200, 200
  116.             snd 2200, 300
  117.             _DISPLAY
  118.             initball
  119.             _DELAY .5
  120.             EXIT SUB
  121.         ELSE
  122.             snd 2600, 8
  123.             pa = _PI(1) - pa
  124.             px = pr2 + pr
  125.         END IF
  126.     END IF
  127.  
  128.     IF px + pr > tl - pr2 THEN
  129.         IF tw13 < py - pr AND py + pr < tw23 THEN
  130.             computer = computer + 1
  131.             CLS
  132.             updateScore
  133.             drawTable
  134.             striker csx, csy
  135.             striker psx, psy
  136.             puck tl - pr, py
  137.             FOR i = 0 TO pr STEP 4
  138.                 shade = 64 + i / pr2 * 100
  139.                 COLOR _RGB(shade, shade, shade)
  140.                 LINE (tl - pr, t13)-(tl - i, tw23), , BF
  141.             NEXT
  142.             snd 2200, 300
  143.             snd 1200, 200
  144.             _DISPLAY
  145.             initball
  146.             _DELAY .5
  147.             EXIT SUB
  148.         ELSE
  149.             snd 2600, 5
  150.             pa = _PI(1) - pa
  151.             px = tl - pr2 - pr
  152.         END IF
  153.     END IF
  154.  
  155.     IF py - pr < pr2 THEN
  156.         snd 2600, 8
  157.         pa = -pa
  158.         py = pr2 + pr
  159.     END IF
  160.  
  161.     IF py + pr > tw - pr2 THEN
  162.         snd 2600, 8
  163.         pa = -pa
  164.         py = tw - pr2 - pr
  165.     END IF
  166.  
  167.     IF SQR((px - psx) ^ 2 + (py - psy) ^ 2) < (pr + pr2) THEN
  168.         pa = _ATAN2(py - psy, px - psx)
  169.         'boost puck away
  170.         px = px + .5 * speed * COS(pa)
  171.         py = py + .5 * speed * SIN(pa)
  172.         snd 2200, 4
  173.     END IF
  174.     IF SQR((px - csx) ^ 2 + (py - csy) ^ 2) < (pr + pr2) THEN
  175.         pa = _ATAN2(py - csy, px - csx)
  176.         'boost puck away
  177.         px = px + .5 * speed * COS(pa)
  178.         py = py + .5 * speed * SIN(pa)
  179.         snd 2200, 4
  180.     END IF
  181.     puck px, py
  182.  
  183. SUB puck (x, y)
  184.     COLOR _RGB(90, 90, 90)
  185.     fillcirc x, y, pr
  186.     COLOR _RGB(190, 100, 0)
  187.     fillcirc x, y, pr - 4
  188.  
  189. SUB striker (x, y)
  190.     FOR i = pr2 TO pr STEP -1
  191.         shade = 164 - 90 * SIN(i * _PI(2) / pr)
  192.         COLOR _RGB(shade, shade, shade)
  193.         fillcirc x, y, i
  194.     NEXT
  195.     FOR i = pr TO 0 STEP -1
  196.         shade = 185 + 70 * (pr - i) / pr
  197.         COLOR _RGB(shade, shade, shade)
  198.         fillcirc x, y, i
  199.     NEXT
  200.  
  201. 'Steve McNeil's  copied from his forum   note: Radius is too common a name
  202. SUB fillcirc (CX AS LONG, CY AS LONG, R AS LONG)
  203.     DIM subRadius AS LONG, RadiusError AS LONG
  204.     DIM X AS LONG, Y AS LONG
  205.  
  206.     subRadius = ABS(R)
  207.     RadiusError = -subRadius
  208.     X = subRadius
  209.     Y = 0
  210.  
  211.     IF subRadius = 0 THEN PSET (CX, CY): EXIT SUB
  212.  
  213.     ' Draw the middle span here so we don't draw it twice in the main loop,
  214.     ' which would be a problem with blending turned on.
  215.     LINE (CX - X, CY)-(CX + X, CY), , BF
  216.  
  217.     WHILE X > Y
  218.         RadiusError = RadiusError + Y * 2 + 1
  219.         IF RadiusError >= 0 THEN
  220.             IF X <> Y + 1 THEN
  221.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), , BF
  222.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), , BF
  223.             END IF
  224.             X = X - 1
  225.             RadiusError = RadiusError - X * 2
  226.         END IF
  227.         Y = Y + 1
  228.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), , BF
  229.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), , BF
  230.     WEND
  231.  
  232. SUB snd (frq, dur)
  233.     SOUND frq / 2.2, dur * .01
  234.  
  235. SUB cp (lineNum, s$)
  236.     '1200 pixels / 85 characters = 14.11 pixels/char wide
  237.     '700 pixels / 28 lines = 18.42 pixels / char high
  238.     x = (xmax - 11 * LEN(s$)) \ 2
  239.     y = lineNum * 25
  240.     _PRINTSTRING (x, y), s$
  241.  
  242.  

 
Air Hockey.PNG


Feel free to adjust the _LIMIT amount to your skill level.
« Last Edit: March 11, 2020, 06:29:30 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Air Hockey
« Reply #1 on: March 12, 2020, 12:28:50 am »
Improved for 2020:
Quote
' 2020-03-11 v2-1 (QB64 v1.4 now) cleanup some code:
' Fix _MOUSEINPUT block too newbie ;)
' Fix flat spots on strikers how long have they been there?
' Increase frames per sec and slow puck speed for less double images.
' Oh that sped up the AI player! Nice.
' Do start shots to the side instead of directly at goal. MUCH BETTER!
' Update opening screen with this info. Now pause the puck at start.
' Ran OPTION _EXPLICIT and found a type-O that has been 0 all this time!

Code: QB64: [Select]
  1. 'Air Hockey v2-1.bas for QB64
  2. ' Started in QB64 Walter fork version (B+=MGA) 2017-09-05
  3. ' The first version was a direct translation from SmallBASIC,
  4. ' Now v2.0 add some more graphic image handling, try new things.
  5. ' 2020-03-11 v2-1 (QB64 v1.4 now) cleanup some code:
  6. ' Fix _MOUSEINPUT block too newbie ;)
  7. ' Fix flat spots on strikers how long have they been there?
  8. ' Increase frames per sec and slow puck speed for less double images.
  9. ' Oh that sped up the AI player! Nice.
  10. ' Do start shots to the side instead of directly at goal. MUCH BETTER!
  11. ' Update opening screen with this info. Now pause the puck at start.
  12. ' Ran OPTION _EXPLICIT and found a type-O that has been 0 all this time!
  13.  
  14. CONST xmax = 1200, ymax = 700 'screen dimensions
  15. SCREEN _NEWIMAGE(xmax, ymax, 32)
  16. _TITLE "Air Hockey v2-1 by bplus"
  17. _DELAY .25
  18.  
  19. CONST pr = 16 '              puck radius
  20. CONST pr2 = 2 * pr '         puck diameter = bumper width = radius of strikers
  21. CONST tl = xmax '            table length
  22. CONST tw = tl / 2 '          table width
  23. CONST tw13 = .3333 * tw \ 1 'goal end point
  24. CONST tw23 = .6667 * tw \ 1 'goal end point
  25. CONST speed = 15 '           puck speed also see _limit in main loop
  26. CONST midC = 316 '           (tl - 2 * pr2) \ 4 + pr2   'mid line of computer's sin field
  27. CONST rangeC = 252 '         316 - 252 = 64 (bumper + pr2)  316 + 252 = 568 (mid screen - pr2)
  28.  
  29. COMMON SHARED f&, table&, computer, player, s$, tx, px, py, pa, psx, psy, c1, csx, csy, strkr&
  30.  
  31. f& = _LOADFONT("C:\Windows\Fonts\arial.ttf", 25) ' arial normal style  if you have windows
  32. _FONT f& '                                         arial is pretty common if you don't have Windows
  33.  
  34. table& = _NEWIMAGE(xmax, tw, 32)
  35. _DEST table&
  36. drawTable
  37.  
  38. strkr& = _NEWIMAGE(2 * pr2 + 1, 2 * pr2 + 1, 32) ' more space to avoid right and bottom flat edges
  39. _DEST strkr&
  40. striker pr2, pr2
  41.  
  42. _DEST 0 '                                                    Opening screen
  43. cp 7, "Air Hockey, first to score 21 goals wins!"
  44. cp 9, "Player you will be defending the goal on the right (a black slot)."
  45. cp 10, "Your goal is on the left, defended by the computer."
  46. cp 12, "The puck will be started going up and down in the middle of"
  47. cp 13, "the screen at slight angle towards a randomly selected goal."
  48. cp 16, "Press any when ready..."
  49. updateScore
  50. _PUTIMAGE (0, 0), table&, 0
  51. drawComputerStriker
  52. psx = _MOUSEX: psy = _MOUSEY
  53. drawPlayerStriker
  54. initball
  55. WHILE player < 21 AND computer < 21 '        play until someone scores 21
  56.     CLS
  57.     updateScore
  58.     _PUTIMAGE (0, 0), table&, 0
  59.     drawComputerStriker
  60.     psx = _MOUSEX: psy = _MOUSEY
  61.     drawPlayerStriker
  62.     drawPuck
  63.     _DISPLAY
  64.     _LIMIT 60 '<<<<<<<<<<<<<  slow down, speeed up as needed for good game
  65. IF computer > player THEN '                                    last report
  66.     s$ = "Game Won by Computer."
  67.     tx = 450
  68.     s$ = "Game Won by Player!"
  69.     tx = 470
  70. COLOR _RGB(200, 240, 140)
  71. _PRINTSTRING (tx, tw + 30), s$
  72.  
  73. SUB initball 'toss puck out to side slightly angled to one goal or the other
  74.     DIM pao
  75.     px = tl / 2: py = tw / 2: pao = _PI(1 / 10) * RND
  76.     puck px, py
  77.     _DISPLAY
  78.     _DELAY .3
  79.     IF RND < .5 THEN pa = _PI(.5) ELSE pa = _PI(1.5)
  80.     IF RND < .5 THEN pa = pa + pao ELSE pa = pa - pao
  81.  
  82. SUB updateScore
  83.     COLOR _RGB(40, 255, 255)
  84.     s$ = "Computer: " + STR$(computer) + SPACE$(67) + "Player: " + STR$(player)
  85.     _PRINTSTRING (200, tw + 30), s$
  86.  
  87. SUB drawTable
  88.     DIM i, shade
  89.     FOR i = 0 TO pr2 STEP 4
  90.         shade = 64 + i / pr2 * 100
  91.         COLOR _RGB(shade, shade, shade)
  92.         LINE (i, i)-(tl - i, tw - i), , BF
  93.     NEXT
  94.     LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB(190, 230, 255), BF 'field
  95.     LINE (pr, tw13)-(pr2, tw23), _RGB(60, 60, 60), BF
  96.     LINE (tl - pr2, tw13)-(tl - pr, tw23), _RGB(60, 60, 60), BF
  97.     LINE (tl \ 2 - 1, pr2)-(tl \ 2 + 1, tw - pr2), _RGB(128, 128, 128), BF
  98.  
  99. SUB drawPlayerStriker
  100.     IF psx - pr2 < tl / 2 THEN psx = tl / 2 + pr2
  101.     IF psx + pr2 > tl - pr2 THEN psx = tl - 2 * pr2
  102.     IF psy - pr2 < pr2 THEN psy = 2 * pr2
  103.     IF psy + pr2 > tw - pr2 THEN psy = tw - 2 * pr2
  104.     _PUTIMAGE (psx - pr2, psy - pr2), strkr&, 0
  105.  
  106. SUB drawComputerStriker
  107.     c1 = c1 + _PI(1 / 80)
  108.     csx = midC + rangeC * SIN(c1)
  109.     IF px > csx THEN csy = py + pr2 * 1.5 * SIN(c1)
  110.     IF csy - pr2 < pr2 THEN csy = 2 * pr2
  111.     IF csy + pr2 > tw - pr2 THEN csy = tw - 2 * pr2
  112.     _PUTIMAGE (csx - pr2, csy - pr2), strkr&, 0
  113.  
  114. SUB drawPuck
  115.     'update ball x, y and see if hit anything
  116.     DIM i, shade
  117.     px = px + speed * COS(pa)
  118.     py = py + speed * SIN(pa)
  119.  
  120.     IF px - pr < pr2 THEN
  121.         IF tw13 < py - pr AND py + pr < tw23 THEN 'through computer slot, player scores
  122.             player = player + 1
  123.             CLS
  124.             updateScore
  125.             drawTable
  126.             striker csx, csy
  127.             striker psx, psy
  128.             puck pr, py
  129.             FOR i = 0 TO pr STEP 4
  130.                 shade = 64 + i / pr2 * 100
  131.                 COLOR _RGB(shade, shade, shade)
  132.                 LINE (i, tw13)-(pr, tw23), , BF ' wow tw13 has been 0
  133.             NEXT
  134.             snd 1200, 200
  135.             snd 2200, 300
  136.             _DISPLAY
  137.             initball
  138.             _DELAY .5
  139.             EXIT SUB
  140.         ELSE
  141.             snd 2600, 8
  142.             pa = _PI(1) - pa
  143.             px = pr2 + pr
  144.         END IF
  145.     END IF
  146.  
  147.     IF px + pr > tl - pr2 THEN
  148.         IF tw13 < py - pr AND py + pr < tw23 THEN
  149.             computer = computer + 1
  150.             CLS
  151.             updateScore
  152.             drawTable
  153.             striker csx, csy
  154.             striker psx, psy
  155.             puck tl - pr, py
  156.             FOR i = 0 TO pr STEP 4
  157.                 shade = 64 + i / pr2 * 100
  158.                 COLOR _RGB(shade, shade, shade)
  159.                 LINE (tl - pr, tw13)-(tl - i, tw23), , BF 't13 again!
  160.             NEXT
  161.             snd 2200, 300
  162.             snd 1200, 200
  163.             _DISPLAY
  164.             initball
  165.             _DELAY .5
  166.             EXIT SUB
  167.         ELSE
  168.             snd 2600, 5
  169.             pa = _PI(1) - pa
  170.             px = tl - pr2 - pr
  171.         END IF
  172.     END IF
  173.  
  174.     IF py - pr < pr2 THEN ' hit top boundry
  175.         snd 2600, 8
  176.         pa = -pa
  177.         py = pr2 + pr
  178.     END IF
  179.  
  180.     IF py + pr > tw - pr2 THEN ' hit bottom boundry
  181.         snd 2600, 8
  182.         pa = -pa
  183.         py = tw - pr2 - pr
  184.     END IF
  185.  
  186.     IF SQR((px - psx) ^ 2 + (py - psy) ^ 2) < (pr + pr2) THEN 'contact player striker
  187.         pa = _ATAN2(py - psy, px - psx)
  188.         'boost puck away
  189.         px = px + .5 * speed * COS(pa)
  190.         py = py + .5 * speed * SIN(pa)
  191.         snd 2200, 4
  192.     END IF
  193.     IF SQR((px - csx) ^ 2 + (py - csy) ^ 2) < (pr + pr2) THEN 'contact computer striker
  194.         pa = _ATAN2(py - csy, px - csx)
  195.         'boost puck away
  196.         px = px + .5 * speed * COS(pa)
  197.         py = py + .5 * speed * SIN(pa)
  198.         snd 2200, 4
  199.     END IF
  200.     puck px, py ' here it is!
  201.  
  202. SUB puck (x, y)
  203.     COLOR _RGB(90, 90, 90)
  204.     fillcirc x, y, pr
  205.     COLOR _RGB(190, 100, 0)
  206.     fillcirc x, y, pr - 4
  207.  
  208. SUB striker (x, y)
  209.     DIM i, shade
  210.     FOR i = pr2 TO pr STEP -1
  211.         shade = 164 - 90 * SIN(i * _PI(2) / pr)
  212.         COLOR _RGB(shade, shade, shade)
  213.         fillcirc x, y, i
  214.     NEXT
  215.     FOR i = pr TO 0 STEP -1
  216.         shade = 185 + 70 * (pr - i) / pr
  217.         COLOR _RGB(shade, shade, shade)
  218.         fillcirc x, y, i
  219.     NEXT
  220.  
  221. 'Steve McNeil's  copied from his forum   note: Radius is too common a name
  222. SUB fillcirc (CX AS LONG, CY AS LONG, R AS LONG)
  223.     DIM subRadius AS LONG, RadiusError AS LONG
  224.     DIM X AS LONG, Y AS LONG
  225.  
  226.     subRadius = ABS(R)
  227.     RadiusError = -subRadius
  228.     X = subRadius
  229.     Y = 0
  230.  
  231.     IF subRadius = 0 THEN PSET (CX, CY): EXIT SUB
  232.  
  233.     ' Draw the middle span here so we don't draw it twice in the main loop,
  234.     ' which would be a problem with blending turned on.
  235.     LINE (CX - X, CY)-(CX + X, CY), , BF
  236.  
  237.     WHILE X > Y
  238.         RadiusError = RadiusError + Y * 2 + 1
  239.         IF RadiusError >= 0 THEN
  240.             IF X <> Y + 1 THEN
  241.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), , BF
  242.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), , BF
  243.             END IF
  244.             X = X - 1
  245.             RadiusError = RadiusError - X * 2
  246.         END IF
  247.         Y = Y + 1
  248.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), , BF
  249.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), , BF
  250.     WEND
  251.  
  252. SUB snd (frq, dur)
  253.     SOUND frq / 2.2, dur * .01
  254.  
  255. SUB cp (lineNum, s$)
  256.     DIM x, y
  257.     '1200 pixels / 85 characters = 14.11 pixels/char wide
  258.     '700 pixels / 28 lines = 18.42 pixels / char high
  259.     x = (xmax - 11 * LEN(s$)) \ 2
  260.     y = lineNum * 25
  261.     _PRINTSTRING (x, y), s$
  262.  
  263.  
« Last Edit: March 12, 2020, 12:32:24 am by bplus »

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Air Hockey
« Reply #2 on: March 12, 2020, 08:19:20 am »
This... looks familiar... Nice conversion!
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Air Hockey
« Reply #3 on: March 12, 2020, 12:03:30 pm »
Thanks Johnno, were you able to get Arial Font going on Linux?

I can give you the Arial font I use but any font will do that can be 25 pixels high and about 11 wide. I tried QB64's Cyberbit.ttf, a little too curly but worse, the bottoms of g, y, p, q letters with tails are getting cut off.

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Air Hockey
« Reply #4 on: March 12, 2020, 04:30:32 pm »
Yes I did. I noticed your file reference and edited accordingly... Ran like a dream... I quit the game once the computer scored more than I did... lol
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Air Hockey
« Reply #5 on: March 12, 2020, 07:02:48 pm »
Thanks I had some pretty good battles myself last night. It wins because it never tires or gets distracted.

Angle bank shots to goal are best bet. Just getting puck past it is good too, it will often knock it in for you.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Air Hockey
« Reply #6 on: March 13, 2020, 10:39:16 am »
Being an x-road hockey player, I love this game. Improved my slap shot and wrist shot all with the same motion. I could have been a contender if I could have mastered that shot in real life. Stick handling still sucked. I need some kind of magnet on the puck if I want to deke.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Air Hockey
« Reply #7 on: March 13, 2020, 10:55:03 am »
Hi Dimster,

Well I just learned a "deke" is a fake out while maintaining control of puck.

How about dribbling the puck along your side boundary to near the boundary line between opponents and then a bank shot to the goal.

Offline DANILIN

  • Forum Regular
  • Posts: 128
    • View Profile
    • Danilin youtube
Re: Air Hockey
« Reply #8 on: March 22, 2020, 06:22:28 pm »
I think we need a dark theme
for playing on a dark background that is pleasing for our eyes
choice: black or dark green or dark purple
Russia looks world from future. big data is peace data.
https://youtube.com/playlist?list=PLBBTP9oVY7IagpH0g9FNUQ8JqmHwxDDDB
i never recommend anything to anyone and always write only about myself

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Air Hockey
« Reply #9 on: March 23, 2020, 12:08:47 pm »
I think we need a dark theme
for playing on a dark background that is pleasing for our eyes
choice: black or dark green or dark purple

Code: QB64: [Select]
  1. LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB(190, 230, 255), BF 'field
  2.  
This lovely shade of sky blue is virus free! Oh look this was from my early days with QB64, no _RGB32(), should be &HFFBBBBFF

Of course this being source code make the shade whatever pleases the eye. All hockey games on physical boards, I've seen were white, air hockey... don't remember shade

Here's what Google show's
https://www.google.com/search?q=70%27s+air+hockey+games&client=opera&hs=qbn&sxsrf=ALeKk02LbeoakD1bXPSQGXFru0vQ2sxf8g:1584979630804&source=lnms&tbm=isch&sa=X&ved=2ahUKEwjoz_qe_bDoAhXXXc0KHfKWDxUQ_AUoAnoECAsQBA&biw=1297&bih=667

Yeah, pretty much white! ;-))
« Last Edit: March 23, 2020, 12:20:21 pm by bplus »

Offline DANILIN

  • Forum Regular
  • Posts: 128
    • View Profile
    • Danilin youtube
Re: Air Hockey
« Reply #10 on: March 23, 2020, 03:05:27 pm »
replace line of listing 109
it's real include dark theme many variants of colors

'LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB(190, 230, 255), BF 'field
'LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB(0, 0, 0), BF 'field
'LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB(0, 50, 50), BF 'field
'LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB(50, 50, 0), BF 'field

LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB(50, 0, 50), BF 'field
Russia looks world from future. big data is peace data.
https://youtube.com/playlist?list=PLBBTP9oVY7IagpH0g9FNUQ8JqmHwxDDDB
i never recommend anything to anyone and always write only about myself

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Air Hockey
« Reply #11 on: March 23, 2020, 03:17:15 pm »
Can you still see puck with darker fields?

Oh maybe a puck that light's up! and glows!!!

The goals could have a line of blinking lights and blow up into fireworks when someone wins a game!
« Last Edit: March 23, 2020, 03:19:04 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Air Hockey
« Reply #12 on: March 23, 2020, 03:59:24 pm »
Nice color DANILIN, thanks for tip! updated circle fill with color and lightened edge around puck.

It helps contrast the edges of puck, Strikers and the field.

Code: QB64: [Select]
  1. 'Air Hockey v2-1.bas for QB64
  2. ' Started in QB64 Walter fork version (B+=MGA) 2017-09-05
  3. ' The first version was a direct translation from SmallBASIC,
  4. ' Now v2.0 add some more graphic image handling, try new things.
  5. ' 2020-03-11 v2-1 (QB64 v1.4 now) cleanup some code:
  6. ' Fix _MOUSEINPUT block too newbie ;)
  7. ' Fix flat spots on strikers how long have they been there?
  8. ' Increase frames per sec and slow puck speed for less double images.
  9. ' Oh that sped up the AI player! Nice.
  10. ' Do start shots to the side instead of directly at goal. MUCH BETTER!
  11. ' Update opening screen with this info. Now pause the puck at start.
  12. ' Ran OPTION _EXPLICIT and found a type-O that has been 0 all this time!
  13.  
  14. ' v2020-03-23 Dark Theme as suggested by Danlin also fix fill circle with color
  15. ' also lighten color around the puck, oh fix the rest of the _rgb to rgb32.
  16.  
  17. CONST xmax = 1200, ymax = 700 'screen dimensions
  18. SCREEN _NEWIMAGE(xmax, ymax, 32)
  19. _TITLE "Air Hockey v2020-03-23 Dark Theme"
  20. _DELAY .25
  21.  
  22. CONST pr = 16 '              puck radius
  23. CONST pr2 = 2 * pr '         puck diameter = bumper width = radius of strikers
  24. CONST tl = xmax '            table length
  25. CONST tw = tl / 2 '          table width
  26. CONST tw13 = .3333 * tw \ 1 'goal end point
  27. CONST tw23 = .6667 * tw \ 1 'goal end point
  28. CONST speed = 15 '           puck speed also see _limit in main loop
  29. CONST midC = 316 '           (tl - 2 * pr2) \ 4 + pr2   'mid line of computer's sin field
  30. CONST rangeC = 252 '         316 - 252 = 64 (bumper + pr2)  316 + 252 = 568 (mid screen - pr2)
  31.  
  32. COMMON SHARED f&, table&, computer, player, s$, tx, px, py, pa, psx, psy, c1, csx, csy, strkr&
  33.  
  34. f& = _LOADFONT("C:\Windows\Fonts\arial.ttf", 25) ' arial normal style  if you have windows
  35. _FONT f& '                                         arial is pretty common if you don't have Windows
  36.  
  37. table& = _NEWIMAGE(xmax, tw, 32)
  38. _DEST table&
  39. drawTable
  40.  
  41. strkr& = _NEWIMAGE(2 * pr2 + 1, 2 * pr2 + 1, 32) ' more space to avoid right and bottom flat edges
  42. _DEST strkr&
  43. striker pr2, pr2
  44.  
  45. _DEST 0 '                                                    Opening screen
  46. cp 7, "Air Hockey, first to score 21 goals wins!"
  47. cp 9, "Player you will be defending the goal on the right (a black slot)."
  48. cp 10, "Your goal is on the left, defended by the computer."
  49. cp 12, "The puck will be started going up and down in the middle of"
  50. cp 13, "the screen at slight angle towards a randomly selected goal."
  51. cp 16, "Press any when ready..."
  52. updateScore
  53. _PUTIMAGE (0, 0), table&, 0
  54. drawComputerStriker
  55. psx = _MOUSEX: psy = _MOUSEY
  56. drawPlayerStriker
  57. initball
  58. WHILE player < 21 AND computer < 21 '        play until someone scores 21
  59.     CLS
  60.     updateScore
  61.     _PUTIMAGE (0, 0), table&, 0
  62.     drawComputerStriker
  63.     psx = _MOUSEX: psy = _MOUSEY
  64.     drawPlayerStriker
  65.     drawPuck
  66.     _DISPLAY
  67.     _LIMIT 60 '<<<<<<<<<<<<<  slow down, speeed up as needed for good game
  68. IF computer > player THEN '                                    last report
  69.     s$ = "Game Won by Computer."
  70.     tx = 450
  71.     s$ = "Game Won by Player!"
  72.     tx = 470
  73. COLOR _RGB32(200, 240, 140)
  74. _PRINTSTRING (tx, tw + 30), s$
  75.  
  76. SUB initball 'toss puck out to side slightly angled to one goal or the other
  77.     DIM pao
  78.     px = tl / 2: py = tw / 2: pao = _PI(1 / 10) * RND
  79.     puck px, py
  80.     _DISPLAY
  81.     _DELAY .3
  82.     IF RND < .5 THEN pa = _PI(.5) ELSE pa = _PI(1.5)
  83.     IF RND < .5 THEN pa = pa + pao ELSE pa = pa - pao
  84.  
  85. SUB updateScore
  86.     COLOR _RGB32(40, 255, 255)
  87.     s$ = "Computer: " + STR$(computer) + SPACE$(67) + "Player: " + STR$(player)
  88.     _PRINTSTRING (200, tw + 30), s$
  89.  
  90. SUB drawTable
  91.     DIM i, shade
  92.     FOR i = 0 TO pr2 STEP 4
  93.         shade = 64 + i / pr2 * 100
  94.         COLOR _RGB32(shade, shade, shade)
  95.         LINE (i, i)-(tl - i, tw - i), , BF
  96.     NEXT
  97.     LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB32(190, 230, 255), BF 'field
  98.     LINE (pr2, pr2)-(tl - pr2, tw - pr2), _RGB32(50, 0, 50), BF 'field
  99.     LINE (pr, tw13)-(pr2, tw23), _RGB32(60, 60, 60), BF
  100.     LINE (tl - pr2, tw13)-(tl - pr, tw23), _RGB32(60, 60, 60), BF
  101.     LINE (tl \ 2 - 1, pr2)-(tl \ 2 + 1, tw - pr2), _RGB32(128, 128, 128), BF
  102.  
  103. SUB drawPlayerStriker
  104.     IF psx - pr2 < tl / 2 THEN psx = tl / 2 + pr2
  105.     IF psx + pr2 > tl - pr2 THEN psx = tl - 2 * pr2
  106.     IF psy - pr2 < pr2 THEN psy = 2 * pr2
  107.     IF psy + pr2 > tw - pr2 THEN psy = tw - 2 * pr2
  108.     _PUTIMAGE (psx - pr2, psy - pr2), strkr&, 0
  109.  
  110. SUB drawComputerStriker
  111.     c1 = c1 + _PI(1 / 80)
  112.     csx = midC + rangeC * SIN(c1)
  113.     IF px > csx THEN csy = py + pr2 * 1.5 * SIN(c1)
  114.     IF csy - pr2 < pr2 THEN csy = 2 * pr2
  115.     IF csy + pr2 > tw - pr2 THEN csy = tw - 2 * pr2
  116.     _PUTIMAGE (csx - pr2, csy - pr2), strkr&, 0
  117.  
  118. SUB drawPuck
  119.     'update ball x, y and see if hit anything
  120.     DIM i, shade
  121.     px = px + speed * COS(pa)
  122.     py = py + speed * SIN(pa)
  123.  
  124.     IF px - pr < pr2 THEN
  125.         IF tw13 < py - pr AND py + pr < tw23 THEN 'through computer slot, player scores
  126.             player = player + 1
  127.             CLS
  128.             updateScore
  129.             drawTable
  130.             striker csx, csy
  131.             striker psx, psy
  132.             puck pr, py
  133.             FOR i = 0 TO pr STEP 4
  134.                 shade = 64 + i / pr2 * 100
  135.                 COLOR _RGB32(shade, shade, shade)
  136.                 LINE (i, tw13)-(pr, tw23), , BF ' wow tw13 has been 0
  137.             NEXT
  138.             snd 1200, 200
  139.             snd 2200, 300
  140.             _DISPLAY
  141.             initball
  142.             _DELAY .5
  143.             EXIT SUB
  144.         ELSE
  145.             snd 2600, 8
  146.             pa = _PI(1) - pa
  147.             px = pr2 + pr
  148.         END IF
  149.     END IF
  150.  
  151.     IF px + pr > tl - pr2 THEN
  152.         IF tw13 < py - pr AND py + pr < tw23 THEN
  153.             computer = computer + 1
  154.             CLS
  155.             updateScore
  156.             drawTable
  157.             striker csx, csy
  158.             striker psx, psy
  159.             puck tl - pr, py
  160.             FOR i = 0 TO pr STEP 4
  161.                 shade = 64 + i / pr2 * 100
  162.                 COLOR _RGB32(shade, shade, shade)
  163.                 LINE (tl - pr, tw13)-(tl - i, tw23), , BF 't13 again!
  164.             NEXT
  165.             snd 2200, 300
  166.             snd 1200, 200
  167.             _DISPLAY
  168.             initball
  169.             _DELAY .5
  170.             EXIT SUB
  171.         ELSE
  172.             snd 2600, 5
  173.             pa = _PI(1) - pa
  174.             px = tl - pr2 - pr
  175.         END IF
  176.     END IF
  177.  
  178.     IF py - pr < pr2 THEN ' hit top boundry
  179.         snd 2600, 8
  180.         pa = -pa
  181.         py = pr2 + pr
  182.     END IF
  183.  
  184.     IF py + pr > tw - pr2 THEN ' hit bottom boundry
  185.         snd 2600, 8
  186.         pa = -pa
  187.         py = tw - pr2 - pr
  188.     END IF
  189.  
  190.     IF SQR((px - psx) ^ 2 + (py - psy) ^ 2) < (pr + pr2) THEN 'contact player striker
  191.         pa = _ATAN2(py - psy, px - psx)
  192.         'boost puck away
  193.         px = px + .5 * speed * COS(pa)
  194.         py = py + .5 * speed * SIN(pa)
  195.         snd 2200, 4
  196.     END IF
  197.     IF SQR((px - csx) ^ 2 + (py - csy) ^ 2) < (pr + pr2) THEN 'contact computer striker
  198.         pa = _ATAN2(py - csy, px - csx)
  199.         'boost puck away
  200.         px = px + .5 * speed * COS(pa)
  201.         py = py + .5 * speed * SIN(pa)
  202.         snd 2200, 4
  203.     END IF
  204.     puck px, py ' here it is!
  205.  
  206. SUB puck (x, y)
  207.     fillcirc x, y, pr, _RGB32(160, 160, 160)
  208.     fillcirc x, y, pr - 4, _RGB32(190, 100, 0)
  209.  
  210. SUB striker (x, y)
  211.     DIM i, shade
  212.     FOR i = pr2 TO pr STEP -1
  213.         shade = 164 - 90 * SIN(i * _PI(2) / pr)
  214.         fillcirc x, y, i, _RGB32(shade, shade, shade)
  215.     NEXT
  216.     FOR i = pr TO 0 STEP -1
  217.         shade = 185 + 70 * (pr - i) / pr
  218.         fillcirc x, y, i, _RGB32(shade, shade, shade)
  219.     NEXT
  220.  
  221. 'Steve McNeil's  copied from his forum   note: Radius is too common a name
  222. SUB fillcirc (CX AS LONG, CY AS LONG, R AS LONG, C AS _UNSIGNED LONG)
  223.     DIM subRadius AS LONG, RadiusError AS LONG
  224.     DIM X AS LONG, Y AS LONG
  225.  
  226.     subRadius = ABS(R)
  227.     RadiusError = -subRadius
  228.     X = subRadius
  229.     Y = 0
  230.  
  231.     IF subRadius = 0 THEN PSET (CX, CY), C: EXIT SUB
  232.  
  233.     ' Draw the middle span here so we don't draw it twice in the main loop,
  234.     ' which would be a problem with blending turned on.
  235.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  236.  
  237.     WHILE X > Y
  238.         RadiusError = RadiusError + Y * 2 + 1
  239.         IF RadiusError >= 0 THEN
  240.             IF X <> Y + 1 THEN
  241.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  242.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  243.             END IF
  244.             X = X - 1
  245.             RadiusError = RadiusError - X * 2
  246.         END IF
  247.         Y = Y + 1
  248.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  249.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  250.     WEND
  251.  
  252. SUB snd (frq, dur)
  253.     SOUND frq / 2.2, dur * .01
  254.  
  255. SUB cp (lineNum, s$)
  256.     DIM x, y
  257.     '1200 pixels / 85 characters = 14.11 pixels/char wide
  258.     '700 pixels / 28 lines = 18.42 pixels / char high
  259.     x = (xmax - 11 * LEN(s$)) \ 2
  260.     y = lineNum * 25
  261.     _PRINTSTRING (x, y), s$
  262.  
  263.  

EDIT: fix the rest of the _RGB's
Air Hockey Dark Theme.PNG
* Air Hockey Dark Theme.PNG (Filesize: 34.87 KB, Dimensions: 1207x733, Views: 291)
« Last Edit: March 23, 2020, 04:41:13 pm by bplus »