Author Topic: Invaders bplus style  (Read 7010 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Invaders bplus style
« Reply #15 on: July 29, 2019, 02:49:24 pm »
Storyboard:  Aliens invade the world!

After intercepting our broadcast transmissions of Tom and Jerry shows, Aliens decide that mice are the dominant life-form upon our planet.  Though their ships are circular in design (as all good UFOs should be), they have a “mouse cloaking device” which produces a 3-dimensional hologram around the ship.  Attacking the head causes the bullet to pass harmlessly through the hologram, doing zero damage to the actual alien spaceship.  Only by targeting the rear of the hologram can actual damage be accrued to destroy the alien ship...

Steve, you're hired! :)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Invaders bplus style
« Reply #16 on: July 29, 2019, 11:23:16 pm »
OK another overhaul. Along with changes talked about earlier I added sound effects.

"Game Over" across the screen is very effective signal for cease fire. And I ask for go again when exiting the Top Ten sub. This saves player from having to do 2 key press answers back to back.

There is a whole different method to calculation of hits to ships, ironically it is like an idea Codeguy had that I shot down because it was flawed for the intended app. Here, because the the shots are straight up and down it works and probably much faster.

Man I got stuck with a bug that was allowing a shot ship to be shot over and over. Took me awhile to loose that bug, really hacked up the code to loose it. It seems to be gone now...

You might want to delete old Top Ten file because scoring is different.

So here is b0.3:
Code: QB64: [Select]
  1. _TITLE "Invaders b0_3" 'Bplus started 2019-07-27 inspired by Ken's fun program series
  2.  
  3. ' 2019-07-29 from feed back fix game ending with big "Game Over" sign and delay before Top Ten.
  4. ' Show score to compare with Top Ten Numbers.
  5. ' Change the way hits are calculated, use method that avoids distance function or ABS.
  6. ' Change TopTen sub to TopTenGoAgain$ function to also get Play Again reply.
  7.  
  8. 'OK let's start charging for bullets! 1 point per... and do a hit % to reward skillful shooting
  9. 'change BEEPs to SOUNDS, add more to report, Game Over signals end of game, TopTen does go again.
  10.  
  11. CONST xmax = 1200, ymax = 720, PI = 3.141592653589793, PD2 = 1.570796326794897, PT2 = 6.283185307
  12. SCREEN _NEWIMAGE(xmax, ymax, 32)
  13. _SCREENMOVE 100, 20
  14.  
  15. TYPE typeO
  16.     x AS SINGLE
  17.     y AS SINGLE
  18.     xc AS SINGLE
  19.     yc AS SINGLE
  20.     dx AS SINGLE
  21.     dy AS SINGLE
  22.     a AS SINGLE
  23.     lastX AS SINGLE
  24.     lastY AS SINGLE
  25.     v1 AS SINGLE
  26.     v2 AS SINGLE
  27.     size AS SINGLE
  28.     live AS INTEGER
  29.     exploding AS INTEGER
  30.     lastShot AS SINGLE
  31.     c AS _UNSIGNED LONG
  32.  
  33. DIM SHARED o(100) AS typeO, shoot AS INTEGER, points AS INTEGER, bullets AS INTEGER, hits AS INTEGER
  34. DIM i AS INTEGER, j AS INTEGER, kh AS LONG, red AS INTEGER, again$
  35.     setUp
  36.     WHILE o(0).live
  37.         LINE (0, 0)-(xmax, ymax), _RGBA(0, 0, 0, 255), BF
  38.         kh = _KEYHIT
  39.         IF kh = 32 THEN shoot = -1
  40.         IF kh = 18432 THEN o(0).dx = 0
  41.         IF kh = 19200 THEN o(0).dx = -3
  42.         IF kh = 19712 THEN o(0).dx = 3
  43.         report
  44.  
  45.         'dead ships and bullets? but still exploding  this separated out because ships are getting hit more than once while exploding
  46.         FOR i = 1 TO 3
  47.             IF o(i).exploding THEN
  48.                 o(i).exploding = o(i).exploding - 1
  49.                 IF o(i).exploding = 0 THEN
  50.                     newEnemy i
  51.                 ELSE 'draw explosion
  52.                     SOUND 1000 - o(i).size * 3 + (21 - o(i).exploding) * 10, .1
  53.                     red = rand(60, 255)
  54.                     fcirc o(i).x, o(i).y, o(i).exploding * 3, _RGB32(red, rand(0, red), 0)
  55.                 END IF
  56.             END IF 'i = x
  57.         NEXT
  58.         'bullets
  59.         FOR i = 4 TO 100
  60.             IF o(i).exploding THEN
  61.                 o(i).exploding = o(i).exploding - 1
  62.                 SOUND 1600, .05
  63.                 red = rand(60, 255)
  64.                 fcirc o(i).x, o(i).y, o(i).exploding, _RGB32(red, rand(0, red), 0)
  65.             END IF
  66.         NEXT
  67.  
  68.         FOR i = 0 TO 100
  69.             IF o(i).live <> 0 THEN 'draw everything, update positions, check updated position
  70.                 IF i = 0 THEN 'shooter
  71.                     IF o(0).exploding = 0 THEN
  72.                         drawshooter o(i).x
  73.                         IF shoot AND (TIMER(.001) - o(0).lastShot) > .1 THEN '.2 is this the cause of hitting a ship twice?
  74.                             newBullet 0, o(0).x, ymax - 60
  75.                         END IF
  76.                         IF o(i).x + o(i).dx > 0 AND o(i).x + o(i).dx < xmax THEN
  77.                             o(i).x = o(i).x + o(i).dx
  78.                         ELSE
  79.                             o(i).dx = -o(i).dx
  80.                         END IF
  81.                     ELSEIF o(0).exploding THEN 'exploded enough
  82.                         o(i).exploding = o(i).exploding - 1
  83.                         IF o(i).exploding = 0 THEN 'no longer exploding
  84.                             o(0).live = o(0).live - 1
  85.                             IF o(0).live = 0 THEN
  86.                                 fcirc o(0).x, ymax - 75, 50, &HFF770000
  87.                                 report
  88.                                 EXIT FOR
  89.                             ELSE
  90.                                 drawshooter o(i).x
  91.                             END IF
  92.                         ELSE 'exploding
  93.                             SOUND 400 + o(0).exploding * 7, .3
  94.                             red = rand(60, 255)
  95.                             fcirc o(0).x, ymax - 75, o(0).exploding * 6, _RGB32(red, rand(0, red), 0)
  96.                         END IF
  97.                     END IF
  98.  
  99.                 ELSEIF i > 0 AND i < 4 THEN 'enemy ships
  100.                     'update coodinates
  101.                     o(i).lastX = o(i).x: o(i).lastY = o(i).y
  102.                     o(i).x = o(i).xc + 150 * (COS(o(i).a) + COS(o(i).v1 * o(i).a) / 2 + SIN(o(i).v2 * o(i).a) / 3)
  103.                     o(i).y = o(i).yc + 150 * (SIN(o(i).a) + SIN(o(i).v1 * o(i).a) / 2 + COS(o(i).v2 * o(i).a) / 3)
  104.                     drawRat i
  105.                     o(i).a = o(i).a + PI / 1440
  106.                     IF o(i).xc + o(i).dx > 0 AND o(i).xc + o(i).dx < xmax THEN
  107.                         o(i).xc = o(i).xc + o(i).dx
  108.                     ELSE
  109.                         o(i).dx = -o(i).dx
  110.                     END IF
  111.                     'drop bombs
  112.                     IF TIMER(.001) - o(i).lastShot > 3 THEN
  113.                         newBullet i, o(i).x, o(i).y + o(i).size
  114.                     END IF
  115.  
  116.                 ELSEIF i > 3 AND i < 101 THEN 'bullets
  117.                     fcirc o(i).x, o(i).y, o(i).size, o(i).c
  118.                     IF o(i).y + o(i).dy > 0 AND o(i).y + o(i).dy < ymax THEN
  119.                         IF o(i).dy > 0 THEN o(i).dy = o(i).dy + .1 'gravity
  120.                         o(i).y = o(i).y + o(i).dy
  121.                     ELSE
  122.                         o(i).live = 0
  123.                     END IF
  124.  
  125.                     'did this bullet hit anything
  126.                     IF o(i).dy > 0 THEN 'did it hit the shooter
  127.                         IF (o(0).x - o(0).size <= o(i).x) AND (o(i).x <= o(0).x + o(0).size) THEN
  128.                             IF (o(0).y - o(0).size <= o(i).y) AND (o(i).y <= o(0).y + o(0).size + 20) THEN
  129.                                 IF o(0).exploding = 0 AND o(0).live THEN
  130.                                     SOUND 400 + 5 * 20, .1
  131.                                     o(0).exploding = 20 'signal exploding
  132.                                     o(i).live = 0 'kill bullet
  133.                                 END IF
  134.                             END IF
  135.                         END IF
  136.                     ELSEIF o(i).dy < 0 THEN 'did it hit the enemy?
  137.                         FOR j = 1 TO 3
  138.                             IF (o(j).x - o(j).size <= o(i).x) AND (o(i).x <= o(j).x + o(j).size) THEN 'is x right
  139.                                 IF (o(j).y - o(j).size - 5 < o(i).y) AND (o(i).y <= o(j).y + o(j).size + 5) THEN 'is y right
  140.                                     IF o(j).exploding = 0 AND o(j).live <> 0 THEN 'ship not exploding already
  141.                                         o(j).exploding = 20
  142.                                         SOUND 800 - o(i).size * 3, .1
  143.                                         points = points + 50 - o(j).size
  144.                                         hits = hits + 1
  145.                                         o(i).live = 0: o(j).live = 0 'kill bullet and ship
  146.                                     END IF 'if not exploding already
  147.                                 END IF 'if y is right
  148.                             END IF 'if x is right
  149.                         NEXT
  150.  
  151.                         'finally bullet versus bullet!!  remember these bullets (i) are headed up
  152.                         FOR j = i + 1 TO 100 ' find only those going in different directions
  153.                             IF o(j).dy > 0 THEN 'look for bullets headed down
  154.                                 IF o(j).live THEN
  155.                                     IF o(j).x - 3 <= o(i).x AND o(i).x <= o(j).x + 3 THEN 'is x right
  156.                                         IF (o(j).y - 8 <= o(i).y) AND (o(i).y <= o(j).y + o(j).dy) THEN 'is y right  why 16 gravity accums
  157.                                             fcirc o(i).x, o(i).y, 200, &HFFFFFFFF
  158.                                             o(i).live = 0: o(j).live = 0
  159.                                             o(i).exploding = 10
  160.                                             SOUND 2800, 1
  161.                                         END IF 'if y is right
  162.                                     END IF 'if x is right
  163.                                 END IF 'both still live
  164.                             END IF 'bullets going in opposite directions
  165.                         NEXT
  166.                     END IF 'bullet hit
  167.                 END IF 'shooter
  168.             END IF 'live
  169.         NEXT
  170.         _DISPLAY
  171.         _LIMIT 60
  172.     WEND
  173.     cText xmax / 2, ymax / 2, 128, &HFFFF5500, "Game Over"
  174.     _DISPLAY: _DELAY 2.5: _KEYCLEAR ' stop hammer'n the keys!  ;-))
  175.     again$ = topTenGoAgain$(points)
  176. LOOP UNTIL LEN(again$)
  177.  
  178. SUB setUp
  179.     'obj 0 is the player's shooter
  180.     DIM i AS INTEGER
  181.     ERASE o
  182.     points = 0: bullets = 0: hits = 0
  183.     o(0).x = xmax / 2: o(0).y = ymax - 60: o(0).size = 50
  184.     o(0).live = 10
  185.     FOR i = 1 TO 3 'enemy
  186.         newEnemy i
  187.     NEXT
  188.  
  189. SUB newEnemy (i)
  190.     DIM r, g, b
  191.     IF i < 1 OR i > 3 THEN BEEP: EXIT SUB
  192.     o(i).a = RND * PT2: o(i).live = 1: o(i).v1 = rand(2, 19): o(i).v2 = rand(2, 19)
  193.     r = rand(128, 255): g = rand(0, .5 * r): b = rand(0, .5 * g)
  194.     o(i).size = rand(10, 45): o(i).c = _RGB32(r, g, b)
  195.     o(i).yc = ymax / 2 - 30: o(i).lastShot = TIMER(.003) + i
  196.     IF RND < .5 THEN
  197.         o(i).xc = 0: o(i).dx = 1
  198.     ELSE
  199.         o(i).xc = xmax: o(i).dx = -1
  200.     END IF
  201.  
  202. SUB newBullet (who, x, y)
  203.     DIM ii AS INTEGER
  204.     FOR ii = 4 TO 100 'find bullet slot
  205.         IF o(ii).live = 0 AND o(ii).exploding = 0 THEN EXIT FOR 'got slot
  206.     NEXT
  207.     IF ii >= 4 AND ii <= 100 THEN
  208.         o(ii).x = x: o(ii).y = y: o(ii).size = 2: o(ii).live = -1: o(who).lastShot = TIMER(.001)
  209.         IF shoot AND who = 0 THEN
  210.             o(ii).dy = -10: o(ii).c = &HFFFFFFFF: bullets = bullets + 1: points = points - 1
  211.             SOUND 700, .3
  212.         ELSEIF who > 0 AND who < 4 THEN
  213.             o(ii).dy = 1: o(ii).c = &HFFFFFF00
  214.             SOUND 300, 1
  215.         END IF
  216.     END IF
  217.     shoot = 0
  218.  
  219. SUB report
  220.     DIM s$
  221.     s$ = "Lives: " + TS$(o(0).live) + "           Bullets: " + TS$(bullets) + "    Hits: " + TS$(hits) + "    Eff% "
  222.     IF bullets = 0 THEN s$ = s$ + "**" ELSE s$ = s$ + TS$(100 * hits \ bullets)
  223.     s$ = s$ + "           Points: " + TS$(points)
  224.     cText xmax / 2, 30, 20, &HFF009900, s$
  225.  
  226. SUB drawRat (i)
  227.     DIM noseX, noseY, neckX, neckY, tailX, tailY, earLX, earLY, earRX, earRY, wX, wY, rh
  228.     rh = _ATAN2(o(i).y - o(i).lastY, o(i).x - o(i).lastX)
  229.     noseX = o(i).x + 2 * o(i).size * COS(rh)
  230.     noseY = o(i).y + 2 * o(i).size * SIN(rh)
  231.     neckX = o(i).x + .75 * o(i).size * COS(rh)
  232.     neckY = o(i).y + .75 * o(i).size * SIN(rh)
  233.     tailX = o(i).x + 2 * o(i).size * COS(rh + _PI)
  234.     tailY = o(i).y + 2 * o(i).size * SIN(rh + _PI)
  235.     earLX = o(i).x + o(i).size * COS(rh - _PI(1 / 12))
  236.     earLY = o(i).y + o(i).size * SIN(rh - _PI(1 / 12))
  237.     earRX = o(i).x + o(i).size * COS(rh + _PI(1 / 12))
  238.     earRY = o(i).y + o(i).size * SIN(rh + _PI(1 / 12))
  239.     fcirc o(i).x, o(i).y, .65 * o(i).size, o(i).c
  240.     fcirc neckX, neckY, o(i).size * .3, o(i).c
  241.     fTri noseX, noseY, earLX, earLY, earRX, earRY, o(i).c
  242.     fcirc earLX, earLY, o(i).size * .3, o(i).c
  243.     fcirc earRX, earRY, o(i).size * .3, o(i).c
  244.     wX = .5 * o(i).size * COS(rh - _PI(11 / 18))
  245.     wY = .5 * o(i).size * SIN(rh - _PI(11 / 18))
  246.     ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, o(i).c
  247.     wX = .5 * o(i).size * COS(rh - _PI(7 / 18))
  248.     wY = .5 * o(i).size * SIN(rh - _PI(7 / 18))
  249.     ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, o(i).c
  250.     ln o(i).x, o(i).y, tailX, tailY, o(i).c
  251.  
  252. SUB drawshooter (x) 'simple red iso triangle pointed towards radianAngle
  253.     DIM y1, y2, x1, x2
  254.     'calculate 3 points of triangle shooter
  255.     y1 = ymax - 10
  256.     y2 = ymax - 60
  257.     x1 = x - 50
  258.     x2 = x + 50
  259.     fTri x, y1, x1, ymax, x, y2, _RGB(0, 0, 200)
  260.     fTri x, y1, x2, ymax, x, y2, _RGB(0, 0, 200)
  261.     ln x, y1, x1, ymax, _RGB32(255, 255, 128)
  262.     ln x1, ymax, x, y2, _RGB32(255, 255, 128)
  263.     ln x, y1, x2, ymax, _RGB32(255, 255, 128)
  264.     ln x2, ymax, x, y2, _RGB32(255, 255, 128)
  265.     ln x, y1, x, y2, _RGB32(255, 255, 128)
  266.  
  267. ' This FUNCTION creates a file in the same folder as your .bas source or .exe
  268. 'EDIT: 2019-07-29 change to FUNCTION to combine Top Ten update functions with Go Again reply.
  269. FUNCTION topTenGoAgain$ (compareScore AS INTEGER)
  270.     DIM fName$, n AS INTEGER, names$(1 TO 10), scores(1 TO 10), name$, score AS INTEGER
  271.     DIM settleScore AS INTEGER, i AS INTEGER
  272.     fName$ = "Top 10 Scores.txt" '<<<  since this is toolbox code change this as needed for app
  273.     CLS: PRINT: PRINT "Your score was:"; compareScore: PRINT: PRINT "Top Ten Scorers and Scores:"
  274.     IF _FILEEXISTS(fName$) THEN
  275.         OPEN fName$ FOR INPUT AS #1
  276.         WHILE EOF(1) = 0 AND n < 10
  277.             n = n + 1
  278.             INPUT #1, name$
  279.             INPUT #1, score
  280.             IF compareScore >= score AND settleScore = 0 THEN
  281.                 PRINT "You have made the Top Ten!"
  282.                 INPUT "Type your name here: ", names$(n)
  283.                 scores(n) = compareScore
  284.                 settleScore = -1
  285.                 n = n + 1
  286.                 IF n <= 10 THEN names$(n) = name$: scores(n) = score
  287.             ELSE
  288.                 scores(n) = score: names$(n) = name$
  289.             END IF
  290.         WEND
  291.         CLOSE #1
  292.         IF n < 10 AND settleScore = 0 THEN
  293.             PRINT "There is a slot open for your name and score."
  294.             INPUT "Type your name here: ", name$
  295.             IF name$ <> "" THEN n = n + 1: names$(n) = name$: scores(n) = compareScore
  296.         END IF
  297.         OPEN fName$ FOR OUTPUT AS #1
  298.         IF n > 10 THEN n = 10
  299.         FOR i = 1 TO n
  300.             PRINT #1, names$(i): PRINT #1, scores(i)
  301.             PRINT i, names$(i), scores(i)
  302.         NEXT
  303.         CLOSE #1
  304.     ELSE
  305.         PRINT "You are first into file!"
  306.         INPUT "Type your name here:"; name$
  307.         OPEN fName$ FOR OUTPUT AS #1
  308.         PRINT #1, name$: PRINT #1, compareScore
  309.         CLOSE #1
  310.     END IF
  311.     PRINT: INPUT "Press <Enter> to play again, <q (or any) + Enter> to quit... "; topTenGoAgain$
  312.  
  313. 'center the text on midpoint x, y
  314. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  315.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  316.     fg = _DEFAULTCOLOR
  317.     'screen snapshot
  318.     cur& = _DEST
  319.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  320.     _DEST I&
  321.     COLOR K, _RGBA32(0, 0, 0, 0)
  322.     _PRINTSTRING (0, 0), txt$
  323.     mult = textHeight / 16
  324.     xlen = LEN(txt$) * 8 * mult
  325.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  326.     COLOR fg
  327.     _FREEIMAGE I&
  328.  
  329.     TS$ = _TRIM$(STR$(n))
  330.  
  331. FUNCTION rand% (lo%, hi%)
  332.     rand% = INT(RND * (hi% - lo% + 1)) + lo%
  333.  
  334. ' found at [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]:    http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
  335. SUB fTri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  336.     DIM a&
  337.     a& = _NEWIMAGE(1, 1, 32)
  338.     _DEST a&
  339.     PSET (0, 0), K
  340.     _DEST 0
  341.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  342.     _FREEIMAGE a& '<<< this is important!
  343.  
  344. SUB ln (x1, y1, x2, y2, K AS _UNSIGNED LONG) 'box frame
  345.     LINE (x1, y1)-(x2, y2), K
  346.  
  347. 'from Steve Gold standard
  348. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  349.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  350.     DIM X AS INTEGER, Y AS INTEGER
  351.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  352.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  353.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  354.     WHILE X > Y
  355.         RadiusError = RadiusError + Y * 2 + 1
  356.         IF RadiusError >= 0 THEN
  357.             IF X <> Y + 1 THEN
  358.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  359.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  360.             END IF
  361.             X = X - 1
  362.             RadiusError = RadiusError - X * 2
  363.         END IF
  364.         Y = Y + 1
  365.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  366.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  367.     WEND
  368.  

Oh yeah, bullet versus bullet has been added and is working. A rare event but when it happens you will see a white flash and high "metallic" ping! If you have bombs coming your way that you can't escape, try shooting at them.
« Last Edit: July 29, 2019, 11:26:17 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Invaders bplus style
« Reply #17 on: July 30, 2019, 02:42:59 pm »
Great job! I was thinking about adding multi-shots on mine but the only way I know how to do it would be using an array, like a 10 shot limit on the screen and then start over. But in my game I think it would be too easy. But I like how you added a % of how many times you hit the rat.
Also, the reason why I have a built-in Top Ten is to see if you can beat them, to make it a challenge. :) If you wish to use a built-in Top Ten, feel free to use any of my code. Mine makes the extra file even if you don't have it already, like yours. 

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Invaders bplus style
« Reply #18 on: July 30, 2019, 03:07:37 pm »
Hi Ken,

I already took your Top Ten, modified the heck out of it, in a Sub, and posted code for anyone's Toolbox of Subs and Functions. I have fixed 2 bugs for it and added a new function to it, it returns the user reply about going again. The function and demo are here: https://www.qb64.org/forum/index.php?topic=1511.msg107586#msg107586

Yes, Top Ten is great motivator to challenge people to beat their best performance.

Yes, I am tracking 97 bullets in an array of most all the game objects. Bullets are just like ships and shooters in data you need to track them. My bullets are recycled, they go live when activated and when they go out of bounds or hit a ship, shooter or themselves, they are deactivated, addresses ready to use again somewhere else.

I was going to use hit% as reward for not machine gunning the rats, but what the heck these rats are nuclear toxins and need to be removed before the world is waist deep in their radioactive waste. ;-))
« Last Edit: July 30, 2019, 03:09:29 pm by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Invaders bplus style
« Reply #19 on: July 30, 2019, 04:13:56 pm »
Hi
I find very cool also sound effects. Great
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Invaders bplus style
« Reply #20 on: July 31, 2019, 08:37:31 am »
Thanks TempodiBasic,

Here is a game where Top Ten really works. The sound effects definitely add to playing pleasure too.

Last night I played this game for some time, even seeing bullet versus bullet happen 2 times in a row (when I get tired of sniper shots or get in a jam, I start machine gunning... ) and I am thinking the idea I had for a Boss Pause, a break in intense action, is still good but what I had planned might not work... so don't hold your breath for new versions this one is going on back burner to stew for awhile.

Actually I am considering modifying a Ping Pong and a Breakout version with this style shooter / paddle action.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Invaders bplus style
« Reply #21 on: July 31, 2019, 11:31:11 am »
Ah, you ratcheted it up another notch! It plays like a real arcade game now. Mice! I mean nice!

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: Invaders bplus style
« Reply #22 on: July 31, 2019, 11:52:08 am »
Ah, you ratcheted it up another notch! It plays like a real arcade game now. Mice! I mean nice!

Pete

The drawings are more mouse than rat. I watched America's Got Talent last night and there was a lady with a rat act. The rat's ears are nothing like the drawing which is pretty Mickey Mouse, I admit. Anyway I am feeling a little remorse for adding to rat's bad rep stereo type, so remember guys these rats/mice are "Maze Refugees" who got into a next door nuclear waste dump and mutated into very dangerous sideways flying aliens with deadly excrement that... well, I guess a backstory is needed for those who might love rats... and might take offense to this game and with all the shootings in the news... wait, that's what the aliens want us to believe, that these are rats or mice! ;-))

BTW Why do they call it "America's Got Talent"? These people are coming from allot of places other than USA. It should be called: The World's Got Talent ( and allot of very unusual people!)
« Last Edit: July 31, 2019, 11:56:35 am by bplus »

Marked as best answer by bplus on July 31, 2019, 05:09:49 pm

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Invaders bplus style
« Reply #23 on: July 31, 2019, 09:09:09 pm »
Overhauled the Top Ten screen:

Code: QB64: [Select]
  1. _TITLE "Invaders b0_4" 'Bplus started 2019-07-27 inspired by Ken's fun program series
  2.  
  3. ' 2019-07-29 b0_3 from feed back fix game ending with big "Game Over" sign and delay before Top Ten.
  4. ' Show score to compare with Top Ten Numbers.
  5. ' Change the way hits are calculated, use method that avoids distance function or ABS.
  6. ' Change TopTen sub to TopTenGoAgain$ function to also get Play Again reply.
  7. ' OK let's start charging for bullets! 1 point per... and do a hit % to reward skillful shooting
  8. ' change BEEPs to SOUNDS, add more to report, Game Over signals end of game, TopTen does go again also.
  9.  
  10. ' 2019-07-31 Rework the Top Ten screen using Text sub routine that I want to demo in "another one for the Toolbox."
  11. ' This new TopTen function now uses inputBox$ which added a ton of lines to the program!
  12.  
  13.  
  14. CONST xmax = 1200, ymax = 720, PI = 3.141592653589793, PD2 = 1.570796326794897, PT2 = 6.283185307
  15. SCREEN _NEWIMAGE(xmax, ymax, 32)
  16. _SCREENMOVE 100, 20
  17.  
  18. TYPE typeO
  19.     x AS SINGLE
  20.     y AS SINGLE
  21.     xc AS SINGLE
  22.     yc AS SINGLE
  23.     dx AS SINGLE
  24.     dy AS SINGLE
  25.     a AS SINGLE
  26.     lastX AS SINGLE
  27.     lastY AS SINGLE
  28.     v1 AS SINGLE
  29.     v2 AS SINGLE
  30.     size AS SINGLE
  31.     live AS INTEGER
  32.     exploding AS INTEGER
  33.     lastShot AS SINGLE
  34.     c AS _UNSIGNED LONG
  35.  
  36. DIM SHARED o(100) AS typeO, shoot AS INTEGER, points AS INTEGER, bullets AS INTEGER, hits AS INTEGER
  37. DIM i AS INTEGER, j AS INTEGER, kh AS LONG, red AS INTEGER, again$
  38.     setUp
  39.     WHILE o(0).live
  40.         LINE (0, 0)-(xmax, ymax), _RGBA(0, 0, 0, 255), BF
  41.         kh = _KEYHIT
  42.         IF kh = 32 THEN shoot = -1
  43.         IF kh = 18432 THEN o(0).dx = 0
  44.         IF kh = 19200 THEN o(0).dx = -3
  45.         IF kh = 19712 THEN o(0).dx = 3
  46.         report
  47.  
  48.         'dead ships and bullets? but still exploding  this separated out because ships are getting hit more than once while exploding
  49.         FOR i = 1 TO 3
  50.             IF o(i).exploding THEN
  51.                 o(i).exploding = o(i).exploding - 1
  52.                 IF o(i).exploding = 0 THEN
  53.                     newEnemy i
  54.                 ELSE 'draw explosion
  55.                     SOUND 1000 - o(i).size * 3 + (21 - o(i).exploding) * 10, .1
  56.                     red = rand(60, 255)
  57.                     fcirc o(i).x, o(i).y, o(i).exploding * 3, _RGB32(red, rand(0, red), 0)
  58.                 END IF
  59.             END IF 'i = x
  60.         NEXT
  61.         'bullets
  62.         FOR i = 4 TO 100
  63.             IF o(i).exploding THEN
  64.                 o(i).exploding = o(i).exploding - 1
  65.                 SOUND 1600, .05
  66.                 red = rand(60, 255)
  67.                 fcirc o(i).x, o(i).y, o(i).exploding, _RGB32(red, rand(0, red), 0)
  68.             END IF
  69.         NEXT
  70.  
  71.         FOR i = 0 TO 100
  72.             IF o(i).live <> 0 THEN 'draw everything, update positions, check updated position
  73.                 IF i = 0 THEN 'shooter
  74.                     IF o(0).exploding = 0 THEN
  75.                         drawshooter o(i).x
  76.                         IF shoot AND (TIMER(.001) - o(0).lastShot) > .1 THEN '.2 is this the cause of hitting a ship twice?
  77.                             newBullet 0, o(0).x, ymax - 60
  78.                         END IF
  79.                         IF o(i).x + o(i).dx > 0 AND o(i).x + o(i).dx < xmax THEN
  80.                             o(i).x = o(i).x + o(i).dx
  81.                         ELSE
  82.                             o(i).dx = -o(i).dx
  83.                         END IF
  84.                     ELSEIF o(0).exploding THEN 'exploded enough
  85.                         o(i).exploding = o(i).exploding - 1
  86.                         IF o(i).exploding = 0 THEN 'no longer exploding
  87.                             o(0).live = o(0).live - 1
  88.                             IF o(0).live = 0 THEN
  89.                                 fcirc o(0).x, ymax - 75, 50, &HFF770000
  90.                                 report
  91.                                 EXIT FOR
  92.                             ELSE
  93.                                 drawshooter o(i).x
  94.                             END IF
  95.                         ELSE 'exploding
  96.                             SOUND 400 + o(0).exploding * 7, .3
  97.                             red = rand(60, 255)
  98.                             fcirc o(0).x, ymax - 75, o(0).exploding * 6, _RGB32(red, rand(0, red), 0)
  99.                         END IF
  100.                     END IF
  101.  
  102.                 ELSEIF i > 0 AND i < 4 THEN 'enemy ships
  103.                     'update coodinates
  104.                     o(i).lastX = o(i).x: o(i).lastY = o(i).y
  105.                     o(i).x = o(i).xc + 150 * (COS(o(i).a) + COS(o(i).v1 * o(i).a) / 2 + SIN(o(i).v2 * o(i).a) / 3)
  106.                     o(i).y = o(i).yc + 150 * (SIN(o(i).a) + SIN(o(i).v1 * o(i).a) / 2 + COS(o(i).v2 * o(i).a) / 3)
  107.                     drawRat i
  108.                     o(i).a = o(i).a + PI / 1440
  109.                     IF o(i).xc + o(i).dx > 0 AND o(i).xc + o(i).dx < xmax THEN
  110.                         o(i).xc = o(i).xc + o(i).dx
  111.                     ELSE
  112.                         o(i).dx = -o(i).dx
  113.                     END IF
  114.                     'drop bombs
  115.                     IF TIMER(.001) - o(i).lastShot > 3 THEN
  116.                         newBullet i, o(i).x, o(i).y + o(i).size
  117.                     END IF
  118.  
  119.                 ELSEIF i > 3 AND i < 101 THEN 'bullets
  120.                     fcirc o(i).x, o(i).y, o(i).size, o(i).c
  121.                     IF o(i).y + o(i).dy > 0 AND o(i).y + o(i).dy < ymax THEN
  122.                         IF o(i).dy > 0 THEN o(i).dy = o(i).dy + .1 'gravity
  123.                         o(i).y = o(i).y + o(i).dy
  124.                     ELSE
  125.                         o(i).live = 0
  126.                     END IF
  127.  
  128.                     'did this bullet hit anything
  129.                     IF o(i).dy > 0 THEN 'did it hit the shooter
  130.                         IF (o(0).x - o(0).size <= o(i).x) AND (o(i).x <= o(0).x + o(0).size) THEN
  131.                             IF (o(0).y - o(0).size <= o(i).y) AND (o(i).y <= o(0).y + o(0).size + 20) THEN
  132.                                 IF o(0).exploding = 0 AND o(0).live THEN
  133.                                     SOUND 400 + 5 * 20, .1
  134.                                     o(0).exploding = 20 'signal exploding
  135.                                     o(i).live = 0 'kill bullet
  136.                                 END IF
  137.                             END IF
  138.                         END IF
  139.                     ELSEIF o(i).dy < 0 THEN 'did it hit the enemy?
  140.                         FOR j = 1 TO 3
  141.                             IF (o(j).x - o(j).size <= o(i).x) AND (o(i).x <= o(j).x + o(j).size) THEN 'is x right
  142.                                 IF (o(j).y - o(j).size - 5 < o(i).y) AND (o(i).y <= o(j).y + o(j).size + 5) THEN 'is y right
  143.                                     IF o(j).exploding = 0 AND o(j).live <> 0 THEN 'ship not exploding already
  144.                                         o(j).exploding = 20
  145.                                         SOUND 800 - o(i).size * 3, .1
  146.                                         points = points + 50 - o(j).size
  147.                                         hits = hits + 1
  148.                                         o(i).live = 0: o(j).live = 0 'kill bullet and ship
  149.                                     END IF 'if not exploding already
  150.                                 END IF 'if y is right
  151.                             END IF 'if x is right
  152.                         NEXT
  153.  
  154.                         'finally bullet versus bullet!!  remember these bullets (i) are headed up
  155.                         FOR j = i + 1 TO 100 ' find only those going in different directions
  156.                             IF o(j).dy > 0 THEN 'look for bullets headed down
  157.                                 IF o(j).live THEN
  158.                                     IF o(j).x - 3 <= o(i).x AND o(i).x <= o(j).x + 3 THEN 'is x right
  159.                                         IF (o(j).y - 8 <= o(i).y) AND (o(i).y <= o(j).y + o(j).dy) THEN 'is y right  why 16 gravity accums
  160.                                             fcirc o(i).x, o(i).y, 200, &HFFFFFFFF
  161.                                             o(i).live = 0: o(j).live = 0
  162.                                             o(i).exploding = 10
  163.                                             SOUND 2800, 1
  164.                                         END IF 'if y is right
  165.                                     END IF 'if x is right
  166.                                 END IF 'both still live
  167.                             END IF 'bullets going in opposite directions
  168.                         NEXT
  169.                     END IF 'bullet hit
  170.                 END IF 'shooter
  171.             END IF 'live
  172.         NEXT
  173.         _DISPLAY
  174.         _LIMIT 60
  175.     WEND
  176.     cText xmax / 2, ymax / 2, 128, &HFFFF5500, "Game Over"
  177.     _DISPLAY: _DELAY 2.5: _KEYCLEAR ' stop hammer'n the keys!  ;-))
  178.     again$ = topTenGoAgain$(points)
  179. LOOP UNTIL LEN(again$)
  180.  
  181. SUB setUp
  182.     'obj 0 is the player's shooter
  183.     DIM i AS INTEGER
  184.     ERASE o
  185.     points = 0: bullets = 0: hits = 0
  186.     o(0).x = xmax / 2: o(0).y = ymax - 60: o(0).size = 50
  187.     o(0).live = 10
  188.     FOR i = 1 TO 3 'enemy
  189.         newEnemy i
  190.     NEXT
  191.  
  192. SUB newEnemy (i)
  193.     DIM r, g, b
  194.     IF i < 1 OR i > 3 THEN BEEP: EXIT SUB
  195.     o(i).a = RND * PT2: o(i).live = 1: o(i).v1 = rand(2, 19): o(i).v2 = rand(2, 19)
  196.     r = rand(128, 255): g = rand(0, .5 * r): b = rand(0, .5 * g)
  197.     o(i).size = rand(10, 45): o(i).c = _RGB32(r, g, b)
  198.     o(i).yc = ymax / 2 - 30: o(i).lastShot = TIMER(.003) + i
  199.     IF RND < .5 THEN
  200.         o(i).xc = 0: o(i).dx = 1
  201.     ELSE
  202.         o(i).xc = xmax: o(i).dx = -1
  203.     END IF
  204.  
  205. SUB newBullet (who, x, y)
  206.     DIM ii AS INTEGER
  207.     FOR ii = 4 TO 100 'find bullet slot
  208.         IF o(ii).live = 0 AND o(ii).exploding = 0 THEN EXIT FOR 'got slot
  209.     NEXT
  210.     IF ii >= 4 AND ii <= 100 THEN
  211.         o(ii).x = x: o(ii).y = y: o(ii).size = 2: o(ii).live = -1: o(who).lastShot = TIMER(.001)
  212.         IF shoot AND who = 0 THEN
  213.             o(ii).dy = -10: o(ii).c = &HFFFFFFFF: bullets = bullets + 1: points = points - 1
  214.             SOUND 700, .3
  215.         ELSEIF who > 0 AND who < 4 THEN
  216.             o(ii).dy = 1: o(ii).c = &HFFFFFF00
  217.             SOUND 300, 1
  218.         END IF
  219.     END IF
  220.     shoot = 0
  221.  
  222. SUB report
  223.     DIM s$
  224.     s$ = "Lives: " + TS$(o(0).live) + "           Bullets: " + TS$(bullets) + "    Hits: " + TS$(hits) + "    Eff% "
  225.     IF bullets = 0 THEN s$ = s$ + "**" ELSE s$ = s$ + TS$(100 * hits \ bullets)
  226.     s$ = s$ + "           Points: " + TS$(points)
  227.     cText xmax / 2, 30, 20, &HFF009900, s$
  228.  
  229. SUB drawRat (i)
  230.     DIM noseX, noseY, neckX, neckY, tailX, tailY, earLX, earLY, earRX, earRY, wX, wY, rh
  231.     rh = _ATAN2(o(i).y - o(i).lastY, o(i).x - o(i).lastX)
  232.     noseX = o(i).x + 2 * o(i).size * COS(rh)
  233.     noseY = o(i).y + 2 * o(i).size * SIN(rh)
  234.     neckX = o(i).x + .75 * o(i).size * COS(rh)
  235.     neckY = o(i).y + .75 * o(i).size * SIN(rh)
  236.     tailX = o(i).x + 2 * o(i).size * COS(rh + _PI)
  237.     tailY = o(i).y + 2 * o(i).size * SIN(rh + _PI)
  238.     earLX = o(i).x + o(i).size * COS(rh - _PI(1 / 12))
  239.     earLY = o(i).y + o(i).size * SIN(rh - _PI(1 / 12))
  240.     earRX = o(i).x + o(i).size * COS(rh + _PI(1 / 12))
  241.     earRY = o(i).y + o(i).size * SIN(rh + _PI(1 / 12))
  242.     fcirc o(i).x, o(i).y, .65 * o(i).size, o(i).c
  243.     fcirc neckX, neckY, o(i).size * .3, o(i).c
  244.     fTri noseX, noseY, earLX, earLY, earRX, earRY, o(i).c
  245.     fcirc earLX, earLY, o(i).size * .3, o(i).c
  246.     fcirc earRX, earRY, o(i).size * .3, o(i).c
  247.     wX = .5 * o(i).size * COS(rh - _PI(11 / 18))
  248.     wY = .5 * o(i).size * SIN(rh - _PI(11 / 18))
  249.     ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, o(i).c
  250.     wX = .5 * o(i).size * COS(rh - _PI(7 / 18))
  251.     wY = .5 * o(i).size * SIN(rh - _PI(7 / 18))
  252.     ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, o(i).c
  253.     ln o(i).x, o(i).y, tailX, tailY, o(i).c
  254.  
  255. SUB drawshooter (x) 'simple red iso triangle pointed towards radianAngle
  256.     DIM y1, y2, x1, x2
  257.     'calculate 3 points of triangle shooter
  258.     y1 = ymax - 10
  259.     y2 = ymax - 60
  260.     x1 = x - 50
  261.     x2 = x + 50
  262.     fTri x, y1, x1, ymax, x, y2, _RGB(0, 0, 200)
  263.     fTri x, y1, x2, ymax, x, y2, _RGB(0, 0, 200)
  264.     ln x, y1, x1, ymax, _RGB32(255, 255, 128)
  265.     ln x1, ymax, x, y2, _RGB32(255, 255, 128)
  266.     ln x, y1, x2, ymax, _RGB32(255, 255, 128)
  267.     ln x2, ymax, x, y2, _RGB32(255, 255, 128)
  268.     ln x, y1, x, y2, _RGB32(255, 255, 128)
  269.  
  270. ' This FUNCTION creates a file in the same folder as your .bas source or .exe
  271. 'EDIT: 2019-07-31 this function needs:
  272. ' SUB cText(x, y, pixelTextHeight, Colr)
  273. ' SUB inputBox$(prompt$, title$, maxBoxWidth)
  274. ' which needs scnState(restoreTF)
  275. FUNCTION topTenGoAgain$ (compareScore AS INTEGER)
  276.     DIM fName$, n AS INTEGER, names$(1 TO 10), scores(1 TO 10), name$, score AS INTEGER
  277.     DIM settleScore AS INTEGER, i AS INTEGER, yc, s$
  278.  
  279.     fName$ = "Top 10 Scores.txt" '<<<  since this is toolbox code change this as needed for app
  280.     CLS
  281.     cText _WIDTH / 2, _HEIGHT / 8, 20, &HFF0000FF, "Your score was:" + STR$(compareScore)
  282.     IF _FILEEXISTS(fName$) THEN
  283.         OPEN fName$ FOR INPUT AS #1
  284.         WHILE EOF(1) = 0 AND n < 10
  285.             n = n + 1
  286.             INPUT #1, name$
  287.             INPUT #1, score
  288.             IF compareScore >= score AND settleScore = 0 THEN
  289.                 names$(n) = inputBox$("Please enter your name here:", "You have made the Top Ten!", 40)
  290.                 scores(n) = compareScore
  291.                 settleScore = -1
  292.                 n = n + 1
  293.                 IF n <= 10 THEN names$(n) = name$: scores(n) = score
  294.             ELSE
  295.                 scores(n) = score: names$(n) = name$
  296.             END IF
  297.         WEND
  298.         CLOSE #1
  299.         IF n < 10 AND settleScore = 0 THEN
  300.             name$ = inputBox$("Please enter your name here:", "Top Ten has slot open for you:", 40)
  301.             IF name$ <> "" THEN n = n + 1: names$(n) = name$: scores(n) = compareScore
  302.         END IF
  303.         IF n > 10 THEN n = 10
  304.         yc = (_HEIGHT - 20 * (n + 2)) / 2
  305.         cText _WIDTH / 2, yc, 40, &HFFFFFF00, "Top Ten Scorers and Scores:"
  306.         OPEN fName$ FOR OUTPUT AS #1
  307.         FOR i = 1 TO n
  308.             PRINT #1, names$(i): PRINT #1, scores(i)
  309.             s$ = RIGHT$(" " + STR$(i), 2) + "  " + LEFT$(names$(i) + STRING$(25, "."), 20)
  310.             s$ = s$ + RIGHT$(SPACE$(10) + STR$(scores(i)), 10)
  311.             cText _WIDTH / 2, yc + 30 + i * 20, 20, &HFF00FFFF, s$
  312.         NEXT
  313.         _DISPLAY
  314.         _DELAY 3.5
  315.         CLOSE #1
  316.     ELSE
  317.         name$ = inputBox("Please enter your name here:", "You are first into Top Ten file.", 40)
  318.         OPEN fName$ FOR OUTPUT AS #1
  319.         PRINT #1, name$: PRINT #1, compareScore
  320.         CLOSE #1
  321.     END IF
  322.     topTenGoAgain$ = inputBox$("Press <Enter> to play again, enter q (or any) to quit... ", "Play Again?", 66)
  323.  
  324. 'center the text around (x, y) point, needs a graphics screen!
  325. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  326.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  327.     fg = _DEFAULTCOLOR
  328.     'screen snapshot
  329.     cur& = _DEST
  330.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  331.     _DEST I&
  332.     COLOR K, _RGBA32(0, 0, 0, 0)
  333.     _PRINTSTRING (0, 0), txt$
  334.     mult = textHeight / 16
  335.     xlen = LEN(txt$) * 8 * mult
  336.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  337.     COLOR fg
  338.     _FREEIMAGE I&
  339.  
  340. ' You can grab this box by title and drag it around screen for full viewing while answering prompt.
  341. ' Only one line allowed for prompt$
  342. ' boxWidth is 4 more than the allowed length of input, it needs to be longer than title$ and prompt$ also
  343. ' Utilities > Input Box > Input Box 1 tester v 2019-07-31
  344. ' This FUNCTION needs scnState(restroreTF)
  345. FUNCTION inputBox$ (prompt$, title$, boxWidth AS _BYTE)
  346.     DIM ForeColor AS _UNSIGNED LONG, BackColor AS _UNSIGNED LONG, White AS _UNSIGNED LONG
  347.     DIM sw AS INTEGER, sh AS INTEGER, curScrn AS LONG, backScrn AS LONG, ibx AS LONG 'some handles
  348.  
  349.     'colors
  350.     ForeColor = &HFF000055 '<  change as desired  prompt text color, back color or type in area
  351.     BackColor = &HFF6080CC '<  change as desired  used fore color in type in area
  352.     White = &HFFFFFFFF
  353.  
  354.     'items to restore at exit
  355.     scnState 0
  356.  
  357.     'screen snapshot
  358.     sw = _WIDTH: sh = _HEIGHT: curScrn = _DEST
  359.     backScrn = _NEWIMAGE(sw, sh, 32)
  360.     _PUTIMAGE , curScrn, backScrn
  361.  
  362.     'moving box around on screen
  363.     DIM bxW AS INTEGER, bxH AS INTEGER
  364.     DIM mb AS INTEGER, mx AS INTEGER, my AS INTEGER, mi AS INTEGER, grabx AS INTEGER, graby AS INTEGER
  365.     DIM tlx AS INTEGER, tly AS INTEGER 'top left corner of message box
  366.     DIM lastx AS INTEGER, lasty AS INTEGER
  367.     DIM inp$, kh&
  368.  
  369.     'draw message box
  370.     bxW = boxWidth * 8: bxH = 7 * 16
  371.     ibx = _NEWIMAGE(bxW, bxH, 32)
  372.     _DEST ibx
  373.     COLOR &HFF880000, White
  374.     LOCATE 1, 1: PRINT LEFT$(SPACE$(INT((boxWidth - LEN(title$) - 3)) / 2) + title$ + SPACE$(boxWidth), boxWidth)
  375.     COLOR White, &HFFBB0000
  376.     LOCATE 1, boxWidth - 2: PRINT " X "
  377.     COLOR ForeColor, BackColor
  378.     LOCATE 2, 1: PRINT SPACE$(boxWidth);
  379.     LOCATE 3, 1: PRINT LEFT$(SPACE$((boxWidth - LEN(prompt$)) / 2) + prompt$ + SPACE$(boxWidth), boxWidth);
  380.     LOCATE 4, 1: PRINT SPACE$(boxWidth);
  381.     LOCATE 5, 1: PRINT SPACE$(boxWidth);
  382.     LOCATE 6, 1: PRINT SPACE$(boxWidth);
  383.     inp$ = ""
  384.     GOSUB finishBox
  385.  
  386.     'convert to pixels the top left corner of box at moment
  387.     bxW = boxWidth * 8: bxH = 5 * 16
  388.     tlx = (sw - bxW) / 2: tly = (sh - bxH) / 2
  389.     lastx = tlx: lasty = tly
  390.     _KEYCLEAR
  391.     'now allow user to move it around or just read it
  392.     WHILE 1
  393.         CLS
  394.         _PUTIMAGE , backScrn
  395.         _PUTIMAGE (tlx, tly), ibx, curScrn
  396.         _DISPLAY
  397.         WHILE _MOUSEINPUT: WEND
  398.         mx = _MOUSEX: my = _MOUSEY: mb = _MOUSEBUTTON(1)
  399.         IF mb THEN
  400.             IF mx >= tlx AND mx <= tlx + bxW AND my >= tly AND my <= tly + 16 THEN 'mouse down on title bar
  401.                 IF mx >= tlx + bxW - 24 THEN EXIT WHILE
  402.                 grabx = mx - tlx: graby = my - tly
  403.                 DO WHILE mb 'wait for release
  404.                     mi = _MOUSEINPUT: mb = _MOUSEBUTTON(1)
  405.                     mx = _MOUSEX: my = _MOUSEY
  406.                     IF mx - grabx >= 0 AND mx - grabx <= sw - bxW AND my - graby >= 0 AND my - graby <= sh - bxH THEN
  407.                         'attempt to speed up with less updates
  408.                         IF ((lastx - (mx - grabx)) ^ 2 + (lasty - (my - graby)) ^ 2) ^ .5 > 10 THEN
  409.                             tlx = mx - grabx: tly = my - graby
  410.                             CLS
  411.                             _PUTIMAGE , backScrn
  412.                             _PUTIMAGE (tlx, tly), ibx, curScrn
  413.                             lastx = tlx: lasty = tly
  414.                             _DISPLAY
  415.                         END IF
  416.                     END IF
  417.                     _LIMIT 400
  418.                 LOOP
  419.             END IF
  420.         END IF
  421.         kh& = _KEYHIT
  422.         SELECT CASE kh& 'whew not much for the main event!
  423.             CASE 13: EXIT WHILE
  424.             CASE 27: inp$ = "": EXIT WHILE
  425.             CASE 32 TO 128: IF LEN(inp$) < boxWidth - 4 THEN inp$ = inp$ + CHR$(kh&): GOSUB finishBox ELSE BEEP
  426.             CASE 8: IF LEN(inp$) THEN inp$ = LEFT$(inp$, LEN(inp$) - 1): GOSUB finishBox ELSE BEEP
  427.         END SELECT
  428.  
  429.         _LIMIT 60
  430.     WEND
  431.  
  432.     'put things back
  433.     scnState 1 'need fg and bg colors set to cls
  434.     CLS '? is this needed YES!!
  435.     _PUTIMAGE , backScrn
  436.     _DISPLAY
  437.     _FREEIMAGE backScrn
  438.     _FREEIMAGE ibx
  439.     scnState 1 'because we have to call _display, we have to call this again
  440.     inputBox$ = inp$
  441.  
  442.     finishBox:
  443.     _DEST ibx
  444.     COLOR BackColor, ForeColor
  445.     LOCATE 5, 2: PRINT LEFT$(" " + inp$ + SPACE$(boxWidth - 2), boxWidth - 2)
  446.     _DEST curScrn
  447.     RETURN
  448.  
  449. 'from mBox v 2019-07-31 update
  450. ' for saving and restoring screen settins
  451. SUB scnState (restoreTF AS INTEGER) 'Thanks Steve McNeill
  452.     STATIC Font AS LONG, DefaultColor AS _UNSIGNED LONG, BackGroundColor AS _UNSIGNED LONG, Dest AS LONG, Source AS LONG
  453.     STATIC row AS INTEGER, col AS INTEGER, autodisplay AS INTEGER, mb AS INTEGER
  454.     IF restoreTF THEN
  455.         _FONT Font
  456.         COLOR DefaultColor, BackGroundColor
  457.         _DEST Dest
  458.         _SOURCE Source
  459.         LOCATE row, col
  460.         IF autodisplay THEN _AUTODISPLAY ELSE _DISPLAY
  461.         _KEYCLEAR
  462.         WHILE _MOUSEINPUT: WEND 'clear mouse clicks
  463.         mb = _MOUSEBUTTON(1)
  464.         IF mb THEN
  465.             DO
  466.                 WHILE _MOUSEINPUT: WEND
  467.                 mb = _MOUSEBUTTON(1)
  468.                 _LIMIT 100
  469.             LOOP UNTIL mb = 0
  470.         END IF
  471.     ELSE
  472.         Font = _FONT: DefaultColor = _DEFAULTCOLOR: BackGroundColor = _BACKGROUNDCOLOR
  473.         Dest = _DEST: Source = _SOURCE
  474.         row = CSRLIN: col = POS(0): autodisplay = _AUTODISPLAY
  475.     END IF
  476.  
  477.     TS$ = _TRIM$(STR$(n))
  478.  
  479. FUNCTION rand% (lo%, hi%)
  480.     rand% = INT(RND * (hi% - lo% + 1)) + lo%
  481.  
  482. ' found at [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]:    http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
  483. SUB fTri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  484.     DIM a&
  485.     a& = _NEWIMAGE(1, 1, 32)
  486.     _DEST a&
  487.     PSET (0, 0), K
  488.     _DEST 0
  489.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  490.     _FREEIMAGE a& '<<< this is important!
  491.  
  492. SUB ln (x1, y1, x2, y2, K AS _UNSIGNED LONG) 'box frame
  493.     LINE (x1, y1)-(x2, y2), K
  494.  
  495. 'from Steve Gold standard
  496. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  497.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  498.     DIM X AS INTEGER, Y AS INTEGER
  499.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  500.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  501.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  502.     WHILE X > Y
  503.         RadiusError = RadiusError + Y * 2 + 1
  504.         IF RadiusError >= 0 THEN
  505.             IF X <> Y + 1 THEN
  506.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  507.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  508.             END IF
  509.             X = X - 1
  510.             RadiusError = RadiusError - X * 2
  511.         END IF
  512.         Y = Y + 1
  513.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  514.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  515.     WEND
  516.  

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Invaders bplus style
« Reply #24 on: August 01, 2019, 07:44:50 am »
Cool Bplus
I have discovered up key that stops shooter and I have experimented  collision bullet to bullet, moreover we can spam bullets shooting aliens.
Great top ten!
« Last Edit: August 01, 2019, 08:04:50 am by TempodiBasic »
Programming isn't difficult, only it's  consuming time and coffee

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Invaders bplus style
« Reply #25 on: August 01, 2019, 08:07:21 am »
Sorry Bplus
You have given me a tentation so I have put a little MOD in your cool game.

Code: QB64: [Select]
  1. _TITLE "Invaders b0_4" 'Bplus started 2019-07-27 inspired by Ken's fun program series
  2.  
  3. ' 2019-07-29 b0_3 from feed back fix game ending with big "Game Over" sign and delay before Top Ten.
  4. ' Show score to compare with Top Ten Numbers.
  5. ' Change the way hits are calculated, use method that avoids distance function or ABS.
  6. ' Change TopTen sub to TopTenGoAgain$ function to also get Play Again reply.
  7. ' OK let's start charging for bullets! 1 point per... and do a hit % to reward skillful shooting
  8. ' change BEEPs to SOUNDS, add more to report, Game Over signals end of game, TopTen does go again also.
  9.  
  10. ' 2019-07-31 Rework the Top Ten screen using Text sub routine that I want to demo in "another one for the Toolbox."
  11. ' This new TopTen function now uses inputBox$ which added a ton of lines to the program!
  12.  
  13.  
  14. CONST xmax = 1200, ymax = 720, PI = 3.141592653589793, PD2 = 1.570796326794897, PT2 = 6.283185307
  15. SCREEN _NEWIMAGE(xmax, ymax, 32)
  16. _SCREENMOVE 100, 20
  17.  
  18. TYPE typeO
  19.     x AS SINGLE
  20.     y AS SINGLE
  21.     xc AS SINGLE
  22.     yc AS SINGLE
  23.     dx AS SINGLE
  24.     dy AS SINGLE
  25.     dv AS SINGLE
  26.     a AS SINGLE
  27.     lastX AS SINGLE
  28.     lastY AS SINGLE
  29.     v1 AS SINGLE
  30.     v2 AS SINGLE
  31.     size AS SINGLE
  32.     live AS INTEGER
  33.     exploding AS INTEGER
  34.     lastShot AS SINGLE
  35.     c AS _UNSIGNED LONG
  36.  
  37. DIM SHARED o(100) AS typeO, shoot AS INTEGER, points AS INTEGER, bullets AS INTEGER, hits AS INTEGER
  38. DIM i AS INTEGER, j AS INTEGER, kh AS LONG, red AS INTEGER, again$
  39.     setUp
  40.     WHILE o(0).live
  41.         LINE (0, 0)-(xmax, ymax), _RGBA(0, 0, 0, 255), BF
  42.         kh = _KEYHIT
  43.         IF kh = 32 THEN shoot = -1
  44.         IF kh = 18432 THEN
  45.             o(0).dx = 0: o(0).dv = 0
  46.         END IF
  47.         IF kh = 19200 THEN
  48.             IF o(0).dx <= -3 AND o(0).dx > -7 THEN
  49.                 o(0).dv = o(0).dv - 1
  50.             ELSE
  51.                 o(0).dx = -3
  52.                 o(0).dv = 0
  53.             END IF
  54.         END IF
  55.         IF kh = 19712 THEN
  56.             IF o(0).dx >= 3 AND o(0).dx < 7 THEN
  57.                 o(0).dv = o(0).dv + 1
  58.             ELSE
  59.                 o(0).dx = 3
  60.                 o(0).dv = 0
  61.             END IF
  62.         END IF
  63.  
  64.  
  65.         report
  66.  
  67.         'dead ships and bullets? but still exploding  this separated out because ships are getting hit more than once while exploding
  68.         FOR i = 1 TO 3
  69.             IF o(i).exploding THEN
  70.                 o(i).exploding = o(i).exploding - 1
  71.                 IF o(i).exploding = 0 THEN
  72.                     newEnemy i
  73.                 ELSE 'draw explosion
  74.                     SOUND 1000 - o(i).size * 3 + (21 - o(i).exploding) * 10, .1
  75.                     red = rand(60, 255)
  76.                     fcirc o(i).x, o(i).y, o(i).exploding * 3, _RGB32(red, rand(0, red), 0)
  77.                 END IF
  78.             END IF 'i = x
  79.         NEXT
  80.         'bullets
  81.         FOR i = 4 TO 100
  82.             IF o(i).exploding THEN
  83.                 o(i).exploding = o(i).exploding - 1
  84.                 SOUND 1600, .05
  85.                 red = rand(60, 255)
  86.                 fcirc o(i).x, o(i).y, o(i).exploding, _RGB32(red, rand(0, red), 0)
  87.             END IF
  88.         NEXT
  89.  
  90.         FOR i = 0 TO 100
  91.             IF o(i).live <> 0 THEN 'draw everything, update positions, check updated position
  92.                 IF i = 0 THEN 'shooter
  93.                     IF o(0).exploding = 0 THEN
  94.                         drawshooter o(i).x
  95.                         IF shoot AND (TIMER(.001) - o(0).lastShot) > .1 THEN '.2 is this the cause of hitting a ship twice?
  96.                             newBullet 0, o(0).x, ymax - 60
  97.                         END IF
  98.                         IF o(i).x + o(i).dx + o(i).dv > 0 AND o(i).x + o(i).dx + o(i).dv < xmax THEN
  99.                             o(i).x = o(i).x + o(i).dx + o(i).dv
  100.                         ELSE
  101.                             o(i).dx = -o(i).dx
  102.                             o(i).dv = 0
  103.                         END IF
  104.                     ELSEIF o(0).exploding THEN 'exploded enough
  105.                         o(i).exploding = o(i).exploding - 1
  106.                         IF o(i).exploding = 0 THEN 'no longer exploding
  107.                             o(0).live = o(0).live - 1
  108.                             IF o(0).live = 0 THEN
  109.                                 fcirc o(0).x, ymax - 75, 50, &HFF770000
  110.                                 report
  111.                                 EXIT FOR
  112.                             ELSE
  113.                                 drawshooter o(i).x
  114.                             END IF
  115.                         ELSE 'exploding
  116.                             SOUND 400 + o(0).exploding * 7, .3
  117.                             red = rand(60, 255)
  118.                             fcirc o(0).x, ymax - 75, o(0).exploding * 6, _RGB32(red, rand(0, red), 0)
  119.                         END IF
  120.                     END IF
  121.  
  122.                 ELSEIF i > 0 AND i < 4 THEN 'enemy ships
  123.                     'update coodinates
  124.                     o(i).lastX = o(i).x: o(i).lastY = o(i).y
  125.                     o(i).x = o(i).xc + 150 * (COS(o(i).a) + COS(o(i).v1 * o(i).a) / 2 + SIN(o(i).v2 * o(i).a) / 3)
  126.                     o(i).y = o(i).yc + 150 * (SIN(o(i).a) + SIN(o(i).v1 * o(i).a) / 2 + COS(o(i).v2 * o(i).a) / 3)
  127.                     drawRat i
  128.                     o(i).a = o(i).a + PI / 1440
  129.                     IF o(i).xc + o(i).dx > 0 AND o(i).xc + o(i).dx < xmax THEN
  130.                         o(i).xc = o(i).xc + o(i).dx
  131.                     ELSE
  132.                         o(i).dx = -o(i).dx
  133.                     END IF
  134.                     'drop bombs
  135.                     IF TIMER(.001) - o(i).lastShot > 3 THEN
  136.                         newBullet i, o(i).x, o(i).y + o(i).size
  137.                     END IF
  138.  
  139.                 ELSEIF i > 3 AND i < 101 THEN 'bullets
  140.                     fcirc o(i).x, o(i).y, o(i).size, o(i).c
  141.                     IF o(i).y + o(i).dy > 0 AND o(i).y + o(i).dy < ymax THEN
  142.                         IF o(i).dy > 0 THEN o(i).dy = o(i).dy + .1 'gravity
  143.                         o(i).y = o(i).y + o(i).dy
  144.                     ELSE
  145.                         o(i).live = 0
  146.                     END IF
  147.  
  148.                     'did this bullet hit anything
  149.                     IF o(i).dy > 0 THEN 'did it hit the shooter
  150.                         IF (o(0).x - o(0).size <= o(i).x) AND (o(i).x <= o(0).x + o(0).size) THEN
  151.                             IF (o(0).y - o(0).size <= o(i).y) AND (o(i).y <= o(0).y + o(0).size + 20) THEN
  152.                                 IF o(0).exploding = 0 AND o(0).live THEN
  153.                                     SOUND 400 + 5 * 20, .1
  154.                                     o(0).exploding = 20 'signal exploding
  155.                                     o(i).live = 0 'kill bullet
  156.                                 END IF
  157.                             END IF
  158.                         END IF
  159.                     ELSEIF o(i).dy < 0 THEN 'did it hit the enemy?
  160.                         FOR j = 1 TO 3
  161.                             IF (o(j).x - o(j).size <= o(i).x) AND (o(i).x <= o(j).x + o(j).size) THEN 'is x right
  162.                                 IF (o(j).y - o(j).size - 5 < o(i).y) AND (o(i).y <= o(j).y + o(j).size + 5) THEN 'is y right
  163.                                     IF o(j).exploding = 0 AND o(j).live <> 0 THEN 'ship not exploding already
  164.                                         o(j).exploding = 20
  165.                                         SOUND 800 - o(i).size * 3, .1
  166.                                         points = points + 50 - o(j).size
  167.                                         hits = hits + 1
  168.                                         o(i).live = 0: o(j).live = 0 'kill bullet and ship
  169.                                     END IF 'if not exploding already
  170.                                 END IF 'if y is right
  171.                             END IF 'if x is right
  172.                         NEXT
  173.  
  174.                         'finally bullet versus bullet!!  remember these bullets (i) are headed up
  175.                         FOR j = i + 1 TO 100 ' find only those going in different directions
  176.                             IF o(j).dy > 0 THEN 'look for bullets headed down
  177.                                 IF o(j).live THEN
  178.                                     IF o(j).x - 3 <= o(i).x AND o(i).x <= o(j).x + 3 THEN 'is x right
  179.                                         IF (o(j).y - 8 <= o(i).y) AND (o(i).y <= o(j).y + o(j).dy) THEN 'is y right  why 16 gravity accums
  180.                                             fcirc o(i).x, o(i).y, 200, &HFFFFFFFF
  181.                                             o(i).live = 0: o(j).live = 0
  182.                                             o(i).exploding = 10
  183.                                             SOUND 2800, 1
  184.                                         END IF 'if y is right
  185.                                     END IF 'if x is right
  186.                                 END IF 'both still live
  187.                             END IF 'bullets going in opposite directions
  188.                         NEXT
  189.                     END IF 'bullet hit
  190.                 END IF 'shooter
  191.             END IF 'live
  192.         NEXT
  193.         _DISPLAY
  194.         _LIMIT 60
  195.     WEND
  196.     cText xmax / 2, ymax / 2, 128, &HFFFF5500, "Game Over"
  197.     _DISPLAY: _DELAY 2.5: _KEYCLEAR ' stop hammer'n the keys!  ;-))
  198.     again$ = topTenGoAgain$(points)
  199. LOOP UNTIL LEN(again$)
  200.  
  201. SUB setUp
  202.     'obj 0 is the player's shooter
  203.     DIM i AS INTEGER
  204.     ERASE o
  205.     points = 0: bullets = 0: hits = 0
  206.     o(0).x = xmax / 2: o(0).y = ymax - 60: o(0).size = 50
  207.     o(0).live = 10
  208.     FOR i = 1 TO 3 'enemy
  209.         newEnemy i
  210.     NEXT
  211.  
  212. SUB newEnemy (i)
  213.     DIM r, g, b
  214.     IF i < 1 OR i > 3 THEN BEEP: EXIT SUB
  215.     o(i).a = RND * PT2: o(i).live = 1: o(i).v1 = rand(2, 19): o(i).v2 = rand(2, 19)
  216.     r = rand(128, 255): g = rand(0, .5 * r): b = rand(0, .5 * g)
  217.     o(i).size = rand(10, 45): o(i).c = _RGB32(r, g, b)
  218.     o(i).yc = ymax / 2 - 30: o(i).lastShot = TIMER(.003) + i
  219.     IF RND < .5 THEN
  220.         o(i).xc = 0: o(i).dx = 1
  221.     ELSE
  222.         o(i).xc = xmax: o(i).dx = -1
  223.     END IF
  224.  
  225. SUB newBullet (who, x, y)
  226.     DIM ii AS INTEGER
  227.     FOR ii = 4 TO 100 'find bullet slot
  228.         IF o(ii).live = 0 AND o(ii).exploding = 0 THEN EXIT FOR 'got slot
  229.     NEXT
  230.     IF ii >= 4 AND ii <= 100 THEN
  231.         o(ii).x = x: o(ii).y = y: o(ii).size = 2: o(ii).live = -1: o(who).lastShot = TIMER(.001)
  232.         IF shoot AND who = 0 THEN
  233.             o(ii).dy = -10: o(ii).c = &HFFFFFFFF: bullets = bullets + 1: points = points - 1
  234.             SOUND 700, .3
  235.         ELSEIF who > 0 AND who < 4 THEN
  236.             o(ii).dy = 1: o(ii).c = &HFFFFFF00
  237.             SOUND 300, 1
  238.         END IF
  239.     END IF
  240.     shoot = 0
  241.  
  242. SUB report
  243.     DIM s$
  244.     s$ = "Lives: " + TS$(o(0).live) + "           Bullets: " + TS$(bullets) + "    Hits: " + TS$(hits) + "    Eff% "
  245.     IF bullets = 0 THEN s$ = s$ + "**" ELSE s$ = s$ + TS$(100 * hits \ bullets)
  246.     s$ = s$ + "           Points: " + TS$(points)
  247.     cText xmax / 2, 30, 20, &HFF009900, s$
  248.  
  249. SUB drawRat (i)
  250.     DIM noseX, noseY, neckX, neckY, tailX, tailY, earLX, earLY, earRX, earRY, wX, wY, rh
  251.     rh = _ATAN2(o(i).y - o(i).lastY, o(i).x - o(i).lastX)
  252.     noseX = o(i).x + 2 * o(i).size * COS(rh)
  253.     noseY = o(i).y + 2 * o(i).size * SIN(rh)
  254.     neckX = o(i).x + .75 * o(i).size * COS(rh)
  255.     neckY = o(i).y + .75 * o(i).size * SIN(rh)
  256.     tailX = o(i).x + 2 * o(i).size * COS(rh + _PI)
  257.     tailY = o(i).y + 2 * o(i).size * SIN(rh + _PI)
  258.     earLX = o(i).x + o(i).size * COS(rh - _PI(1 / 12))
  259.     earLY = o(i).y + o(i).size * SIN(rh - _PI(1 / 12))
  260.     earRX = o(i).x + o(i).size * COS(rh + _PI(1 / 12))
  261.     earRY = o(i).y + o(i).size * SIN(rh + _PI(1 / 12))
  262.     fcirc o(i).x, o(i).y, .65 * o(i).size, o(i).c
  263.     fcirc neckX, neckY, o(i).size * .3, o(i).c
  264.     fTri noseX, noseY, earLX, earLY, earRX, earRY, o(i).c
  265.     fcirc earLX, earLY, o(i).size * .3, o(i).c
  266.     fcirc earRX, earRY, o(i).size * .3, o(i).c
  267.     wX = .5 * o(i).size * COS(rh - _PI(11 / 18))
  268.     wY = .5 * o(i).size * SIN(rh - _PI(11 / 18))
  269.     ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, o(i).c
  270.     wX = .5 * o(i).size * COS(rh - _PI(7 / 18))
  271.     wY = .5 * o(i).size * SIN(rh - _PI(7 / 18))
  272.     ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, o(i).c
  273.     ln o(i).x, o(i).y, tailX, tailY, o(i).c
  274.  
  275. SUB drawshooter (x) 'simple red iso triangle pointed towards radianAngle
  276.     DIM y1, y2, x1, x2
  277.     'calculate 3 points of triangle shooter
  278.     y1 = ymax - 10
  279.     y2 = ymax - 60
  280.     x1 = x - 50
  281.     x2 = x + 50
  282.     fTri x, y1, x1, ymax, x, y2, _RGB(0, 0, 200)
  283.     fTri x, y1, x2, ymax, x, y2, _RGB(0, 0, 200)
  284.     ln x, y1, x1, ymax, _RGB32(255, 255, 128)
  285.     ln x1, ymax, x, y2, _RGB32(255, 255, 128)
  286.     ln x, y1, x2, ymax, _RGB32(255, 255, 128)
  287.     ln x2, ymax, x, y2, _RGB32(255, 255, 128)
  288.     ln x, y1, x, y2, _RGB32(255, 255, 128)
  289.  
  290. ' This FUNCTION creates a file in the same folder as your .bas source or .exe
  291. 'EDIT: 2019-07-31 this function needs:
  292. ' SUB cText(x, y, pixelTextHeight, Colr)
  293. ' SUB inputBox$(prompt$, title$, maxBoxWidth)
  294. ' which needs scnState(restoreTF)
  295. FUNCTION topTenGoAgain$ (compareScore AS INTEGER)
  296.     DIM fName$, n AS INTEGER, names$(1 TO 10), scores(1 TO 10), NAME$, score AS INTEGER
  297.     DIM settleScore AS INTEGER, i AS INTEGER, yc, s$
  298.  
  299.     fName$ = "Top 10 Scores.txt" '<<<  since this is toolbox code change this as needed for app
  300.     CLS
  301.     cText _WIDTH / 2, _HEIGHT / 8, 20, &HFF0000FF, "Your score was:" + STR$(compareScore)
  302.     IF _FILEEXISTS(fName$) THEN
  303.         OPEN fName$ FOR INPUT AS #1
  304.         WHILE EOF(1) = 0 AND n < 10
  305.             n = n + 1
  306.             INPUT #1, NAME$
  307.             INPUT #1, score
  308.             IF compareScore >= score AND settleScore = 0 THEN
  309.                 names$(n) = inputBox$("Please enter your name here:", "You have made the Top Ten!", 40)
  310.                 scores(n) = compareScore
  311.                 settleScore = -1
  312.                 n = n + 1
  313.                 IF n <= 10 THEN names$(n) = NAME$: scores(n) = score
  314.             ELSE
  315.                 scores(n) = score: names$(n) = NAME$
  316.             END IF
  317.         WEND
  318.         CLOSE #1
  319.         IF n < 10 AND settleScore = 0 THEN
  320.             NAME$ = inputBox$("Please enter your name here:", "Top Ten has slot open for you:", 40)
  321.             IF NAME$ <> "" THEN n = n + 1: names$(n) = NAME$: scores(n) = compareScore
  322.         END IF
  323.         IF n > 10 THEN n = 10
  324.         yc = (_HEIGHT - 20 * (n + 2)) / 2
  325.         cText _WIDTH / 2, yc, 40, &HFFFFFF00, "Top Ten Scorers and Scores:"
  326.         OPEN fName$ FOR OUTPUT AS #1
  327.         FOR i = 1 TO n
  328.             PRINT #1, names$(i): PRINT #1, scores(i)
  329.             s$ = RIGHT$(" " + STR$(i), 2) + "  " + LEFT$(names$(i) + STRING$(25, "."), 20)
  330.             s$ = s$ + RIGHT$(SPACE$(10) + STR$(scores(i)), 10)
  331.             cText _WIDTH / 2, yc + 30 + i * 20, 20, &HFF00FFFF, s$
  332.         NEXT
  333.         _DISPLAY
  334.         _DELAY 3.5
  335.         CLOSE #1
  336.     ELSE
  337.         NAME$ = inputBox("Please enter your name here:", "You are first into Top Ten file.", 40)
  338.         OPEN fName$ FOR OUTPUT AS #1
  339.         PRINT #1, NAME$: PRINT #1, compareScore
  340.         CLOSE #1
  341.     END IF
  342.     topTenGoAgain$ = inputBox$("Press <Enter> to play again, enter q (or any) to quit... ", "Play Again?", 66)
  343.  
  344. 'center the text around (x, y) point, needs a graphics screen!
  345. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  346.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  347.     fg = _DEFAULTCOLOR
  348.     'screen snapshot
  349.     cur& = _DEST
  350.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  351.     _DEST I&
  352.     COLOR K, _RGBA32(0, 0, 0, 0)
  353.     _PRINTSTRING (0, 0), txt$
  354.     mult = textHeight / 16
  355.     xlen = LEN(txt$) * 8 * mult
  356.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  357.     COLOR fg
  358.     _FREEIMAGE I&
  359.  
  360. ' You can grab this box by title and drag it around screen for full viewing while answering prompt.
  361. ' Only one line allowed for prompt$
  362. ' boxWidth is 4 more than the allowed length of input, it needs to be longer than title$ and prompt$ also
  363. ' Utilities > Input Box > Input Box 1 tester v 2019-07-31
  364. ' This FUNCTION needs scnState(restroreTF)
  365. FUNCTION inputBox$ (prompt$, title$, boxWidth AS _BYTE)
  366.     DIM ForeColor AS _UNSIGNED LONG, BackColor AS _UNSIGNED LONG, White AS _UNSIGNED LONG
  367.     DIM sw AS INTEGER, sh AS INTEGER, curScrn AS LONG, backScrn AS LONG, ibx AS LONG 'some handles
  368.  
  369.     'colors
  370.     ForeColor = &HFF000055 '<  change as desired  prompt text color, back color or type in area
  371.     BackColor = &HFF6080CC '<  change as desired  used fore color in type in area
  372.     White = &HFFFFFFFF
  373.  
  374.     'items to restore at exit
  375.     scnState 0
  376.  
  377.     'screen snapshot
  378.     sw = _WIDTH: sh = _HEIGHT: curScrn = _DEST
  379.     backScrn = _NEWIMAGE(sw, sh, 32)
  380.     _PUTIMAGE , curScrn, backScrn
  381.  
  382.     'moving box around on screen
  383.     DIM bxW AS INTEGER, bxH AS INTEGER
  384.     DIM mb AS INTEGER, mx AS INTEGER, my AS INTEGER, mi AS INTEGER, grabx AS INTEGER, graby AS INTEGER
  385.     DIM tlx AS INTEGER, tly AS INTEGER 'top left corner of message box
  386.     DIM lastx AS INTEGER, lasty AS INTEGER
  387.     DIM INP$, kh&
  388.  
  389.     'draw message box
  390.     bxW = boxWidth * 8: bxH = 7 * 16
  391.     ibx = _NEWIMAGE(bxW, bxH, 32)
  392.     _DEST ibx
  393.     COLOR &HFF880000, White
  394.     LOCATE 1, 1: PRINT LEFT$(SPACE$(INT((boxWidth - LEN(title$) - 3)) / 2) + title$ + SPACE$(boxWidth), boxWidth)
  395.     COLOR White, &HFFBB0000
  396.     LOCATE 1, boxWidth - 2: PRINT " X "
  397.     COLOR ForeColor, BackColor
  398.     LOCATE 2, 1: PRINT SPACE$(boxWidth);
  399.     LOCATE 3, 1: PRINT LEFT$(SPACE$((boxWidth - LEN(prompt$)) / 2) + prompt$ + SPACE$(boxWidth), boxWidth);
  400.     LOCATE 4, 1: PRINT SPACE$(boxWidth);
  401.     LOCATE 5, 1: PRINT SPACE$(boxWidth);
  402.     LOCATE 6, 1: PRINT SPACE$(boxWidth);
  403.     INP$ = ""
  404.     GOSUB finishBox
  405.  
  406.     'convert to pixels the top left corner of box at moment
  407.     bxW = boxWidth * 8: bxH = 5 * 16
  408.     tlx = (sw - bxW) / 2: tly = (sh - bxH) / 2
  409.     lastx = tlx: lasty = tly
  410.     _KEYCLEAR
  411.     'now allow user to move it around or just read it
  412.     WHILE 1
  413.         CLS
  414.         _PUTIMAGE , backScrn
  415.         _PUTIMAGE (tlx, tly), ibx, curScrn
  416.         _DISPLAY
  417.         WHILE _MOUSEINPUT: WEND
  418.         mx = _MOUSEX: my = _MOUSEY: mb = _MOUSEBUTTON(1)
  419.         IF mb THEN
  420.             IF mx >= tlx AND mx <= tlx + bxW AND my >= tly AND my <= tly + 16 THEN 'mouse down on title bar
  421.                 IF mx >= tlx + bxW - 24 THEN EXIT WHILE
  422.                 grabx = mx - tlx: graby = my - tly
  423.                 DO WHILE mb 'wait for release
  424.                     mi = _MOUSEINPUT: mb = _MOUSEBUTTON(1)
  425.                     mx = _MOUSEX: my = _MOUSEY
  426.                     IF mx - grabx >= 0 AND mx - grabx <= sw - bxW AND my - graby >= 0 AND my - graby <= sh - bxH THEN
  427.                         'attempt to speed up with less updates
  428.                         IF ((lastx - (mx - grabx)) ^ 2 + (lasty - (my - graby)) ^ 2) ^ .5 > 10 THEN
  429.                             tlx = mx - grabx: tly = my - graby
  430.                             CLS
  431.                             _PUTIMAGE , backScrn
  432.                             _PUTIMAGE (tlx, tly), ibx, curScrn
  433.                             lastx = tlx: lasty = tly
  434.                             _DISPLAY
  435.                         END IF
  436.                     END IF
  437.                     _LIMIT 400
  438.                 LOOP
  439.             END IF
  440.         END IF
  441.         kh& = _KEYHIT
  442.         SELECT CASE kh& 'whew not much for the main event!
  443.             CASE 13: EXIT WHILE
  444.             CASE 27: INP$ = "": EXIT WHILE
  445.             CASE 32 TO 128: IF LEN(INP$) < boxWidth - 4 THEN INP$ = INP$ + CHR$(kh&): GOSUB finishBox ELSE BEEP
  446.             CASE 8: IF LEN(INP$) THEN INP$ = LEFT$(INP$, LEN(INP$) - 1): GOSUB finishBox ELSE BEEP
  447.         END SELECT
  448.  
  449.         _LIMIT 60
  450.     WEND
  451.  
  452.     'put things back
  453.     scnState 1 'need fg and bg colors set to cls
  454.     CLS '? is this needed YES!!
  455.     _PUTIMAGE , backScrn
  456.     _DISPLAY
  457.     _FREEIMAGE backScrn
  458.     _FREEIMAGE ibx
  459.     scnState 1 'because we have to call _display, we have to call this again
  460.     inputBox$ = INP$
  461.  
  462.     finishBox:
  463.     _DEST ibx
  464.     COLOR BackColor, ForeColor
  465.     LOCATE 5, 2: PRINT LEFT$(" " + INP$ + SPACE$(boxWidth - 2), boxWidth - 2)
  466.     _DEST curScrn
  467.     RETURN
  468.  
  469. 'from mBox v 2019-07-31 update
  470. ' for saving and restoring screen settins
  471. SUB scnState (restoreTF AS INTEGER) 'Thanks Steve McNeill
  472.     STATIC Font AS LONG, DefaultColor AS _UNSIGNED LONG, BackGroundColor AS _UNSIGNED LONG, Dest AS LONG, Source AS LONG
  473.     STATIC row AS INTEGER, col AS INTEGER, autodisplay AS INTEGER, mb AS INTEGER
  474.     IF restoreTF THEN
  475.         _FONT Font
  476.         COLOR DefaultColor, BackGroundColor
  477.         _DEST Dest
  478.         _SOURCE Source
  479.         LOCATE row, col
  480.         IF autodisplay THEN _AUTODISPLAY ELSE _DISPLAY
  481.         _KEYCLEAR
  482.         WHILE _MOUSEINPUT: WEND 'clear mouse clicks
  483.         mb = _MOUSEBUTTON(1)
  484.         IF mb THEN
  485.             DO
  486.                 WHILE _MOUSEINPUT: WEND
  487.                 mb = _MOUSEBUTTON(1)
  488.                 _LIMIT 100
  489.             LOOP UNTIL mb = 0
  490.         END IF
  491.     ELSE
  492.         Font = _FONT: DefaultColor = _DEFAULTCOLOR: BackGroundColor = _BACKGROUNDCOLOR
  493.         Dest = _DEST: Source = _SOURCE
  494.         row = CSRLIN: col = POS(0): autodisplay = _AUTODISPLAY
  495.     END IF
  496.  
  497.     TS$ = _TRIM$(STR$(n))
  498.  
  499. FUNCTION rand% (lo%, hi%)
  500.     rand% = INT(RND * (hi% - lo% + 1)) + lo%
  501.  
  502. ' found at [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]:    http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
  503. SUB fTri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  504.     DIM a&
  505.     a& = _NEWIMAGE(1, 1, 32)
  506.     _DEST a&
  507.     PSET (0, 0), K
  508.     _DEST 0
  509.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  510.     _FREEIMAGE a& '<<< this is important!
  511.  
  512. SUB ln (x1, y1, x2, y2, K AS _UNSIGNED LONG) 'box frame
  513.     LINE (x1, y1)-(x2, y2), K
  514.  
  515. 'from Steve Gold standard
  516. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  517.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  518.     DIM X AS INTEGER, Y AS INTEGER
  519.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  520.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  521.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  522.     WHILE X > Y
  523.         RadiusError = RadiusError + Y * 2 + 1
  524.         IF RadiusError >= 0 THEN
  525.             IF X <> Y + 1 THEN
  526.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  527.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  528.             END IF
  529.             X = X - 1
  530.             RadiusError = RadiusError - X * 2
  531.         END IF
  532.         Y = Y + 1
  533.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  534.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  535.     WEND
  536.  
  537.  

here is my raw idea of incremental speed for shooter.
Thanks
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Invaders bplus style
« Reply #26 on: August 01, 2019, 09:25:20 am »
Thanks TempodiBasic,

I have thought about allowing a speed increase to shooter but forgot about it when I learned strategies for shooting the aliens and started breaking 1000 regularly.

I don't think we need another .dv variable though. I will play around with this idea, thanks again.

"spamming" the aliens, ha! that's better than "machine gunning" :D


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Invaders bplus style
« Reply #27 on: August 01, 2019, 10:58:36 am »
Hi TempodiBasic,

A .dv is not needed, these changes will work without the .dv added to Type:
Code: QB64: [Select]
  1.         IF kh = 18432 OR kh = 20480 THEN o(0).dx = 0 'up or down, stop for either key (new for down arrow)
  2.  
  3.         'For TempodiBasic acceleration idea
  4.         IF kh = 19200 THEN 'left or more left
  5.             IF o(0).dx < 0 AND o(0).dx > -8 THEN o(0).dx = o(0).dx - 1 ELSE o(0).dx = -3
  6.         END IF
  7.         IF kh = 19712 THEN 'right or more right
  8.             IF o(0).dx > 0 AND o(0).dx < 8 THEN o(0).dx = o(0).dx + 1 ELSE o(0).dx = 3
  9.         END IF
  10.  

I also modified shooter for reporting .dx for testing with acceleration:
Code: QB64: [Select]
  1. SUB drawshooter (x)
  2.     DIM y1, y2, x1, x2
  3.     'calculate 3 points of triangle shooter
  4.     y1 = ymax - 10
  5.     y2 = ymax - 60
  6.     x1 = x - 50
  7.     x2 = x + 50
  8.     fTri x, y1, x1, ymax, x, y2, &HFF0000BB
  9.     fTri x, y1, x2, ymax, x, y2, &HFF0000BB
  10.     ln x, y1, x1, ymax, _RGB32(255, 255, 128)
  11.     ln x1, ymax, x, y2, _RGB32(255, 255, 128)
  12.     ln x, y1, x2, ymax, _RGB32(255, 255, 128)
  13.     ln x2, ymax, x, y2, _RGB32(255, 255, 128)
  14.  
  15.     ' For TempodiBasic Mod this might be handy
  16.     'ln x, y1, x, y2, _RGB32(255, 255, 128)
  17.     COLOR &HFF88BBFF, &HFF0000BB
  18.     _PRINTSTRING (x - 8, y1 - 24), STR$(o(0).dx)
  19.     COLOR &HFFFFFFFF, &HFF000000
  20.  

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Invaders bplus style
« Reply #28 on: August 01, 2019, 05:20:12 pm »
Hi Bplus

what to say, it is clear that clearer is the code better is the result! ;)

here news
Code: QB64: [Select]
  1. _TITLE "Invaders b0_4_1" 'Bplus started 2019-07-27 inspired by Ken's fun program series
  2.  
  3. ' 2019-07-29 b0_3 from feed back fix game ending with big "Game Over" sign and delay before Top Ten.
  4. ' Show score to compare with Top Ten Numbers.
  5. ' Change the way hits are calculated, use method that avoids distance function or ABS.
  6. ' Change TopTen sub to TopTenGoAgain$ function to also get Play Again reply.
  7. ' OK let's start charging for bullets! 1 point per... and do a hit % to reward skillful shooting
  8. ' change BEEPs to SOUNDS, add more to report, Game Over signals end of game, TopTen does go again also.
  9.  
  10. ' 2019-07-31 Rework the Top Ten screen using Text sub routine that I want to demo in "another one for the Toolbox."
  11. ' This new TopTen function now uses inputBox$ which added a ton of lines to the program!
  12.  
  13. '2019-08-01  incremental speed of shooter
  14.  
  15. CONST xmax = 1200, ymax = 720, PI = 3.141592653589793, PD2 = 1.570796326794897, PT2 = 6.283185307
  16. SCREEN _NEWIMAGE(xmax, ymax, 32)
  17. _SCREENMOVE 100, 20
  18.  
  19. TYPE typeO
  20.     x AS SINGLE
  21.     y AS SINGLE
  22.     xc AS SINGLE
  23.     yc AS SINGLE
  24.     dx AS SINGLE
  25.     dy AS SINGLE
  26.     a AS SINGLE
  27.     lastX AS SINGLE
  28.     lastY AS SINGLE
  29.     v1 AS SINGLE
  30.     v2 AS SINGLE
  31.     size AS SINGLE
  32.     live AS INTEGER
  33.     exploding AS INTEGER
  34.     lastShot AS SINGLE
  35.     c AS _UNSIGNED LONG
  36.  
  37. DIM SHARED o(100) AS typeO, shoot AS INTEGER, points AS INTEGER, bullets AS INTEGER, hits AS INTEGER
  38. DIM i AS INTEGER, j AS INTEGER, kh AS LONG, red AS INTEGER, again$
  39.     setUp
  40.     WHILE o(0).live
  41.         LINE (0, 0)-(xmax, ymax), _RGBA(0, 0, 0, 255), BF
  42.         kh = _KEYHIT
  43.         IF kh = 32 THEN shoot = -1
  44.         'IF kh = 18432 THEN o(0).dx = 0
  45.         ' IF kh = 19200 THEN o(0).dx = -3
  46.         ' IF kh = 19712 THEN o(0).dx = 3
  47.  
  48.         IF kh = 18432 OR kh = 20480 THEN o(0).dx = 0 'up or down, stop for either key (new for down arrow)
  49.  
  50.         'For TempodiBasic acceleration idea
  51.         IF kh = 19200 THEN 'left or more left
  52.             IF o(0).dx < 0 AND o(0).dx > -8 THEN o(0).dx = o(0).dx - 1 ELSE o(0).dx = -3
  53.         END IF
  54.         IF kh = 19712 THEN 'right or more right
  55.             IF o(0).dx > 0 AND o(0).dx < 8 THEN o(0).dx = o(0).dx + 1 ELSE o(0).dx = 3
  56.         END IF
  57.  
  58.         report
  59.  
  60.         'dead ships and bullets? but still exploding  this separated out because ships are getting hit more than once while exploding
  61.         FOR i = 1 TO 3
  62.             IF o(i).exploding THEN
  63.                 o(i).exploding = o(i).exploding - 1
  64.                 IF o(i).exploding = 0 THEN
  65.                     newEnemy i
  66.                 ELSE 'draw explosion
  67.                     SOUND 1000 - o(i).size * 3 + (21 - o(i).exploding) * 10, .1
  68.                     red = rand(60, 255)
  69.                     fcirc o(i).x, o(i).y, o(i).exploding * 3, _RGB32(red, rand(0, red), 0)
  70.                 END IF
  71.             END IF 'i = x
  72.         NEXT
  73.         'bullets
  74.         FOR i = 4 TO 100
  75.             IF o(i).exploding THEN
  76.                 o(i).exploding = o(i).exploding - 1
  77.                 SOUND 1600, .05
  78.                 red = rand(60, 255)
  79.                 fcirc o(i).x, o(i).y, o(i).exploding, _RGB32(red, rand(0, red), 0)
  80.             END IF
  81.         NEXT
  82.  
  83.         FOR i = 0 TO 100
  84.             IF o(i).live <> 0 THEN 'draw everything, update positions, check updated position
  85.                 IF i = 0 THEN 'shooter
  86.                     IF o(0).exploding = 0 THEN
  87.                         drawshooter o(i).x
  88.                         IF shoot AND (TIMER(.001) - o(0).lastShot) > .1 THEN '.2 is this the cause of hitting a ship twice?
  89.                             newBullet 0, o(0).x, ymax - 60
  90.                         END IF
  91.                         IF o(i).x + o(i).dx > 0 AND o(i).x + o(i).dx < xmax THEN
  92.                             o(i).x = o(i).x + o(i).dx
  93.                         ELSE
  94.                             o(i).dx = -o(i).dx
  95.                         END IF
  96.                     ELSEIF o(0).exploding THEN 'exploded enough
  97.                         o(i).exploding = o(i).exploding - 1
  98.                         IF o(i).exploding = 0 THEN 'no longer exploding
  99.                             o(0).live = o(0).live - 1
  100.                             IF o(0).live = 0 THEN
  101.                                 fcirc o(0).x, ymax - 75, 50, &HFF770000
  102.                                 report
  103.                                 EXIT FOR
  104.                             ELSE
  105.                                 drawshooter o(i).x
  106.                             END IF
  107.                         ELSE 'exploding
  108.                             SOUND 400 + o(0).exploding * 7, .3
  109.                             red = rand(60, 255)
  110.                             fcirc o(0).x, ymax - 75, o(0).exploding * 6, _RGB32(red, rand(0, red), 0)
  111.                         END IF
  112.                     END IF
  113.  
  114.                 ELSEIF i > 0 AND i < 4 THEN 'enemy ships
  115.                     'update coodinates
  116.                     o(i).lastX = o(i).x: o(i).lastY = o(i).y
  117.                     o(i).x = o(i).xc + 150 * (COS(o(i).a) + COS(o(i).v1 * o(i).a) / 2 + SIN(o(i).v2 * o(i).a) / 3)
  118.                     o(i).y = o(i).yc + 150 * (SIN(o(i).a) + SIN(o(i).v1 * o(i).a) / 2 + COS(o(i).v2 * o(i).a) / 3)
  119.                     drawRat i
  120.                     o(i).a = o(i).a + PI / 1440
  121.                     IF o(i).xc + o(i).dx > 0 AND o(i).xc + o(i).dx < xmax THEN
  122.                         o(i).xc = o(i).xc + o(i).dx
  123.                     ELSE
  124.                         o(i).dx = -o(i).dx
  125.                     END IF
  126.                     'drop bombs
  127.                     IF TIMER(.001) - o(i).lastShot > 3 THEN
  128.                         newBullet i, o(i).x, o(i).y + o(i).size
  129.                     END IF
  130.  
  131.                 ELSEIF i > 3 AND i < 101 THEN 'bullets
  132.                     fcirc o(i).x, o(i).y, o(i).size, o(i).c
  133.                     IF o(i).y + o(i).dy > 0 AND o(i).y + o(i).dy < ymax THEN
  134.                         IF o(i).dy > 0 THEN o(i).dy = o(i).dy + .1 'gravity
  135.                         o(i).y = o(i).y + o(i).dy
  136.                     ELSE
  137.                         o(i).live = 0
  138.                     END IF
  139.  
  140.                     'did this bullet hit anything
  141.                     IF o(i).dy > 0 THEN 'did it hit the shooter
  142.                         IF (o(0).x - o(0).size <= o(i).x) AND (o(i).x <= o(0).x + o(0).size) THEN
  143.                             IF (o(0).y - o(0).size <= o(i).y) AND (o(i).y <= o(0).y + o(0).size + 20) THEN
  144.                                 IF o(0).exploding = 0 AND o(0).live THEN
  145.                                     SOUND 400 + 5 * 20, .1
  146.                                     o(0).exploding = 20 'signal exploding
  147.                                     o(i).live = 0 'kill bullet
  148.                                 END IF
  149.                             END IF
  150.                         END IF
  151.                     ELSEIF o(i).dy < 0 THEN 'did it hit the enemy?
  152.                         FOR j = 1 TO 3
  153.                             IF (o(j).x - o(j).size <= o(i).x) AND (o(i).x <= o(j).x + o(j).size) THEN 'is x right
  154.                                 IF (o(j).y - o(j).size - 5 < o(i).y) AND (o(i).y <= o(j).y + o(j).size + 5) THEN 'is y right
  155.                                     IF o(j).exploding = 0 AND o(j).live <> 0 THEN 'ship not exploding already
  156.                                         o(j).exploding = 20
  157.                                         SOUND 800 - o(i).size * 3, .1
  158.                                         points = points + 50 - o(j).size
  159.                                         hits = hits + 1
  160.                                         o(i).live = 0: o(j).live = 0 'kill bullet and ship
  161.                                     END IF 'if not exploding already
  162.                                 END IF 'if y is right
  163.                             END IF 'if x is right
  164.                         NEXT
  165.  
  166.                         'finally bullet versus bullet!!  remember these bullets (i) are headed up
  167.                         FOR j = i + 1 TO 100 ' find only those going in different directions
  168.                             IF o(j).dy > 0 THEN 'look for bullets headed down
  169.                                 IF o(j).live THEN
  170.                                     IF o(j).x - 3 <= o(i).x AND o(i).x <= o(j).x + 3 THEN 'is x right
  171.                                         IF (o(j).y - 8 <= o(i).y) AND (o(i).y <= o(j).y + o(j).dy) THEN 'is y right  why 16 gravity accums
  172.                                             fcirc o(i).x, o(i).y, 200, &HFFFFFFFF
  173.                                             o(i).live = 0: o(j).live = 0
  174.                                             o(i).exploding = 10
  175.                                             SOUND 2800, 1
  176.                                         END IF 'if y is right
  177.                                     END IF 'if x is right
  178.                                 END IF 'both still live
  179.                             END IF 'bullets going in opposite directions
  180.                         NEXT
  181.                     END IF 'bullet hit
  182.                 END IF 'shooter
  183.             END IF 'live
  184.         NEXT
  185.         _DISPLAY
  186.         _LIMIT 60
  187.     WEND
  188.     cText xmax / 2, ymax / 2, 128, &HFFFF5500, "Game Over"
  189.     _DISPLAY: _DELAY 2.5: _KEYCLEAR ' stop hammer'n the keys!  ;-))
  190.     again$ = topTenGoAgain$(points)
  191. LOOP UNTIL LEN(again$)
  192.  
  193. SUB setUp
  194.     'obj 0 is the player's shooter
  195.     DIM i AS INTEGER
  196.     ERASE o
  197.     points = 0: bullets = 0: hits = 0
  198.     o(0).x = xmax / 2: o(0).y = ymax - 60: o(0).size = 50
  199.     o(0).live = 10
  200.     FOR i = 1 TO 3 'enemy
  201.         newEnemy i
  202.     NEXT
  203.  
  204. SUB newEnemy (i)
  205.     DIM r, g, b
  206.     IF i < 1 OR i > 3 THEN BEEP: EXIT SUB
  207.     o(i).a = RND * PT2: o(i).live = 1: o(i).v1 = rand(2, 19): o(i).v2 = rand(2, 19)
  208.     r = rand(128, 255): g = rand(0, .5 * r): b = rand(0, .5 * g)
  209.     o(i).size = rand(10, 45): o(i).c = _RGB32(r, g, b)
  210.     o(i).yc = ymax / 2 - 30: o(i).lastShot = TIMER(.003) + i
  211.     IF RND < .5 THEN
  212.         o(i).xc = 0: o(i).dx = 1
  213.     ELSE
  214.         o(i).xc = xmax: o(i).dx = -1
  215.     END IF
  216.  
  217. SUB newBullet (who, x, y)
  218.     DIM ii AS INTEGER
  219.     FOR ii = 4 TO 100 'find bullet slot
  220.         IF o(ii).live = 0 AND o(ii).exploding = 0 THEN EXIT FOR 'got slot
  221.     NEXT
  222.     IF ii >= 4 AND ii <= 100 THEN
  223.         o(ii).x = x: o(ii).y = y: o(ii).size = 2: o(ii).live = -1: o(who).lastShot = TIMER(.001)
  224.         IF shoot AND who = 0 THEN
  225.             o(ii).dy = -10: o(ii).c = &HFFFFFFFF: bullets = bullets + 1: points = points - 1
  226.             SOUND 700, .3
  227.         ELSEIF who > 0 AND who < 4 THEN
  228.             o(ii).dy = 1: o(ii).c = &HFFFFFF00
  229.             SOUND 300, 1
  230.         END IF
  231.     END IF
  232.     shoot = 0
  233.  
  234. SUB report
  235.     DIM s$
  236.     s$ = "Lives: " + TS$(o(0).live) + "           Bullets: " + TS$(bullets) + "    Hits: " + TS$(hits) + "    Eff% "
  237.     IF bullets = 0 THEN s$ = s$ + "**" ELSE s$ = s$ + TS$(100 * hits \ bullets)
  238.     s$ = s$ + "           Points: " + TS$(points)
  239.     cText xmax / 2, 30, 20, &HFF009900, s$
  240.  
  241. SUB drawRat (i)
  242.     DIM noseX, noseY, neckX, neckY, tailX, tailY, earLX, earLY, earRX, earRY, wX, wY, rh
  243.     rh = _ATAN2(o(i).y - o(i).lastY, o(i).x - o(i).lastX)
  244.     noseX = o(i).x + 2 * o(i).size * COS(rh)
  245.     noseY = o(i).y + 2 * o(i).size * SIN(rh)
  246.     neckX = o(i).x + .75 * o(i).size * COS(rh)
  247.     neckY = o(i).y + .75 * o(i).size * SIN(rh)
  248.     tailX = o(i).x + 2 * o(i).size * COS(rh + _PI)
  249.     tailY = o(i).y + 2 * o(i).size * SIN(rh + _PI)
  250.     earLX = o(i).x + o(i).size * COS(rh - _PI(1 / 12))
  251.     earLY = o(i).y + o(i).size * SIN(rh - _PI(1 / 12))
  252.     earRX = o(i).x + o(i).size * COS(rh + _PI(1 / 12))
  253.     earRY = o(i).y + o(i).size * SIN(rh + _PI(1 / 12))
  254.     fcirc o(i).x, o(i).y, .65 * o(i).size, o(i).c
  255.     fcirc neckX, neckY, o(i).size * .3, o(i).c
  256.     fTri noseX, noseY, earLX, earLY, earRX, earRY, o(i).c
  257.     fcirc earLX, earLY, o(i).size * .3, o(i).c
  258.     fcirc earRX, earRY, o(i).size * .3, o(i).c
  259.     wX = .5 * o(i).size * COS(rh - _PI(11 / 18))
  260.     wY = .5 * o(i).size * SIN(rh - _PI(11 / 18))
  261.     ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, o(i).c
  262.     wX = .5 * o(i).size * COS(rh - _PI(7 / 18))
  263.     wY = .5 * o(i).size * SIN(rh - _PI(7 / 18))
  264.     ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, o(i).c
  265.     ln o(i).x, o(i).y, tailX, tailY, o(i).c
  266. SUB drawshooter (x)
  267.     DIM y1, y2, x1, x2
  268.     'calculate 3 points of triangle shooter
  269.     y1 = ymax - 10
  270.     y2 = ymax - 60
  271.     x1 = x - 50
  272.     x2 = x + 50
  273.     fTri x, y1, x1, ymax, x, y2, &HFF0000BB
  274.     fTri x, y1, x2, ymax, x, y2, &HFF0000BB
  275.     ln x, y1, x1, ymax, _RGB32(255, 255, 128)
  276.     ln x1, ymax, x, y2, _RGB32(255, 255, 128)
  277.     ln x, y1, x2, ymax, _RGB32(255, 255, 128)
  278.     ln x2, ymax, x, y2, _RGB32(255, 255, 128)
  279.  
  280.     ' For TempodiBasic Mod this might be handy
  281.     'ln x, y1, x, y2, _RGB32(255, 255, 128)
  282.     COLOR &HFF88BBFF, &HFF0000BB
  283.     _PRINTSTRING (x - 8, y1 - 24), STR$(o(0).dx)
  284.     COLOR &HFFFFFFFF, &HFF000000
  285.  
  286. ' This FUNCTION creates a file in the same folder as your .bas source or .exe
  287. 'EDIT: 2019-07-31 this function needs:
  288. ' SUB cText(x, y, pixelTextHeight, Colr)
  289. ' SUB inputBox$(prompt$, title$, maxBoxWidth)
  290. ' which needs scnState(restoreTF)
  291. FUNCTION topTenGoAgain$ (compareScore AS INTEGER)
  292.     DIM fName$, n AS INTEGER, names$(1 TO 10), scores(1 TO 10), NAME$, score AS INTEGER
  293.     DIM settleScore AS INTEGER, i AS INTEGER, yc, s$
  294.  
  295.     fName$ = "Top 10 Scores.txt" '<<<  since this is toolbox code change this as needed for app
  296.     CLS
  297.     cText _WIDTH / 2, _HEIGHT / 8, 20, &HFF0000FF, "Your score was:" + STR$(compareScore)
  298.     IF _FILEEXISTS(fName$) THEN
  299.         OPEN fName$ FOR INPUT AS #1
  300.         WHILE EOF(1) = 0 AND n < 10
  301.             n = n + 1
  302.             INPUT #1, NAME$
  303.             INPUT #1, score
  304.             IF compareScore >= score AND settleScore = 0 THEN
  305.                 names$(n) = inputBox$("Please enter your name here:", "You have made the Top Ten!", 40)
  306.                 scores(n) = compareScore
  307.                 settleScore = -1
  308.                 n = n + 1
  309.                 IF n <= 10 THEN names$(n) = NAME$: scores(n) = score
  310.             ELSE
  311.                 scores(n) = score: names$(n) = NAME$
  312.             END IF
  313.         WEND
  314.         CLOSE #1
  315.         IF n < 10 AND settleScore = 0 THEN
  316.             NAME$ = inputBox$("Please enter your name here:", "Top Ten has slot open for you:", 40)
  317.             IF NAME$ <> "" THEN n = n + 1: names$(n) = NAME$: scores(n) = compareScore
  318.         END IF
  319.         IF n > 10 THEN n = 10
  320.         yc = (_HEIGHT - 20 * (n + 2)) / 2
  321.         cText _WIDTH / 2, yc, 40, &HFFFFFF00, "Top Ten Scorers and Scores:"
  322.         OPEN fName$ FOR OUTPUT AS #1
  323.         FOR i = 1 TO n
  324.             PRINT #1, names$(i): PRINT #1, scores(i)
  325.             s$ = RIGHT$(" " + STR$(i), 2) + "  " + LEFT$(names$(i) + STRING$(25, "."), 20)
  326.             s$ = s$ + RIGHT$(SPACE$(10) + STR$(scores(i)), 10)
  327.             cText _WIDTH / 2, yc + 30 + i * 20, 20, &HFF00FFFF, s$
  328.         NEXT
  329.         _DISPLAY
  330.         _DELAY 3.5
  331.         CLOSE #1
  332.     ELSE
  333.         NAME$ = inputBox("Please enter your name here:", "You are first into Top Ten file.", 40)
  334.         OPEN fName$ FOR OUTPUT AS #1
  335.         PRINT #1, NAME$: PRINT #1, compareScore
  336.         CLOSE #1
  337.     END IF
  338.     topTenGoAgain$ = inputBox$("Press <Enter> to play again, enter q (or any) to quit... ", "Play Again?", 66)
  339.  
  340. 'center the text around (x, y) point, needs a graphics screen!
  341. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  342.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  343.     fg = _DEFAULTCOLOR
  344.     'screen snapshot
  345.     cur& = _DEST
  346.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  347.     _DEST I&
  348.     COLOR K, _RGBA32(0, 0, 0, 0)
  349.     _PRINTSTRING (0, 0), txt$
  350.     mult = textHeight / 16
  351.     xlen = LEN(txt$) * 8 * mult
  352.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  353.     COLOR fg
  354.     _FREEIMAGE I&
  355.  
  356. ' You can grab this box by title and drag it around screen for full viewing while answering prompt.
  357. ' Only one line allowed for prompt$
  358. ' boxWidth is 4 more than the allowed length of input, it needs to be longer than title$ and prompt$ also
  359. ' Utilities > Input Box > Input Box 1 tester v 2019-07-31
  360. ' This FUNCTION needs scnState(restroreTF)
  361. FUNCTION inputBox$ (prompt$, title$, boxWidth AS _BYTE)
  362.     DIM ForeColor AS _UNSIGNED LONG, BackColor AS _UNSIGNED LONG, White AS _UNSIGNED LONG
  363.     DIM sw AS INTEGER, sh AS INTEGER, curScrn AS LONG, backScrn AS LONG, ibx AS LONG 'some handles
  364.  
  365.     'colors
  366.     ForeColor = &HFF000055 '<  change as desired  prompt text color, back color or type in area
  367.     BackColor = &HFF6080CC '<  change as desired  used fore color in type in area
  368.     White = &HFFFFFFFF
  369.  
  370.     'items to restore at exit
  371.     scnState 0
  372.  
  373.     'screen snapshot
  374.     sw = _WIDTH: sh = _HEIGHT: curScrn = _DEST
  375.     backScrn = _NEWIMAGE(sw, sh, 32)
  376.     _PUTIMAGE , curScrn, backScrn
  377.  
  378.     'moving box around on screen
  379.     DIM bxW AS INTEGER, bxH AS INTEGER
  380.     DIM mb AS INTEGER, mx AS INTEGER, my AS INTEGER, mi AS INTEGER, grabx AS INTEGER, graby AS INTEGER
  381.     DIM tlx AS INTEGER, tly AS INTEGER 'top left corner of message box
  382.     DIM lastx AS INTEGER, lasty AS INTEGER
  383.     DIM INP$, kh&
  384.  
  385.     'draw message box
  386.     bxW = boxWidth * 8: bxH = 7 * 16
  387.     ibx = _NEWIMAGE(bxW, bxH, 32)
  388.     _DEST ibx
  389.     COLOR &HFF880000, White
  390.     LOCATE 1, 1: PRINT LEFT$(SPACE$(INT((boxWidth - LEN(title$) - 3)) / 2) + title$ + SPACE$(boxWidth), boxWidth)
  391.     COLOR White, &HFFBB0000
  392.     LOCATE 1, boxWidth - 2: PRINT " X "
  393.     COLOR ForeColor, BackColor
  394.     LOCATE 2, 1: PRINT SPACE$(boxWidth);
  395.     LOCATE 3, 1: PRINT LEFT$(SPACE$((boxWidth - LEN(prompt$)) / 2) + prompt$ + SPACE$(boxWidth), boxWidth);
  396.     LOCATE 4, 1: PRINT SPACE$(boxWidth);
  397.     LOCATE 5, 1: PRINT SPACE$(boxWidth);
  398.     LOCATE 6, 1: PRINT SPACE$(boxWidth);
  399.     INP$ = ""
  400.     GOSUB finishBox
  401.  
  402.     'convert to pixels the top left corner of box at moment
  403.     bxW = boxWidth * 8: bxH = 5 * 16
  404.     tlx = (sw - bxW) / 2: tly = (sh - bxH) / 2
  405.     lastx = tlx: lasty = tly
  406.     _KEYCLEAR
  407.     'now allow user to move it around or just read it
  408.     WHILE 1
  409.         CLS
  410.         _PUTIMAGE , backScrn
  411.         _PUTIMAGE (tlx, tly), ibx, curScrn
  412.         _DISPLAY
  413.         WHILE _MOUSEINPUT: WEND
  414.         mx = _MOUSEX: my = _MOUSEY: mb = _MOUSEBUTTON(1)
  415.         IF mb THEN
  416.             IF mx >= tlx AND mx <= tlx + bxW AND my >= tly AND my <= tly + 16 THEN 'mouse down on title bar
  417.                 IF mx >= tlx + bxW - 24 THEN EXIT WHILE
  418.                 grabx = mx - tlx: graby = my - tly
  419.                 DO WHILE mb 'wait for release
  420.                     mi = _MOUSEINPUT: mb = _MOUSEBUTTON(1)
  421.                     mx = _MOUSEX: my = _MOUSEY
  422.                     IF mx - grabx >= 0 AND mx - grabx <= sw - bxW AND my - graby >= 0 AND my - graby <= sh - bxH THEN
  423.                         'attempt to speed up with less updates
  424.                         IF ((lastx - (mx - grabx)) ^ 2 + (lasty - (my - graby)) ^ 2) ^ .5 > 10 THEN
  425.                             tlx = mx - grabx: tly = my - graby
  426.                             CLS
  427.                             _PUTIMAGE , backScrn
  428.                             _PUTIMAGE (tlx, tly), ibx, curScrn
  429.                             lastx = tlx: lasty = tly
  430.                             _DISPLAY
  431.                         END IF
  432.                     END IF
  433.                     _LIMIT 400
  434.                 LOOP
  435.             END IF
  436.         END IF
  437.         kh& = _KEYHIT
  438.         SELECT CASE kh& 'whew not much for the main event!
  439.             CASE 13: EXIT WHILE
  440.             CASE 27: INP$ = "": EXIT WHILE
  441.             CASE 32 TO 128: IF LEN(INP$) < boxWidth - 4 THEN INP$ = INP$ + CHR$(kh&): GOSUB finishBox ELSE BEEP
  442.             CASE 8: IF LEN(INP$) THEN INP$ = LEFT$(INP$, LEN(INP$) - 1): GOSUB finishBox ELSE BEEP
  443.         END SELECT
  444.  
  445.         _LIMIT 60
  446.     WEND
  447.  
  448.     'put things back
  449.     scnState 1 'need fg and bg colors set to cls
  450.     CLS '? is this needed YES!!
  451.     _PUTIMAGE , backScrn
  452.     _DISPLAY
  453.     _FREEIMAGE backScrn
  454.     _FREEIMAGE ibx
  455.     scnState 1 'because we have to call _display, we have to call this again
  456.     inputBox$ = INP$
  457.  
  458.     finishBox:
  459.     _DEST ibx
  460.     COLOR BackColor, ForeColor
  461.     LOCATE 5, 2: PRINT LEFT$(" " + INP$ + SPACE$(boxWidth - 2), boxWidth - 2)
  462.     _DEST curScrn
  463.     RETURN
  464.  
  465. 'from mBox v 2019-07-31 update
  466. ' for saving and restoring screen settins
  467. SUB scnState (restoreTF AS INTEGER) 'Thanks Steve McNeill
  468.     STATIC Font AS LONG, DefaultColor AS _UNSIGNED LONG, BackGroundColor AS _UNSIGNED LONG, Dest AS LONG, Source AS LONG
  469.     STATIC row AS INTEGER, col AS INTEGER, autodisplay AS INTEGER, mb AS INTEGER
  470.     IF restoreTF THEN
  471.         _FONT Font
  472.         COLOR DefaultColor, BackGroundColor
  473.         _DEST Dest
  474.         _SOURCE Source
  475.         LOCATE row, col
  476.         IF autodisplay THEN _AUTODISPLAY ELSE _DISPLAY
  477.         _KEYCLEAR
  478.         WHILE _MOUSEINPUT: WEND 'clear mouse clicks
  479.         mb = _MOUSEBUTTON(1)
  480.         IF mb THEN
  481.             DO
  482.                 WHILE _MOUSEINPUT: WEND
  483.                 mb = _MOUSEBUTTON(1)
  484.                 _LIMIT 100
  485.             LOOP UNTIL mb = 0
  486.         END IF
  487.     ELSE
  488.         Font = _FONT: DefaultColor = _DEFAULTCOLOR: BackGroundColor = _BACKGROUNDCOLOR
  489.         Dest = _DEST: Source = _SOURCE
  490.         row = CSRLIN: col = POS(0): autodisplay = _AUTODISPLAY
  491.     END IF
  492.  
  493.     TS$ = _TRIM$(STR$(n))
  494.  
  495. FUNCTION rand% (lo%, hi%)
  496.     rand% = INT(RND * (hi% - lo% + 1)) + lo%
  497.  
  498. ' found at [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]:    http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
  499. SUB fTri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  500.     DIM a&
  501.     a& = _NEWIMAGE(1, 1, 32)
  502.     _DEST a&
  503.     PSET (0, 0), K
  504.     _DEST 0
  505.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  506.     _FREEIMAGE a& '<<< this is important!
  507.  
  508. SUB ln (x1, y1, x2, y2, K AS _UNSIGNED LONG) 'box frame
  509.     LINE (x1, y1)-(x2, y2), K
  510.  
  511. 'from Steve Gold standard
  512. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  513.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  514.     DIM X AS INTEGER, Y AS INTEGER
  515.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  516.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  517.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  518.     WHILE X > Y
  519.         RadiusError = RadiusError + Y * 2 + 1
  520.         IF RadiusError >= 0 THEN
  521.             IF X <> Y + 1 THEN
  522.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  523.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  524.             END IF
  525.             X = X - 1
  526.             RadiusError = RadiusError - X * 2
  527.         END IF
  528.         Y = Y + 1
  529.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  530.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  531.     WEND
  532.  
  533.  


Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Invaders bplus style
« Reply #29 on: August 01, 2019, 07:45:58 pm »
Hi TempodiBasic,

How do you like the accelerator? ha! have you time to play with it?

For me, I got used to the original speed +- 3 and learned tricks for shooting the aliens that look like rat/mice.
And the numbers on the shooter are complete distraction! for me anyway.

But someone who has not practiced with first 3 mods of this code might love the accelerator and numbers report on shooter??? I donno...