Author Topic: Artillery Wanted  (Read 13698 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Artillery Wanted
« Reply #45 on: June 28, 2019, 03:15:43 pm »
Wow that is interesting. Mine uses POINT to only detect the brown dirt, nothing else. Like if it hits the text in the sky, it just goes through it. And since the sky is blue, it won't detect that either. This is what I have on mine:
Code: QB64: [Select]
  1. IF POINT(bx, by) = _RGB32(74, 86, 58) THEN
  2.  

I'm not sure what else would help you, I am very, very new on POINT. This is probably the very first time I ever used it.

Ah! only for dirt? not the bases? not the hill? wait the hill is same as dirt for yours... OK. Come to think of it, I did see some tunneling through the bases. What stops tunneling is gravity's effect of pulling down harder making ball go farther that it's radius.

For help, I probably need some but not for the "tunneling" problem. :-))
I will just take a snap shot of screen before showing the new ball and clear screen between each loop with it.
OR do it like Tanks Battle, take a snapshot at start and then record all holes made by explosions, redraw screen at each loop and redraw all the holes in it. But it was really cool, to me, to see the ball cleared without having to clear the screen each loop.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Artillery Wanted
« Reply #46 on: June 28, 2019, 08:54:45 pm »
Yeah, only for dirt. The bases I use coordinate variables, just like my Wall Detection Example, only variables. I thought about it later how I could have used POINT instead but that's OK.

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Artillery Wanted
« Reply #47 on: June 29, 2019, 05:44:36 am »
If memory serves correctly, in the original dos version of Scorched Earth, 'tunnelling'  was an 'option'... Tunnelling or not, I just enjoy blowing stuff up... Now, a nice addition, would be 'collapsible' landscape.... You know, blast a crater in the ground, then watch the sides of the crater slide towards the bottom of the crater... Just a though...

J
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Artillery Wanted
« Reply #48 on: July 02, 2019, 12:05:18 am »
Well after one goofy setback after another, I finally got my MOD worked out. Computer is playing decent game.

Code: QB64: [Select]
  1.  
  2. 'Ken:
  3. 'I've always wanted to make this game ever since I started programming in the 80's.
  4. 'This was made using the BASIC and compile language QB64 from QB64.org
  5. 'This was created by Ken G. with much help from others below.
  6. 'Thank you to B+ for posting much of this math code on the QB64.org forum!
  7. 'Also thank you to johnno56 for a little help on the explosions, from the QB64.org forum.
  8. 'It takes the computer a little time to learn how to hit your base.
  9. 'Created on June 25, 2019.
  10.  
  11. 'Hi Ken, I made a couple of changes to the game. Do you recognize it :D  MOD 2019-07-01 B+
  12.  
  13. CONST xmax = 1200, ymax = 740
  14. _TITLE "Ken's Artillery MOD B+  Hey! They only have one cannon ball between the two of them :D" 'mod B+ makeover started 2019-06-25
  15. SCREEN _NEWIMAGE(xmax, ymax, 32)
  16.  
  17. TYPE ball
  18.     x AS SINGLE
  19.     y AS SINGLE
  20.     dx AS SINGLE
  21.     dy AS SINGLE
  22.  
  23. TYPE Contestent
  24.     baseX AS INTEGER 'butt end of cannon
  25.     baseY AS INTEGER
  26.     baseC AS _UNSIGNED LONG
  27.     cannonAngle AS SINGLE
  28.     velocity AS SINGLE
  29.     points AS INTEGER
  30.  
  31. CONST skyC = &HFF9988FF
  32. CONST ballC = &HFF000000
  33. CONST groundC = &HFF405020
  34. CONST cannonC = &HFF884422
  35. CONST printC = &HFFEEDDCC
  36. CONST groundY = 680
  37. CONST gravity = .05
  38. CONST cannonLength = 100
  39. CONST baseLength = 100
  40. CONST baseHeight = 30
  41. CONST ballRadius = 5
  42. DIM SHARED bg AS LONG, c AS Contestent, p AS Contestent, b AS ball, airX, turn, lastWind
  43.  
  44. bg = _NEWIMAGE(xmax, ymax, 32) 'get bg snap shot area ready
  45. COLOR printC, groundC
  46. setPlayerConstants
  47.     initGame
  48.     WHILE _KEYHIT <> 27 AND p.points <> 5 AND c.points <> 5
  49.         turn = (turn + 1) MOD 2
  50.         IF turn THEN PlayerFire ELSE ComputerFire
  51.     WEND
  52.     _DELAY 3
  53.  
  54. SUB setPlayerConstants
  55.     p.baseX = 10: c.baseX = xmax - 10
  56.     p.baseY = groundY - baseHeight: c.baseY = groundY - baseHeight
  57.     p.baseC = &HFF880000: c.baseC = &HFF000088
  58.     p.cannonAngle = _D2R(360 - 45)
  59.     p.velocity = 7
  60.  
  61. SUB initGame
  62.     p.points = 0: c.points = 0
  63.     MakeMountain xmax / 2, rrnd(200, (xmax - 220) / 2.3), ymax
  64.     LINE (0, groundY)-(xmax, ymax), groundC, BF 'ground
  65.     LINE (p.baseX, p.baseY)-STEP(baseLength, baseHeight), p.baseC, BF
  66.     LINE (c.baseX, c.baseY)-STEP(-baseLength, baseHeight), c.baseC, BF
  67.     SetDisplayWind
  68.     showScore
  69.  
  70. SUB PlayerFire
  71.     DIM kh AS LONG
  72.     p.cannonAngle = 360 - _R2D(p.cannonAngle)
  73.     'IF p.cannonAngle = 360 THEN p.cannonAngle = 0
  74.     LOCATE 44, 1: PRINT "Power: Left/Right   Angle: Up/Down   Fire: Spacebar";
  75.     LOCATE 45, 1: PRINT "Power (0-10): " + TS$(p.velocity);
  76.     LOCATE 46, 1: PRINT "Angle (0-90): " + TS$(p.cannonAngle);
  77.     _DISPLAY
  78.     WHILE kh <> 32
  79.         kh = _KEYHIT
  80.         IF kh = 18432 AND p.cannonAngle + 1 < 90 THEN p.cannonAngle = p.cannonAngle + 1
  81.         IF kh = 20480 AND p.cannonAngle - 1 > 0 THEN p.cannonAngle = p.cannonAngle - 1
  82.         IF kh = 19712 AND (p.velocity + .2 <= 10) THEN p.velocity = p.velocity + .2
  83.         IF kh = 19200 AND (p.velocity - .2 >= .2) THEN p.velocity = p.velocity - .2
  84.         LOCATE 45, 1: PRINT SPACE$(50);
  85.         LOCATE 46, 1: PRINT SPACE$(50);
  86.         LOCATE 45, 1: PRINT "Power (0-10): " + TS$(p.velocity);
  87.         LOCATE 46, 1: PRINT "Angle (0-90): " + TS$(p.cannonAngle);
  88.         _DISPLAY
  89.         _LIMIT 200
  90.     WEND
  91.     LOCATE 44, 1: PRINT SPACE$(60);
  92.     LOCATE 45, 1: PRINT SPACE$(50);
  93.     LOCATE 46, 1: PRINT SPACE$(50);
  94.     p.cannonAngle = _D2R(360 - p.cannonAngle)
  95.     drawCannon cannonC
  96.     b.x = p.baseX + baseLength * COS(p.cannonAngle)
  97.     b.y = p.baseY + baseLength * SIN(p.cannonAngle)
  98.     b.dx = p.velocity * COS(p.cannonAngle)
  99.     b.dy = p.velocity * SIN(p.cannonAngle)
  100.     _DISPLAY
  101.     _PUTIMAGE , 0, bg
  102.     playBall
  103.  
  104. SUB ComputerFire
  105.     IF airX <> lastWind THEN 'new wind blowing make adjustments
  106.         c.cannonAngle = _D2R(180 + 50 - 1000 * airX / 15)
  107.         c.velocity = 7 + 1000 * airX / 9
  108.         lastWind = airX
  109.     END IF
  110.     drawCannon cannonC
  111.     b.x = c.baseX + baseLength * COS(c.cannonAngle)
  112.     b.y = c.baseY + baseLength * SIN(c.cannonAngle)
  113.     b.dx = c.velocity * COS(c.cannonAngle)
  114.     b.dy = c.velocity * SIN(c.cannonAngle)
  115.     LOCATE 45, xmax / 8 - 10: PRINT TS$(c.velocity);
  116.     LOCATE 46, xmax / 8 - 10: PRINT TS$(_R2D(c.cannonAngle) - 180);
  117.     _DISPLAY
  118.     _PUTIMAGE , 0, bg
  119.     playBall
  120.     IF b.x - (p.baseX + .5 * baseLength) > 0 THEN
  121.         c.velocity = c.velocity + (b.x - p.baseX + .5 * baseLength) / 1000
  122.     ELSE
  123.         c.velocity = c.velocity - ((groundY - b.y) + (p.baseX + .5 * baseLength - b.x)) / 1000
  124.     END IF
  125.     LOCATE 45, xmax / 8 - 10: PRINT SPACE$(10);
  126.     LOCATE 46, xmax / 8 - 10: PRINT SPACE$(10);
  127.     _DISPLAY
  128.  
  129. SUB drawCannon (K AS _UNSIGNED LONG)
  130.     IF turn THEN 'players
  131.         LINE (p.baseX, p.baseY)-STEP(baseLength * COS(p.cannonAngle), baseLength * SIN(p.cannonAngle)), K
  132.     ELSE
  133.         LINE (c.baseX, c.baseY)-STEP(baseLength * COS(c.cannonAngle), baseLength * SIN(c.cannonAngle)), K
  134.     END IF
  135.  
  136. SUB playBall
  137.     DIM explosion
  138.     WHILE _KEYHIT <> 27
  139.         _PUTIMAGE , bg, 0 'clear last
  140.         b.dx = b.dx + airX
  141.         b.dy = b.dy + gravity
  142.         b.x = b.x + b.dx
  143.         b.y = b.y + b.dy
  144.         fcirc b.x, b.y, ballRadius, ballC 'draw new
  145.         CenterPrint 45, "                      "
  146.         CenterPrint 45, TS$(b.x) + ", " + TS$(b.y)
  147.         IF b.y >= 0 THEN
  148.             _SOURCE bg 'oh! need this to read point(x, y) off bg !!!!!!!!!1
  149.             IF POINT(b.x, b.y) <> skyC THEN 'explosions
  150.                 FOR explosion = 0 TO 14.5 STEP .25
  151.                     fcirc b.x, b.y, explosion, _RGB32(RND * 255, RND * 255, 0)
  152.                     SOUND 100 + explosion, .25
  153.                     _DISPLAY
  154.                     _DELAY .01
  155.                 NEXT
  156.                 IF POINT(b.x, b.y) = c.baseC THEN ' computer base hit
  157.                     p.points = p.points + 1
  158.                     showScore
  159.                     SOUND 500, 1: SOUND 550, 1: SOUND 600, 1: SOUND 650, 1: SOUND 700, 1
  160.                 ELSEIF POINT(b.x, b.y) = p.baseC THEN ' player base hit
  161.                     c.points = c.points + 1
  162.                     showScore
  163.                     SOUND 700, 1: SOUND 650, 1: SOUND 600, 1: SOUND 550, 1: SOUND 500, 1
  164.                 END IF
  165.                 fcirc b.x, b.y, 3 * ballRadius, skyC
  166.                 'take a snap of new background when ever we blow up
  167.                 CenterPrint 45, "                      "
  168.                 _DISPLAY
  169.                 _PUTIMAGE , 0, bg '<<<< use this after debug
  170.                 EXIT WHILE
  171.             END IF
  172.         END IF
  173.         _DISPLAY
  174.         _LIMIT 30
  175.     WEND
  176.     CenterPrint 45, "                      "
  177.     drawCannon skyC
  178.     _PUTIMAGE , 0, bg
  179.     'take a snap for next player
  180.  
  181. SUB showScore
  182.     DIM s$
  183.     s$ = "Human: " + TS$(p.points) + "  Computer: " + TS$(c.points)
  184.     IF p.points = 5 THEN s$ = s$ + "  YOU WIN!"
  185.     IF c.points = 5 THEN s$ = s$ + "  Computer won."
  186.     CenterPrint 46, s$
  187.     _DISPLAY
  188.  
  189. SUB SetDisplayWind
  190.     airX = rrnd(-20, 20)
  191.     CenterPrint 44, SPACE$(24)
  192.     IF airX < 0 THEN CenterPrint 44, "<<< Wind at: " + TS$(INT(10 * airX) / 10)
  193.     IF airX > 0 THEN CenterPrint 44, "Wind at: " + TS$(INT(10 * airX) / 10) + " >>>"
  194.     airX = airX / 1000
  195.     _DISPLAY
  196.  
  197. SUB MakeMountain (xcenter, maxHeight, mountainbaseY)
  198.     DIM centerDist, i, xc, yc, xl, xr, dir
  199.     LINE (0, 0)-(xmax + 50, ymax + 50), skyC, BF
  200.     centerDist = 15 * RND + 15
  201.     FOR i = 1 TO 5
  202.         IF RND < .5 THEN dir = -1 ELSE dir = 1
  203.         xc = xcenter + dir * centerDist
  204.         yc = maxHeight - centerDist - RND * 25
  205.         xl = xc - rrnd(1.15 * yc, yc)
  206.         xr = xc + rrnd(1.15 * yc, yc)
  207.         IF mountainbaseY - yc < mountainbaseY THEN
  208.             ftri xl, mountainbaseY, xc, mountainbaseY - yc, xr, mountainbaseY, _RGB32(110 - i * 4, RND * 20 + 100 - i * 2, 100 - i * 8)
  209.         ELSE
  210.             EXIT FOR
  211.         END IF
  212.         centerDist = centerDist + 40 * RND + 30
  213.     NEXT
  214.  
  215. SUB ftri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  216.     DIM a&
  217.     a& = _NEWIMAGE(1, 1, 32)
  218.     _DEST a&
  219.     PSET (0, 0), K
  220.     _DEST 0
  221.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  222.     _FREEIMAGE a& '<<< this is important!
  223.  
  224. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  225.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  226.     DIM X AS INTEGER, Y AS INTEGER
  227.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  228.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  229.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  230.     WHILE X > Y
  231.         RadiusError = RadiusError + Y * 2 + 1
  232.         IF RadiusError >= 0 THEN
  233.             IF X <> Y + 1 THEN
  234.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  235.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  236.             END IF
  237.             X = X - 1
  238.             RadiusError = RadiusError - X * 2
  239.         END IF
  240.         Y = Y + 1
  241.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  242.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  243.     WEND
  244.  
  245. FUNCTION rrnd (n1, n2) 'return real number between n1, n2
  246.     rrnd = (n2 - n1) * RND + n1
  247.  
  248. SUB CenterPrint (row, s$)
  249.     LOCATE row, .125 * (xmax - 8 * LEN(s$)) / 2: PRINT s$;
  250.  
  251. FUNCTION TS$ (n)
  252.     TS$ = _TRIM$(STR$(INT(n * 100 + .5) / 100)) 'I have to add .5 for rounding coreectly
  253.  

EDIT: a couple of minor tweaks 2019-07-02
« Last Edit: July 02, 2019, 08:59:44 am by bplus »

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Artillery Wanted
« Reply #49 on: July 02, 2019, 08:25:03 am »
The player needs to be crack shot if winning is the goal. Quite a marksman that enemy player!!
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Artillery Wanted
« Reply #50 on: July 02, 2019, 08:57:05 am »
The player needs to be crack shot if winning is the goal. Quite a marksman that enemy player!!

Yes, you will fall asleep if the enemy doesn't keep you on your toes! Once you get a feel for the shots, it's a pretty even game, it alternate's who goes first after a win.

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Artillery Wanted
« Reply #51 on: July 02, 2019, 05:24:15 pm »
Sooo.... There is a good chance I can be beaten? Hmm... I have an idea for an invulnerability power-up... Activate the ability at 'start up'.... that's it... lol
Logic is the beginning of wisdom.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Artillery Wanted
« Reply #52 on: July 03, 2019, 04:10:57 pm »
Great sound effects. Nice that the mountain size changes each round. I wish the wind would change during the round. Also, there needs to be a display for the power and the angle as they are changed. The AI needs some work, as it constantly attacks the same hole it makes.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Artillery Wanted
« Reply #53 on: July 03, 2019, 04:56:09 pm »
Great sound effects. Nice that the mountain size changes each round. I wish the wind would change during the round. Also, there needs to be a display for the power and the angle as they are changed. The AI needs some work, as it constantly attacks the same hole it makes.

Pete

Hi Pete,

If you are commenting on my MOD (which does have the mountains), the power and angle are displayed and changed with the arrow keys by the human player. (Power and angle displayed when computer is firing but not labeled.)

You are right about AI locking in on Power and Angle setting. I never noticed that happening when testing but sure enough it happened the first time I reviewed it. That's easy enough to fix!

Changing wind? That sucks when you are developing AI, but sure when does wind ever stay exactly the same?
Again easy fix, that would actually fix the other problem of AI locked in a Power and Angle setting, the wind would force change. Good! 2 birds, one stone, I will just change the wind... and label Computer's Power and Angle display.



Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Artillery Wanted
« Reply #54 on: July 04, 2019, 01:57:27 pm »
OK Pete's recommendations adapted, I kind of like the change in the way wind is handled in this MOD:
Code: QB64: [Select]
  1.  
  2. 'Ken:
  3. 'I've always wanted to make this game ever since I started programming in the 80's.
  4. 'This was made using the BASIC and compile language QB64 from QB64.org
  5. 'This was created by Ken G. with much help from others below.
  6. 'Thank you to B+ for posting much of this math code on the QB64.org forum!
  7. 'Also thank you to johnno56 for a little help on the explosions, from the QB64.org forum.
  8. 'It takes the computer a little time to learn how to hit your base.
  9. 'Created on June 25, 2019.
  10.  
  11. 'Hi Ken, I made a couple of changes to the game. Do you recognize it :D  MOD 2019-07-01 B+
  12. ' 2019-07-03 fix items mentioned by Pete label Computer Power and Angle display, apply constant wind change.
  13.  
  14. CONST xmax = 1200, ymax = 740
  15. _TITLE "Ken's Artillery MOD B+  Hey! They only have one cannon ball between the two of them :D" 'mod B+ makeover started 2019-06-25
  16. SCREEN _NEWIMAGE(xmax, ymax, 32)
  17.  
  18. TYPE ball
  19.     x AS SINGLE
  20.     y AS SINGLE
  21.     dx AS SINGLE
  22.     dy AS SINGLE
  23.  
  24. TYPE Contestent
  25.     baseX AS INTEGER 'butt end of cannon
  26.     baseY AS INTEGER
  27.     baseC AS _UNSIGNED LONG
  28.     cannonAngle AS SINGLE
  29.     velocity AS SINGLE
  30.     points AS INTEGER
  31.  
  32. CONST skyC = &HFF9988FF
  33. CONST ballC = &HFF000000
  34. CONST groundC = &HFF405020
  35. CONST cannonC = &HFF884422
  36. CONST printC = &HFFEEDDCC
  37. CONST groundY = 680
  38. CONST gravity = .05
  39. CONST cannonLength = 100
  40. CONST baseLength = 100
  41. CONST baseHeight = 30
  42. CONST ballRadius = 5
  43. DIM SHARED bg AS LONG, c AS Contestent, p AS Contestent, b AS ball, airX, turn, lastWind
  44.  
  45. bg = _NEWIMAGE(xmax, ymax, 32) 'get bg snap shot area ready
  46. COLOR printC, groundC
  47. setPlayerConstants
  48.     initGame
  49.     WHILE _KEYHIT <> 27 AND p.points <> 5 AND c.points <> 5
  50.         SetDisplayWind
  51.         turn = (turn + 1) MOD 2
  52.         IF turn THEN PlayerFire ELSE ComputerFire
  53.     WEND
  54.     _DELAY 3
  55.  
  56. SUB setPlayerConstants
  57.     p.baseX = 10: c.baseX = xmax - 10
  58.     p.baseY = groundY - baseHeight: c.baseY = groundY - baseHeight
  59.     p.baseC = &HFF880000: c.baseC = &HFF000088
  60.     p.cannonAngle = _D2R(360 - 45)
  61.     p.velocity = 7
  62.  
  63. SUB initGame
  64.     p.points = 0: c.points = 0
  65.     MakeMountain xmax / 2, rrnd(200, (xmax - 220) / 2.3), ymax
  66.     LINE (0, groundY)-(xmax, ymax), groundC, BF 'ground
  67.     LINE (p.baseX, p.baseY)-STEP(baseLength, baseHeight), p.baseC, BF
  68.     LINE (c.baseX, c.baseY)-STEP(-baseLength, baseHeight), c.baseC, BF
  69.     airX = rrnd(-20, 20)
  70.     SetDisplayWind
  71.     showScore
  72.  
  73. SUB PlayerFire
  74.     DIM kh AS LONG
  75.     p.cannonAngle = 360 - _R2D(p.cannonAngle)
  76.     'IF p.cannonAngle = 360 THEN p.cannonAngle = 0
  77.     LOCATE 44, 1: PRINT "Power: Left/Right   Angle: Up/Down   Fire: Spacebar";
  78.     LOCATE 45, 10: PRINT "Power (0-10): " + TS$(p.velocity);
  79.     LOCATE 46, 10: PRINT "Angle (0-90): " + TS$(p.cannonAngle);
  80.     _DISPLAY
  81.     WHILE kh <> 32
  82.         kh = _KEYHIT
  83.         IF kh = 18432 AND p.cannonAngle + 1 < 90 THEN p.cannonAngle = p.cannonAngle + 1
  84.         IF kh = 20480 AND p.cannonAngle - 1 > 0 THEN p.cannonAngle = p.cannonAngle - 1
  85.         IF kh = 19712 AND (p.velocity + .2 <= 10) THEN p.velocity = p.velocity + .2
  86.         IF kh = 19200 AND (p.velocity - .2 >= .2) THEN p.velocity = p.velocity - .2
  87.         LOCATE 45, 10: PRINT SPACE$(25);
  88.         LOCATE 46, 10: PRINT SPACE$(25);
  89.         LOCATE 45, 10: PRINT "Power (0-10): " + TS$(p.velocity);
  90.         LOCATE 46, 10: PRINT "Angle (0-90): " + TS$(p.cannonAngle);
  91.         _DISPLAY
  92.         _LIMIT 200
  93.     WEND
  94.     LOCATE 44, 1: PRINT SPACE$(55);
  95.     LOCATE 45, 10: PRINT SPACE$(25);
  96.     LOCATE 46, 10: PRINT SPACE$(25);
  97.     p.cannonAngle = _D2R(360 - p.cannonAngle)
  98.     drawCannon cannonC
  99.     b.x = p.baseX + baseLength * COS(p.cannonAngle)
  100.     b.y = p.baseY + baseLength * SIN(p.cannonAngle)
  101.     b.dx = p.velocity * COS(p.cannonAngle)
  102.     b.dy = p.velocity * SIN(p.cannonAngle)
  103.     _DISPLAY
  104.     _PUTIMAGE , 0, bg
  105.     playBall
  106.  
  107. SUB ComputerFire
  108.     IF ABS(airX - lastWind) > 2 OR c.cannonAngle <= _D2R(5 + 180) THEN 'new game or wind
  109.         c.cannonAngle = _D2R(180 + 50 - airX / 7)
  110.         c.velocity = 7.2 + airX / 10
  111.         lastWind = airX
  112.     END IF
  113.     drawCannon cannonC
  114.     b.x = c.baseX + baseLength * COS(c.cannonAngle)
  115.     b.y = c.baseY + baseLength * SIN(c.cannonAngle)
  116.     b.dx = c.velocity * COS(c.cannonAngle)
  117.     b.dy = c.velocity * SIN(c.cannonAngle)
  118.     LOCATE 45, xmax / 8 - 25: PRINT "Power: " + TS$(c.velocity);
  119.     LOCATE 46, xmax / 8 - 25: PRINT "Angle: " + TS$(_R2D(c.cannonAngle) - 180);
  120.     _DISPLAY
  121.     _PUTIMAGE , 0, bg
  122.     playBall
  123.     IF b.x - (p.baseX + .5 * baseLength) > 0 THEN
  124.         c.velocity = c.velocity + (b.x - p.baseX + .5 * baseLength) / 1000
  125.     ELSE
  126.         c.velocity = c.velocity - ((groundY - b.y) + (p.baseX + .5 * baseLength - b.x)) / 1000
  127.     END IF
  128.     LOCATE 45, xmax / 8 - 25: PRINT SPACE$(25);
  129.     LOCATE 46, xmax / 8 - 25: PRINT SPACE$(25);
  130.     _DISPLAY
  131.  
  132. SUB drawCannon (K AS _UNSIGNED LONG)
  133.     IF turn THEN 'players
  134.         LINE (p.baseX, p.baseY)-STEP(baseLength * COS(p.cannonAngle), baseLength * SIN(p.cannonAngle)), K
  135.     ELSE
  136.         LINE (c.baseX, c.baseY)-STEP(baseLength * COS(c.cannonAngle), baseLength * SIN(c.cannonAngle)), K
  137.     END IF
  138.  
  139. SUB playBall
  140.     DIM explosion
  141.     WHILE _KEYHIT <> 27
  142.         _PUTIMAGE , bg, 0 'clear last
  143.         b.dx = b.dx + airX / 1000
  144.         b.dy = b.dy + gravity
  145.         b.x = b.x + b.dx
  146.         b.y = b.y + b.dy
  147.         fcirc b.x, b.y, ballRadius, ballC 'draw new
  148.         CenterPrint 45, "                      "
  149.         CenterPrint 45, TS$(b.x) + ", " + TS$(b.y)
  150.         IF b.y >= 0 THEN
  151.             _SOURCE bg 'oh! need this to read point(x, y) off bg !!!!!!!!!1
  152.             IF POINT(b.x, b.y) <> skyC THEN 'explosions
  153.                 FOR explosion = 0 TO 14.5 STEP .25
  154.                     fcirc b.x, b.y, explosion, _RGB32(RND * 255, RND * 255, 0)
  155.                     SOUND 100 + explosion, .25
  156.                     _DISPLAY
  157.                     _DELAY .01
  158.                 NEXT
  159.                 IF POINT(b.x, b.y) = c.baseC THEN ' computer base hit
  160.                     p.points = p.points + 1
  161.                     showScore
  162.                     SOUND 500, 1: SOUND 550, 1: SOUND 600, 1: SOUND 650, 1: SOUND 700, 1
  163.                 ELSEIF POINT(b.x, b.y) = p.baseC THEN ' player base hit
  164.                     c.points = c.points + 1
  165.                     showScore
  166.                     SOUND 700, 1: SOUND 650, 1: SOUND 600, 1: SOUND 550, 1: SOUND 500, 1
  167.                 END IF
  168.                 fcirc b.x, b.y, 3 * ballRadius, skyC
  169.                 'take a snap of new background when ever we blow up
  170.                 CenterPrint 45, "                      "
  171.                 _DISPLAY
  172.                 _PUTIMAGE , 0, bg '<<<< use this after debug
  173.                 EXIT WHILE
  174.             END IF
  175.         END IF
  176.         _DISPLAY
  177.         _LIMIT 30
  178.     WEND
  179.     CenterPrint 45, "                      "
  180.     drawCannon skyC
  181.     _PUTIMAGE , 0, bg
  182.  
  183. SUB showScore
  184.     DIM s$
  185.     s$ = "Human: " + TS$(p.points) + "  Computer: " + TS$(c.points)
  186.     IF p.points = 5 THEN s$ = s$ + "  YOU WIN!"
  187.     IF c.points = 5 THEN s$ = s$ + "  Computer won."
  188.     CenterPrint 46, s$
  189.     _DISPLAY
  190.  
  191. SUB SetDisplayWind
  192.     airX = airX + rrnd(-1.5, 1.5)
  193.     IF airX < -20 THEN airX = -19.99
  194.     IF airX > 20 THEN airX = 19.99
  195.     CenterPrint 44, SPACE$(24)
  196.     IF airX < 0 THEN CenterPrint 44, "<<< Wind at: " + TS$(airX)
  197.     IF airX > 0 THEN CenterPrint 44, "Wind at: " + TS$(airX) + " >>>"
  198.     _DISPLAY
  199.  
  200. SUB MakeMountain (xcenter, maxHeight, mountainbaseY)
  201.     DIM centerDist, i, xc, yc, xl, xr, dir
  202.     LINE (0, 0)-(xmax + 50, ymax + 50), skyC, BF
  203.     centerDist = 15 * RND + 15
  204.     FOR i = 1 TO 5
  205.         IF RND < .5 THEN dir = -1 ELSE dir = 1
  206.         xc = xcenter + dir * centerDist: yc = maxHeight - centerDist - RND * 25
  207.         xl = xc - rrnd(1.15 * yc, yc): xr = xc + rrnd(1.15 * yc, yc)
  208.         IF mountainbaseY - yc < mountainbaseY THEN
  209.             ftri xl, mountainbaseY, xc, mountainbaseY - yc, xr, mountainbaseY, _RGB32(110 - i * 4, RND * 20 + 100 - i * 2, 100 - i * 8)
  210.         ELSE
  211.             EXIT FOR
  212.         END IF
  213.         centerDist = centerDist + 40 * RND + 30
  214.     NEXT
  215.  
  216. SUB ftri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  217.     DIM a&
  218.     a& = _NEWIMAGE(1, 1, 32)
  219.     _DEST a&
  220.     PSET (0, 0), K
  221.     _DEST 0
  222.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  223.     _FREEIMAGE a& '<<< this is important!
  224.  
  225. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  226.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  227.     DIM X AS INTEGER, Y AS INTEGER
  228.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  229.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  230.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  231.     WHILE X > Y
  232.         RadiusError = RadiusError + Y * 2 + 1
  233.         IF RadiusError >= 0 THEN
  234.             IF X <> Y + 1 THEN
  235.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  236.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  237.             END IF
  238.             X = X - 1
  239.             RadiusError = RadiusError - X * 2
  240.         END IF
  241.         Y = Y + 1
  242.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  243.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  244.     WEND
  245.  
  246. FUNCTION rrnd (n1, n2) 'return real number between n1, n2
  247.     rrnd = (n2 - n1) * RND + n1
  248.  
  249. SUB CenterPrint (row, s$)
  250.     LOCATE row, .125 * (xmax - 8 * LEN(s$)) / 2: PRINT s$;
  251.  
  252. FUNCTION TS$ (n)
  253.     TS$ = _TRIM$(STR$(INT(n * 100 + .5) / 100)) 'I have to add .5 for rounding coreectly
  254.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Artillery Wanted
« Reply #55 on: July 04, 2019, 02:22:47 pm »
The AI is much better now! I won a couple, and lost a couple. Nice job!

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/