Author Topic: b+ Asteroids makeover  (Read 9262 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: b+ Asteroids makeover
« Reply #30 on: November 01, 2020, 05:05:32 pm »
LOL awesome saucers! It's getting harder too. Is there a way to keep the game moving when the saucer blows up?

I am glad you like the saucers because more are coming your way! hee, hee wait until you see a couple of them double teaming you!

Yeah, as long as you have lives left ie <> 0 then press a button and play the next round. You might as well press the space bar because you don't want to stop shooting for a second! I have now increased lives at start to 10.

Bigger scores because target rich environment! Saucers or Death Bolders are 100 points.

M5 more of what you love in moving space (WIP):
Code: QB64: [Select]
  1. _TITLE "b+ Asteroids m5 They are Here" 'started 2018-07-13"
  2. ' 2020-10-27 remove the alternate subs and get down below 200 LOC almost there now! new shooter action font and background
  3. ' 2020-10-28 another makeover explosions and split asteroids
  4. ' 2020-10-29 fix baby rock management, break between lives
  5. ' 2020-10-29 fix left/right gun, fix explosions over many frames to eliminate pause in action, speed up 60 fps
  6. ' 2020-10-30 m3 SierraKen's idea to angle shooter with mousewheel also finish WASD options, more rocks, points system
  7. ' points:
  8. ' The higher the speed the better    speed range 2 to 5, diff = 3 * 33.3333 = 100          s - 2 * 33.3333
  9. ' The lower the color the better   color range 10 to 60, diff =      50 * 2 = 100  50 - (c - 10) * 2
  10. ' The small        er the size the better  size range 10 to 100, diff = 90 * 1.1111 = 100  90 - (sz -10) * 1.1111
  11. '        ((speed - 2) * 33.3333 + (50 - (c -10)) * 2 + (90 - (r - 10)) * 1.1111) / 3 = 100 best score per hit
  12. ' 2020-10-30 increase level of difficulty, fix double lives lost, add an ending after all lives spent.
  13. ' 2020-10-31 M4 They are Here - the aliens have accepted my invitaion for war games don't get caught in their beam.
  14. ' rework ending and variable LONG suffix. Aliens on the attack 100 points before or after transformed into the Bolder of Death.
  15. ' 2020-11-01 FX Moving through space, Oh yeah, more aliens!
  16.  
  17. '================================================================================================================
  18.  
  19. '    NOTE: !!!!!!!!!!!!!!!   When there is a pause in action, just hit any key to reset next life.
  20.  
  21. '================================================================================================================
  22.  
  23. CONST xmax = 1200, ymax = 700, pi = _PI, polyAngle = _PI / 6, nRocks = 300, nBullets = 2000, bSpeed = 15
  24.  
  25. TYPE alienType
  26.     x AS SINGLE
  27.     y AS SINGLE
  28.     dx AS SINGLE
  29.     dy AS SINGLE
  30.     ls AS LONG ' lights offset
  31.     c AS _UNSIGNED LONG ' color
  32.     live AS LONG
  33.     attackFrame AS LONG
  34.     fireX AS LONG
  35.     fireY AS LONG
  36.     transform AS LONG
  37.  
  38. TYPE particle
  39.     x AS LONG
  40.     y AS LONG
  41.     dx AS SINGLE
  42.     dy AS SINGLE
  43.     size AS SINGLE
  44.     kolor AS _UNSIGNED LONG
  45.  
  46. TYPE bullet
  47.     x AS LONG
  48.     y AS LONG
  49.     dx AS SINGLE
  50.     dy AS SINGLE
  51.     live AS LONG
  52.  
  53. TYPE shipType
  54.     x AS LONG
  55.     y AS LONG
  56.     live AS LONG
  57.     a AS SINGLE '   rotated position usu gun left or right (mouse button), maybe up press w or down press z
  58.  
  59. TYPE rock
  60.     x AS LONG
  61.     y AS LONG
  62.     r AS LONG '            radius
  63.     ra AS SINGLE '         rotation position   a = a + spin
  64.     heading AS SINGLE '    heading from which dx, dy are calc with speed
  65.     speed AS SINGLE '      speed
  66.     spin AS SINGLE '       rotation direction and amount
  67.     seed AS LONG '         for drawing rocks with RND USING
  68.     c AS LONG '            color   rgb(c, c, c)
  69.     live AS LONG '         need this to track rocks still active like bullets
  70.     explodeFrame AS LONG ' after a rock is hit by bullet, it explodes and in more than one frame
  71.  
  72. REDIM SHARED aliens(1 TO 5) AS alienType
  73. DIM SHARED dots(2000) AS particle
  74. DIM SHARED b(nBullets) AS bullet
  75. DIM SHARED ship AS shipType
  76. DIM SHARED r(nRocks) AS rock
  77. DIM SHARED points AS LONG
  78. DIM SHARED rocks AS LONG 'rocks is the minimum number of parent rocks to have on screen  automatic replace when hit or out of bounds
  79.  
  80. DIM fnt AS LONG, fnt2 AS LONG ' file LOAD handles
  81. DIM i AS LONG, bullets AS LONG, fire AS LONG ' index and bullets
  82. DIM r AS LONG, newRockN AS LONG, maxBabyRocks AS LONG, br AS LONG, hits AS LONG ' rock stuff
  83. DIM ai AS LONG, alienN AS LONG ' alien index and number
  84. DIM s$, t, lastt ' general string and times
  85.  
  86. SCREEN _NEWIMAGE(xmax, ymax, 32)
  87. _SCREENMOVE 100, 20
  88.  
  89. fnt = _LOADFONT("ARLRDBD.ttf", 16, "MONOSPACE")
  90. fnt2 = _LOADFONT("ARLRDBD.ttf", 40, "MONOSPACE")
  91. _FONT fnt
  92. COLOR &HFF00FFFF, &H00000000
  93.  
  94. alienN = 1
  95. rocks = 4 ' always active rocks
  96. lives = 10
  97. WHILE lives > 0 AND _KEYDOWN(27) = 0 ' init start restart
  98.     REDIM aliens(1 TO alienN) AS alienType
  99.     FOR ai = 1 TO alienN
  100.         newAlien ai
  101.     NEXT
  102.     FOR i = 1 TO nRocks 'reset rocks mainly clear baby rocks
  103.         newRock (i)
  104.         IF i > rocks THEN r(i).live = 0
  105.     NEXT
  106.     ship.x = xmax / 2 'avoids explosions top left corner at start, dang still get some!
  107.     ship.y = ymax / 2
  108.     ship.live = 1
  109.     WHILE ship.live AND _KEYDOWN(27) = 0
  110.         'draw everything then process bullets
  111.         drawStars 1
  112.         '   CIRCLE (aliens.fireX, aliens.fireY), 10, &HFFFFFFFF   transformtion poimt Bolder of Death
  113.         s$ = "Lives:" + STR$(lives) + "  Hits:" + STR$(hits) + "  Bullets:" + STR$(bullets) + "  Shooting:" + STR$(INT(hits * 100 / bullets)) + "%"
  114.         _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 - 20), s$
  115.         _FONT fnt2
  116.         s$ = STR$(points)
  117.         _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2), s$
  118.         _FONT fnt
  119.         FOR ai = 1 TO alienN
  120.             drawAliens ai
  121.         NEXT
  122.  
  123.         FOR i = 1 TO nRocks
  124.             IF r(i).live THEN drawRock i ' while drawing rocks the ship could be blown up
  125.         NEXT
  126.         FOR i = 1 TO nRocks 'smoke up the place with rock debris fields still flying out from hit frames ago
  127.             IF r(i).explodeFrame THEN
  128.                 r(i).explodeFrame = r(i).explodeFrame + 1
  129.                 IF r(i).explodeFrame > .5 * r(i).r THEN
  130.                     r(i).explodeFrame = 0
  131.                     IF i <= rocks THEN newRock i ' now replace the rock
  132.                 ELSE
  133.                     explode r(i).x, r(i).y, r(i).r, r(i).explodeFrame
  134.                 END IF
  135.             END IF
  136.         NEXT
  137.         IF ship.live THEN
  138.             FOR ai = 1 TO alienN
  139.                 IF SQR((aliens(ai).x - ship.x) ^ 2 + (aliens(ai).y - ship.y) ^ 2) < 60 THEN 'aliens and ship collisde boom boom
  140.                     FOR br = 1 TO 200
  141.                         fcirc ship.x, ship.y, br, _RGB32(255 - br, 255 - 2 * br, 0)
  142.                         _DISPLAY
  143.                         _LIMIT 300
  144.                     NEXT
  145.                     ship.live = 0
  146.                     _CONTINUE
  147.                 ELSE
  148.                     drawship
  149.                 END IF
  150.             NEXT
  151.             WHILE _MOUSEINPUT
  152.                 ship.a = ship.a + _MOUSEWHEEL * pi / 8 ' 22.5  degree changes, Thank Ken for this :)
  153.             WEND 'update ship
  154.             ship.x = _MOUSEX: ship.y = _MOUSEY
  155.             IF _MOUSEBUTTON(1) THEN ship.a = pi 'this is new left and right guns
  156.             IF _MOUSEBUTTON(2) THEN ship.a = 0
  157.             IF _KEYDOWN(ASC("w")) THEN ship.a = 1.5 * pi ' well it works but ??
  158.             IF _KEYDOWN(ASC("a")) THEN ship.a = pi
  159.             IF _KEYDOWN(ASC("s")) THEN ship.a = .5 * pi
  160.             IF _KEYDOWN(ASC("d")) THEN ship.a = 0
  161.             fire = 0
  162.             IF _KEYDOWN(32) THEN 'fire bullets
  163.                 t = TIMER(.01)
  164.                 IF lastt = 0 OR t - lastt > .2 THEN fire = 1: lastt = t
  165.             END IF
  166.             FOR i = 0 TO nBullets 'handle bullets
  167.                 IF b(i).live = 0 AND fire = 1 THEN 'have inactive bullet to use
  168.                     b(i).x = ship.x + bSpeed * COS(ship.a)
  169.                     b(i).y = ship.y + bSpeed * SIN(ship.a)
  170.                     b(i).dx = bSpeed * COS(ship.a)
  171.                     b(i).dy = bSpeed * SIN(ship.a)
  172.                     b(i).live = -1
  173.                     bullets = bullets + 1
  174.                     fire = 0
  175.                 END IF
  176.                 IF b(i).live THEN 'new location
  177.                     b(i).x = b(i).x + b(i).dx
  178.                     b(i).y = b(i).y + b(i).dy
  179.                     IF b(i).x > 0 AND b(i).x < xmax AND b(i).y > 0 AND b(i).y < ymax THEN 'in bounds draw it
  180.  
  181.                         'bullet hit aliens?
  182.                         FOR ai = 1 TO alienN
  183.                             IF SQR((aliens(ai).x - b(i).x) ^ 2 + (aliens(ai).y - b(i).y) ^ 2) < 30 THEN
  184.                                 FOR br = 1 TO 120
  185.                                     CIRCLE (aliens(ai).x, aliens(ai).y), br / 3, plasma~&(0)
  186.                                 NEXT
  187.                                 _DISPLAY
  188.                                 _DELAY .05
  189.                                 aliens(ai).live = 0
  190.                                 newAlien ai
  191.                                 points = points + 100
  192.                                 b(i).live = 0
  193.                                 _CONTINUE
  194.                             END IF
  195.                         NEXT
  196.                         FOR r = 1 TO nRocks 'check for collision with rock
  197.                             IF r(r).live THEN
  198.                                 IF SQR((r(r).x - b(i).x) ^ 2 + (r(r).y - b(i).y) ^ 2) < r(r).r THEN 'its a hit!
  199.                                     r(r).explodeFrame = 1 'linger with explosion
  200.                                     r(r).live = 0
  201.                                     hits = hits + 1
  202.                                     points = points + ((r(r).speed - 2) * 33.3333 + (50 - (r(r).c - 10)) * 2 + (90 - (r(r).r - 10)) * 1.1111) / 3
  203.                                     IF r(r).r > 30 THEN '       split rock  into ? new ones
  204.                                         maxBabyRocks = INT((r(r).r - 10) / 10)
  205.                                         maxBabyRocks = irnd&(2, maxBabyRocks) ' pick a number of baby Rocks
  206.                                         FOR br = 1 TO maxBabyRocks
  207.                                             '                        new rock
  208.                                             newRockN = freeRock& '                          get inactive rock number
  209.                                             newRock newRockN '                              new identity and activate
  210.                                             r(newRockN).r = (r(r).r - 10) / maxBabyRocks '  split in equal parts minus 20% mass
  211.                                             r(newRockN).x = r(r).x + irnd&(-30, 30) '       thrown from parent
  212.                                             r(newRockN).y = r(r).y + irnd&(-30, 30)
  213.                                             r(newRockN).c = r(r).c '                   same color as parent
  214.                                             r(newRockN).heading = rrnd(ship.a - .75 * pi, ship.a + .75 * pi)
  215.                                         NEXT
  216.                                     END IF ' big enough to split
  217.                                     b(i).live = 0 'kill bullet
  218.                                 END IF ' hit rock
  219.                             END IF 'rock is there
  220.                         NEXT ' rock
  221.                         IF b(i).live THEN fcirc b(i).x, b(i).y, 3, _RGB32(255, 255, 0) 'draws bullet
  222.                     ELSE
  223.                         b(i).live = 0 'out of bounds
  224.                     END IF ' bullet is in bounds
  225.                 END IF ' bullet live
  226.             NEXT ' bullet
  227.         END IF ' if ship still live
  228.         _DISPLAY
  229.         IF ship.live = 0 THEN SLEEP ELSE _LIMIT 60 ' if ship dies let's rest and regroup  before restart next life
  230.     WEND
  231.     lives = lives - 1
  232.     IF lives MOD 4 = 0 THEN rocks = rocks + 1
  233.     IF lives MOD 4 = 2 THEN alienN = alienN + 1
  234. ship.x = -200: ship.y = -200 'get it out of the way
  235. i = 0
  236. WHILE _KEYDOWN(ASC("q")) = 0
  237.     drawStars 0
  238.     i = i + 1
  239.     IF i MOD 30 = 29 AND rocks < nRocks THEN rocks = rocks + 1: r(rocks).live = 1
  240.     FOR r = 1 TO nRocks
  241.         IF r(r).live THEN drawRock r
  242.     NEXT
  243.     s$ = "Lives:" + STR$(lives) + "  Hits:" + STR$(hits) + "  Bullets:" + STR$(bullets) + "  Shooting:" + STR$(INT(hits * 100 / bullets)) + "%"
  244.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 - 20), s$
  245.     _FONT fnt2
  246.     s$ = STR$(points)
  247.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2), s$
  248.     _FONT fnt
  249.     s$ = "Press q to quit"
  250.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 + 100), s$
  251.     _DISPLAY
  252.     _LIMIT 60
  253.  
  254. SUB drawStars (moving)
  255.     TYPE starType
  256.         x AS SINGLE
  257.         y AS SINGLE
  258.         size AS SINGLE
  259.         c AS INTEGER
  260.     END TYPE
  261.     STATIC beenHere, stars(600) AS starType, cy AS LONG
  262.     DIM i AS LONG
  263.     IF beenHere = 0 THEN 'static part
  264.         FOR i = 0 TO 200
  265.             stars(i).x = RND * xmax: stars(i).y = RND * ymax: stars(i).size = 0
  266.             stars(i).c = irnd&(80, 140)
  267.         NEXT
  268.         FOR i = 0 TO 200
  269.             stars(i).x = RND * xmax: stars(i).y = RND * ymax: stars(i).size = .3
  270.             stars(i).c = irnd&(80, 140)
  271.         NEXT
  272.  
  273.         FOR i = 1 TO 140
  274.             stars(i + 400).x = RND * xmax: stars(i + 400).y = RND * ymax: stars(i + 100).size = .6
  275.             stars(i).c = irnd&(110, 170)
  276.         NEXT
  277.         FOR i = 1 TO 50
  278.             stars(i + 540).x = RND * xmax: stars(i + 540).y = RND * ymax: stars(i + 170).size = 1.2
  279.             stars(i).c = irnd&(140, 200)
  280.         NEXT
  281.         FOR i = 1 TO 10
  282.             stars(i + 590).x = RND * xmax: stars(i + 590).y = RND * ymax: stars(i + 195).size = 2.4
  283.             stars(i).c = irnd&(170, 235)
  284.         NEXT
  285.         cy = ymax / 2
  286.         beenHere = 1
  287.     END IF
  288.     FOR i = 0 TO cy
  289.         LINE (0, i)-(xmax, i), _RGB32(0, 0, .1 * i + 4)
  290.         LINE (0, ymax - i)-(xmax, ymax - i), _RGB(0, 0, .1 * i + 4)
  291.     NEXT
  292.     FOR i = 0 TO 200
  293.         IF moving THEN
  294.             stars(i).x = stars(i).x + .2 * stars(i).size ^ stars(i).size
  295.             IF stars(i).x > xmax THEN stars(i).x = -1 * RND * 20
  296.         END IF
  297.         fcirc stars(i).x, stars(i).y, stars(i).size, _RGB32(stars(i).c - 10, stars(i).c, stars(i).c + 10)
  298.     NEXT
  299.  
  300. SUB newAlien (i AS LONG)
  301.     DIM side AS LONG, heading
  302.     RANDOMIZE TIMER * RND 'to avoid making twins
  303.     side = irnd&(1, 4) 'bring rock in from one side, need to set heading according to side
  304.     aliens(i).fireX = irnd(10, xmax - 10)
  305.     aliens(i).fireY = irnd(10, ymax - 10)
  306.      aliens(i).attackFrame = irnd(30, 400)    ' EDIT a tweak to survive a little long before murdered with low lives
  307.     SELECT CASE side
  308.         CASE 1
  309.             aliens(i).x = -10
  310.             aliens(i).y = rrnd(20, ymax - 20)
  311.         CASE 2
  312.             aliens(i).x = xmax + 10
  313.             aliens(i).y = rrnd(20, ymax - 20)
  314.         CASE 3
  315.             aliens(i).x = rrnd(20, xmax - 20)
  316.             aliens(i).y = -10
  317.         CASE 4
  318.             aliens(i).x = rrnd(20, xmax - 20)
  319.             aliens(i).y = ymax + 10
  320.     END SELECT
  321.     heading = _ATAN2(aliens(i).fireY - aliens(i).y, aliens(i).fireX - aliens(i).x)
  322.     aliens(i).dx = 3.5 * COS(heading)
  323.     aliens(i).dy = 3.5 * SIN(heading)
  324.     aliens(i).live = 0
  325.     aliens(i).transform = 0
  326.     aliens(i).c = _RGB32(irnd(128, 255), irnd(0, 255), irnd(0, 255))
  327.  
  328. FUNCTION plasma~& (new AS LONG)
  329.     STATIC r, g, b, cnt, beenHere
  330.     IF beenHere = 0 OR new THEN
  331.         r = RND: g = RND: b = RND: beenHere = 1: cnt = 0
  332.     END IF
  333.     cnt = cnt + .2
  334.     plasma~& = _RGB32(127 + 127 * SIN(r * cnt), 127 + 127 * SIN(g * cnt), 127 + 127 * SIN(b * cnt))
  335.  
  336. SUB drawAliens (i AS LONG) 'shipType
  337.     DIM light AS LONG, heading, r AS LONG, g AS LONG, b AS LONG
  338.     IF aliens(i).live THEN
  339.         IF aliens(i).transform = 0 THEN
  340.             r = _RED32(aliens(i).c): g = _GREEN32(aliens(i).c): b = _BLUE32(aliens(i).c)
  341.             fellipse aliens(i).x, aliens(i).y, 6, 15, _RGB32(r, g - 120, b - 100)
  342.             fellipse aliens(i).x, aliens(i).y, 18, 11, _RGB32(r, g - 60, b - 50)
  343.             fellipse aliens(i).x, aliens(i).y, 30, 7, _RGB32(r, g, b)
  344.             FOR light = 1 TO 12
  345.                 fcirc aliens(i).x - 35 + 5 * light + aliens(i).ls, aliens(i).y, 1, _RGB32(aliens(i).ls * 50, aliens(i).ls * 50, aliens(i).ls * 50)
  346.             NEXT
  347.             aliens(i).ls = aliens(i).ls + 1
  348.             IF aliens(i).ls > 5 THEN aliens(i).ls = 0
  349.         ELSE
  350.             fcirc aliens(i).x, aliens(i).y, 30, aliens(i).c
  351.         END IF
  352.         'time to shoot?
  353.         aliens(i).x = aliens(i).x + aliens(i).dx
  354.         aliens(i).y = aliens(i).y + aliens(i).dy
  355.         IF SQR((aliens(i).fireX - aliens(i).x) ^ 2 + (aliens(i).fireY - aliens(i).y) ^ 2) < 5 THEN 'transform into the bolder of death
  356.             aliens(i).transform = 1
  357.             heading = _ATAN2(ship.y - aliens(i).y, ship.x - aliens(i).x)
  358.             aliens(i).dx = 10 * COS(heading)
  359.             aliens(i).dy = 10 * SIN(heading)
  360.         END IF
  361.         IF aliens(i).x < -10 OR aliens(i).x > xmax + 10 THEN
  362.             IF aliens(i).y < -10 OR aliens(i).y > ymax + 10 THEN '  out of bounds goodbye bolder of death!
  363.                 aliens(i).live = 0 'man we dodged a bullet here!!!!
  364.                 newAlien i 'reset the trap
  365.             END IF
  366.         END IF
  367.     ELSE
  368.         IF aliens(i).attackFrame THEN
  369.             aliens(i).attackFrame = aliens(i).attackFrame - 1
  370.             IF aliens(i).attackFrame = 0 THEN
  371.                 aliens(i).live = 1
  372.             END IF
  373.         END IF
  374.     END IF
  375.  
  376. FUNCTION freeRock&
  377.     DIM i AS LONG
  378.     FOR i = rocks + 1 TO nRocks ' look for inactive rock number
  379.         IF r(i).live = 0 AND r(i).explodeFrame = 0 THEN freeRock& = i: EXIT FUNCTION
  380.     NEXT
  381.  
  382. SUB explode (x AS LONG, y AS LONG, r AS LONG, frm AS LONG)
  383.     DIM maxParticles AS LONG, i AS LONG, rounds AS LONG, loopCount AS LONG
  384.     maxParticles = r * 4
  385.     FOR i = 1 TO r
  386.         NewDot i, x, y, r
  387.     NEXT
  388.     rounds = r
  389.     FOR loopCount = 0 TO frm
  390.         IF _KEYDOWN(27) THEN END
  391.         FOR i = 1 TO rounds
  392.             dots(i).x = dots(i).x + dots(i).dx
  393.             dots(i).y = dots(i).y + dots(i).dy
  394.             fcirc dots(i).x, dots(i).y, dots(i).size, dots(i).kolor
  395.         NEXT
  396.         IF rounds < maxParticles THEN
  397.             FOR i = 1 TO r
  398.                 NewDot (rounds + i), x, y, r
  399.             NEXT
  400.             rounds = rounds + r
  401.         END IF
  402.     NEXT
  403.  
  404. SUB NewDot (i AS LONG, x AS LONG, y AS LONG, r AS LONG)
  405.     DIM angle, rd
  406.     angle = pi * 2 * RND
  407.     rd = RND * 30
  408.     dots(i).x = x + rd * COS(angle)
  409.     dots(i).y = y + rd * SIN(angle)
  410.     dots(i).size = RND * r * .05
  411.     rd = RND 'STxAxTIC recommended for rounder spreads
  412.     dots(i).dx = rd * 10 * (10 - 2 * dots(i).size) * COS(angle)
  413.     dots(i).dy = rd * 10 * (10 - 2 * dots(i).size) * SIN(angle)
  414.     rd = 20 + RND * 70
  415.     dots(i).kolor = _RGBA32(rd, rd, rd, 80)
  416.  
  417. SUB drawship 'simple red iso triangle pointed towards radianAngle
  418.     DIM x1 AS LONG, y1 AS LONG, x2 AS LONG, y2 AS LONG, x3 AS LONG, y3 AS LONG
  419.     'calculate 3 tail points of triangle ship
  420.     x1 = ship.x + 40 * COS(ship.a - pi) '   middle
  421.     y1 = ship.y + 40 * SIN(ship.a - pi) '
  422.     x2 = ship.x + 60 * COS(ship.a + .9 * pi) ' wing
  423.     y2 = ship.y + 60 * SIN(ship.a + .9 * pi)
  424.     x3 = ship.x + 60 * COS(ship.a - .9 * pi) ' other wing
  425.     y3 = ship.y + 60 * SIN(ship.a - .9 * pi)
  426.     ftri ship.x, ship.y, x1, y1, x2, y2, _RGB32(80, 120, 80, 80)
  427.     ftri ship.x, ship.y, x1, y1, x3, y3, _RGB32(60, 100, 60, 80)
  428.     LINE (ship.x, ship.y)-(x1, y1), _RGB32(255, 255, 128)
  429.     LINE (ship.x, ship.y)-(x2, y2), _RGB32(180, 180, 120)
  430.     LINE (ship.x, ship.y)-(x3, y3), _RGB32(180, 180, 120)
  431.  
  432. SUB drawRock (iRock)
  433.     RANDOMIZE USING r(iRock).seed 'this prevents having to save a particular sequence of random number
  434.     DIM dx, dy, rad AS LONG, j AS LONG, rRad AS SINGLE, leg AS SINGLE, x0 AS LONG, y0 AS LONG, rc AS LONG, c~&, x1 AS LONG, y1 AS LONG, xoff, yoff, i AS LONG
  435.     DIM x2 AS LONG, y2 AS LONG
  436.     dx = r(iRock).speed * COS(r(iRock).heading)
  437.     dy = r(iRock).speed * SIN(r(iRock).heading) 'update location
  438.     r(iRock).ra = r(iRock).ra + r(iRock).spin
  439.     IF r(iRock).x + dx + r(iRock).r < 0 OR r(iRock).x + dx - r(iRock).r > xmax OR r(iRock).y + dy + r(iRock).r < 0 OR r(iRock).y + dy - r(iRock).r > ymax THEN
  440.         IF iRock <= rocks THEN newRock iRock ELSE r(iRock).live = 0
  441.         EXIT SUB ' reassigned get out of here
  442.     ELSE
  443.         r(iRock).x = r(iRock).x + dx
  444.         r(iRock).y = r(iRock).y + dy
  445.     END IF
  446.     IF ((r(iRock).x - ship.x) ^ 2 + (r(iRock).y - ship.y) ^ 2) ^ .5 < r(iRock).r + 30 THEN 'rock collides with ship?
  447.         FOR rad = 1 TO 200
  448.             fcirc ship.x, ship.y, rad, _RGB32(255 - rad, 255 - 2 * rad, 0)
  449.             _DISPLAY
  450.             _LIMIT 300
  451.         NEXT
  452.         ship.live = 0
  453.         IF iRock <= rocks THEN newRock iRock ELSE r(iRock).live = 0
  454.         EXIT SUB
  455.     END IF
  456.     FOR j = 10 TO 3 STEP -1 '                  rock drawing (see demo program where developed code)
  457.         rRad = .1 * j * r(iRock).r
  458.         leg = rRad * (RND * .7 + .3)
  459.         x0 = r(iRock).x + leg * COS(r(iRock).ra)
  460.         y0 = r(iRock).y + leg * SIN(r(iRock).ra)
  461.         rc = r(iRock).c + 30 * RND - 15
  462.         c~& = _RGB32(rc + 5, rc - 10, rc + 5)
  463.         x1 = x0
  464.         y1 = y0
  465.         xoff = RND * 20 - 10 + r(iRock).x
  466.         yoff = RND * 20 - 10 + r(iRock).y
  467.         FOR i = 1 TO 12
  468.             leg = rRad * (RND * .35 + .65)
  469.             IF i = 12 THEN
  470.                 x2 = x0: y2 = y0
  471.             ELSE
  472.                 x2 = xoff + leg * COS(i * polyAngle + r(iRock).ra)
  473.                 y2 = yoff + leg * SIN(i * polyAngle + r(iRock).ra)
  474.             END IF
  475.             ftri r(iRock).x, r(iRock).y, x1, y1, x2, y2, c~&
  476.             x1 = x2: y1 = y2
  477.         NEXT
  478.     NEXT
  479.  
  480. SUB newRock (iRock)
  481.     DIM side AS LONG
  482.     RANDOMIZE TIMER * RND 'to avoid making twins
  483.     side = irnd&(1, 4) 'bring rock in from one side, need to set heading according to side
  484.     SELECT CASE side
  485.         CASE 1
  486.             r(iRock).x = -10
  487.             r(iRock).y = rrnd(20, ymax - 20)
  488.             r(iRock).heading = 3 * pi / 2 + RND * pi
  489.         CASE 2
  490.             r(iRock).x = xmax + 10
  491.             r(iRock).y = rrnd(20, ymax - 20)
  492.             r(iRock).heading = pi / 2 + RND * pi
  493.         CASE 3
  494.             r(iRock).x = rrnd(20, xmax - 20)
  495.             r(iRock).y = -10
  496.             r(iRock).heading = RND * pi
  497.         CASE 4
  498.             r(iRock).x = rrnd(20, xmax - 20)
  499.             r(iRock).y = ymax + 10
  500.             r(iRock).heading = pi + RND * pi
  501.     END SELECT
  502.     r(iRock).speed = rrnd(2, 5) 'speed, rotation angle, radius, gray coloring, spin, seed, hit for explosion
  503.     r(iRock).ra = RND * 2 * pi
  504.     r(iRock).r = irnd&(30, 100)
  505.     r(iRock).c = irnd&(10, 60)
  506.     r(iRock).spin = rrnd(-pi / 20, pi / 20)
  507.     r(iRock).seed = INT(RND * 64000) - 32000
  508.     r(iRock).explodeFrame = 0
  509.     r(iRock).live = 1
  510.  
  511. FUNCTION irnd& (n1, n2) 'return an integer between 2 numbers
  512.     DIM l%, h%
  513.     IF n1 > n2 THEN l% = n2: h% = n1 ELSE l% = n1: h% = n2
  514.     irnd& = INT(RND * (h% - l% + 1)) + l%
  515.  
  516. FUNCTION rrnd (n1, n2) ' return number (expecting reals =_single, double, _float depending on default / define setup)
  517.     rrnd = (n2 - n1) * RND + n1
  518.  
  519. SUB fellipse (CX AS LONG, CY AS LONG, xr AS LONG, yr AS LONG, C AS _UNSIGNED LONG)
  520.     IF xr = 0 OR yr = 0 THEN EXIT SUB
  521.     DIM x AS LONG, y AS LONG
  522.     w2 = xr * xr: h2 = yr * yr: h2w2 = h2 * w2
  523.     LINE (CX - xr, CY)-(CX + xr, CY), C, BF
  524.     DO WHILE y < yr
  525.         y = y + 1
  526.         x = SQR((h2w2 - y * y * w2) \ h2)
  527.         LINE (CX - x, CY + y)-(CX + x, CY + y), C, BF
  528.         LINE (CX - x, CY - y)-(CX + x, CY - y), C, BF
  529.     LOOP
  530.  
  531. SUB ftri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  532.     DIM D AS LONG
  533.     STATIC a&
  534.     D = _DEST
  535.     IF a& = 0 THEN a& = _NEWIMAGE(1, 1, 32)
  536.     _DEST a&
  537.     _DONTBLEND a& '  '<<<< new 2019-12-16 fix
  538.     PSET (0, 0), K
  539.     _BLEND a& '<<<< new 2019-12-16 fix
  540.     _DEST D
  541.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  542.  
  543. SUB fcirc (x AS LONG, y AS LONG, R AS LONG, C AS _UNSIGNED LONG) 'vince version
  544.     DIM x0 AS LONG, y0 AS LONG, e AS LONG
  545.     x0 = R: y0 = 0: e = 0
  546.     DO WHILE y0 < x0
  547.         IF e <= 0 THEN
  548.             y0 = y0 + 1
  549.             LINE (x - x0, y + y0)-(x + x0, y + y0), C, BF
  550.             LINE (x - x0, y - y0)-(x + x0, y - y0), C, BF
  551.             e = e + 2 * y0
  552.         ELSE
  553.             LINE (x - y0, y - x0)-(x + y0, y - x0), C, BF
  554.             LINE (x - y0, y + x0)-(x + y0, y + x0), C, BF
  555.             x0 = x0 - 1: e = e - 2 * x0
  556.         END IF
  557.     LOOP
  558.     LINE (x - R, y)-(x + R, y), C, BF
  559.  

You just need the font from the asset file now,
« Last Edit: November 01, 2020, 05:57:49 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: b+ Asteroids makeover
« Reply #31 on: November 01, 2020, 05:53:18 pm »
LOL Great job!!!! I'll put this in my Games folder on my computer. :) Thanks for making it.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: b+ Asteroids makeover
« Reply #32 on: November 01, 2020, 05:59:45 pm »
LOL Great job!!!! I'll put this in my Games folder on my computer. :) Thanks for making it.

A little tweak to live longer:
Code: QB64: [Select]
  1. aliens(i).attackFrame = irnd(30, 400)    ' EDIT a tweak to survive a little long before getting murdered with low lives over and over...

Already edited in code above.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: b+ Asteroids makeover
« Reply #33 on: November 01, 2020, 07:45:21 pm »
Thanks.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: b+ Asteroids makeover
« Reply #34 on: November 01, 2020, 09:04:03 pm »
M6 Play again option, continuous shoot (save the spacebar!), save High Score:
Code: QB64: [Select]
  1. _TITLE "b+ Asteroids m6 Play Again" 'started 2018-07-13"
  2. ' 2020-10-27 remove the alternate subs and get down below 200 LOC almost there now! new shooter action font and background
  3. ' 2020-10-28 another makeover explosions and split asteroids
  4. ' 2020-10-29 fix baby rock management, break between lives
  5. ' 2020-10-29 fix left/right gun, fix explosions over many frames to eliminate pause in action, speed up 60 fps
  6. ' 2020-10-30 m3 SierraKen's idea to angle shooter with mousewheel also finish WASD options, more rocks, points system
  7. ' points:
  8. ' The higher the speed the better    speed range 2 to 5, diff = 3 * 33.3333 = 100          s - 2 * 33.3333
  9. ' The lower the color the better   color range 10 to 60, diff =      50 * 2 = 100  50 - (c - 10) * 2
  10. ' The small        er the size the better  size range 10 to 100, diff = 90 * 1.1111 = 100  90 - (sz -10) * 1.1111
  11. '        ((speed - 2) * 33.3333 + (50 - (c -10)) * 2 + (90 - (r - 10)) * 1.1111) / 3 = 100 best score per hit
  12. ' 2020-10-30 increase level of difficulty, fix double lives lost, add an ending after all lives spent.
  13. ' 2020-10-31 M4 They are Here - the aliens have accepted my invitaion for war games don't get caught in their beam.
  14. ' rework ending and variable LONG suffix. Aliens on the attack 100 points before or after transformed into the Bolder of Death.
  15. ' 2020-11-01 M5 FX Moving through space, Oh yeah, more aliens!
  16. ' 2020-11-01 M6 add play again and save high game , continuous shoot
  17.  
  18. '================================================================================================================
  19.  
  20. '    NOTE: !!!!!!!!!!!!!!!   When there is a pause in action, just hit any key to reset next life.
  21.  
  22. '================================================================================================================
  23.  
  24. CONST xmax = 1200, ymax = 700, pi = _PI, polyAngle = _PI / 6, nRocks = 300, nBullets = 2000, bSpeed = 15
  25.  
  26. TYPE alienType
  27.     x AS SINGLE
  28.     y AS SINGLE
  29.     dx AS SINGLE
  30.     dy AS SINGLE
  31.     ls AS LONG ' lights offset
  32.     c AS _UNSIGNED LONG ' color
  33.     live AS LONG
  34.     attackFrame AS LONG
  35.     fireX AS LONG
  36.     fireY AS LONG
  37.     transform AS LONG
  38.  
  39. TYPE particle
  40.     x AS LONG
  41.     y AS LONG
  42.     dx AS SINGLE
  43.     dy AS SINGLE
  44.     size AS SINGLE
  45.     kolor AS _UNSIGNED LONG
  46.  
  47. TYPE bullet
  48.     x AS LONG
  49.     y AS LONG
  50.     dx AS SINGLE
  51.     dy AS SINGLE
  52.     live AS LONG
  53.  
  54. TYPE shipType
  55.     x AS LONG
  56.     y AS LONG
  57.     live AS LONG
  58.     a AS SINGLE '   rotated position usu gun left or right (mouse button), maybe up press w or down press z
  59.  
  60. TYPE rock
  61.     x AS LONG
  62.     y AS LONG
  63.     r AS LONG '            radius
  64.     ra AS SINGLE '         rotation position   a = a + spin
  65.     heading AS SINGLE '    heading from which dx, dy are calc with speed
  66.     speed AS SINGLE '      speed
  67.     spin AS SINGLE '       rotation direction and amount
  68.     seed AS LONG '         for drawing rocks with RND USING
  69.     c AS LONG '            color   rgb(c, c, c)
  70.     live AS LONG '         need this to track rocks still active like bullets
  71.     explodeFrame AS LONG ' after a rock is hit by bullet, it explodes and in more than one frame
  72.  
  73. REDIM SHARED aliens(1 TO 5) AS alienType
  74. DIM SHARED dots(2000) AS particle
  75. DIM SHARED b(nBullets) AS bullet
  76. DIM SHARED ship AS shipType
  77. DIM SHARED r(nRocks) AS rock
  78. DIM SHARED points AS LONG
  79. DIM SHARED rocks AS LONG 'rocks is the minimum number of parent rocks to have on screen  automatic replace when hit or out of bounds
  80.  
  81. DIM HS AS LONG, fnt AS LONG, fnt2 AS LONG ' file LOAD handles
  82. DIM i AS LONG, bullets AS LONG, fire AS LONG ' index and bullets
  83. DIM r AS LONG, newRockN AS LONG, maxBabyRocks AS LONG, br AS LONG, hits AS LONG ' rock stuff
  84. DIM ai AS LONG, alienN AS LONG ' alien index and number
  85. DIM hs$, s$, t, lastt ' general string and times
  86.  
  87. SCREEN _NEWIMAGE(xmax, ymax, 32)
  88. _SCREENMOVE 100, 20
  89.  
  90. fnt = _LOADFONT("ARLRDBD.ttf", 16, "MONOSPACE")
  91. fnt2 = _LOADFONT("ARLRDBD.ttf", 40, "MONOSPACE")
  92. _FONT fnt
  93. COLOR &HFF00FFFF, &H00000000
  94.  
  95. restart:
  96. IF _FILEEXISTS("Asteroids High Score.txt") THEN
  97.     OPEN "Asteroids High Score.txt" FOR INPUT AS #1
  98.     INPUT #1, HS
  99.     CLOSE #1
  100. hs$ = "  High Score:" + STR$(HS)
  101. lives = 10: alienN = 1: rocks = 4: ' always active rocks
  102. points = 0: hits = 0: bullets = 0
  103. WHILE lives > 0 AND _KEYDOWN(27) = 0 ' init start restart
  104.     REDIM aliens(1 TO alienN) AS alienType
  105.     FOR ai = 1 TO alienN
  106.         newAlien ai
  107.     NEXT
  108.     FOR i = 1 TO nRocks 'reset rocks mainly clear baby rocks
  109.         newRock (i)
  110.         IF i > rocks THEN r(i).live = 0
  111.     NEXT
  112.     ship.x = xmax / 2 'avoids explosions top left corner at start, dang still get some!
  113.     ship.y = ymax / 2
  114.     ship.live = 1
  115.     WHILE ship.live AND _KEYDOWN(27) = 0
  116.         'draw everything then process bullets
  117.         drawStars 1
  118.         '   CIRCLE (aliens.fireX, aliens.fireY), 10, &HFFFFFFFF   transformtion poimt Bolder of Death
  119.         s$ = "Lives:" + STR$(lives) + "  Hits:" + STR$(hits) + "  Bullets:" + STR$(bullets) + "  Shooting:" + STR$(INT(hits * 100 / bullets)) + "%"
  120.         _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 - 20), s$
  121.         _FONT fnt2
  122.         s$ = STR$(points) + hs$
  123.         _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2), s$
  124.         _FONT fnt
  125.         FOR ai = 1 TO alienN
  126.             drawAliens ai
  127.         NEXT
  128.  
  129.         FOR i = 1 TO nRocks
  130.             IF r(i).live THEN drawRock i ' while drawing rocks the ship could be blown up
  131.         NEXT
  132.         FOR i = 1 TO nRocks 'smoke up the place with rock debris fields still flying out from hit frames ago
  133.             IF r(i).explodeFrame THEN
  134.                 r(i).explodeFrame = r(i).explodeFrame + 1
  135.                 IF r(i).explodeFrame > .5 * r(i).r THEN
  136.                     r(i).explodeFrame = 0
  137.                     IF i <= rocks THEN newRock i ' now replace the rock
  138.                 ELSE
  139.                     explode r(i).x, r(i).y, r(i).r, r(i).explodeFrame
  140.                 END IF
  141.             END IF
  142.         NEXT
  143.         IF ship.live THEN
  144.             FOR ai = 1 TO alienN
  145.                 IF SQR((aliens(ai).x - ship.x) ^ 2 + (aliens(ai).y - ship.y) ^ 2) < 60 THEN 'aliens and ship collisde boom boom
  146.                     FOR br = 1 TO 200
  147.                         fcirc ship.x, ship.y, br, _RGB32(255 - br, 255 - 2 * br, 0)
  148.                         _DISPLAY
  149.                         _LIMIT 300
  150.                     NEXT
  151.                     ship.live = 0
  152.                     _CONTINUE
  153.                 ELSE
  154.                     drawship
  155.                 END IF
  156.             NEXT
  157.             WHILE _MOUSEINPUT
  158.                 ship.a = ship.a + _MOUSEWHEEL * pi / 8 ' 22.5  degree changes, Thank Ken for this :)
  159.             WEND 'update ship
  160.             ship.x = _MOUSEX: ship.y = _MOUSEY
  161.             IF _MOUSEBUTTON(1) THEN ship.a = pi 'this is new left and right guns
  162.             IF _MOUSEBUTTON(2) THEN ship.a = 0
  163.             IF _KEYDOWN(ASC("w")) THEN ship.a = 1.5 * pi ' well it works but ??
  164.             IF _KEYDOWN(ASC("a")) THEN ship.a = pi
  165.             IF _KEYDOWN(ASC("s")) THEN ship.a = .5 * pi
  166.             IF _KEYDOWN(ASC("d")) THEN ship.a = 0
  167.             fire = 0
  168.             'IF _KEYDOWN(32) THEN 'fire bullets
  169.             t = TIMER(.01)
  170.             IF lastt = 0 OR t - lastt > .2 THEN fire = 1: lastt = t
  171.             'END IF
  172.             FOR i = 0 TO nBullets 'handle bullets
  173.                 IF b(i).live = 0 AND fire = 1 THEN 'have inactive bullet to use
  174.                     b(i).x = ship.x + bSpeed * COS(ship.a)
  175.                     b(i).y = ship.y + bSpeed * SIN(ship.a)
  176.                     b(i).dx = bSpeed * COS(ship.a)
  177.                     b(i).dy = bSpeed * SIN(ship.a)
  178.                     b(i).live = -1
  179.                     bullets = bullets + 1
  180.                     fire = 0
  181.                 END IF
  182.                 IF b(i).live THEN 'new location
  183.                     b(i).x = b(i).x + b(i).dx
  184.                     b(i).y = b(i).y + b(i).dy
  185.                     IF b(i).x > 0 AND b(i).x < xmax AND b(i).y > 0 AND b(i).y < ymax THEN 'in bounds draw it
  186.  
  187.                         'bullet hit aliens?
  188.                         FOR ai = 1 TO alienN
  189.                             IF SQR((aliens(ai).x - b(i).x) ^ 2 + (aliens(ai).y - b(i).y) ^ 2) < 30 THEN
  190.                                 FOR br = 1 TO 120
  191.                                     CIRCLE (aliens(ai).x, aliens(ai).y), br / 3, plasma~&(0)
  192.                                 NEXT
  193.                                 _DISPLAY
  194.                                 _DELAY .05
  195.                                 aliens(ai).live = 0
  196.                                 newAlien ai
  197.                                 points = points + 100
  198.                                 b(i).live = 0
  199.                                 _CONTINUE
  200.                             END IF
  201.                         NEXT
  202.                         FOR r = 1 TO nRocks 'check for collision with rock
  203.                             IF r(r).live THEN
  204.                                 IF SQR((r(r).x - b(i).x) ^ 2 + (r(r).y - b(i).y) ^ 2) < r(r).r THEN 'its a hit!
  205.                                     r(r).explodeFrame = 1 'linger with explosion
  206.                                     r(r).live = 0
  207.                                     hits = hits + 1
  208.                                     points = points + ((r(r).speed - 2) * 33.3333 + (50 - (r(r).c - 10)) * 2 + (90 - (r(r).r - 10)) * 1.1111) / 3
  209.                                     IF r(r).r > 30 THEN '       split rock  into ? new ones
  210.                                         maxBabyRocks = INT((r(r).r - 10) / 10)
  211.                                         maxBabyRocks = irnd&(2, maxBabyRocks) ' pick a number of baby Rocks
  212.                                         FOR br = 1 TO maxBabyRocks
  213.                                             '                        new rock
  214.                                             newRockN = freeRock& '                          get inactive rock number
  215.                                             newRock newRockN '                              new identity and activate
  216.                                             r(newRockN).r = (r(r).r - 10) / maxBabyRocks '  split in equal parts minus 20% mass
  217.                                             r(newRockN).x = r(r).x + irnd&(-30, 30) '       thrown from parent
  218.                                             r(newRockN).y = r(r).y + irnd&(-30, 30)
  219.                                             r(newRockN).c = r(r).c '                   same color as parent
  220.                                             r(newRockN).heading = rrnd(ship.a - .75 * pi, ship.a + .75 * pi)
  221.                                         NEXT
  222.                                     END IF ' big enough to split
  223.                                     b(i).live = 0 'kill bullet
  224.                                 END IF ' hit rock
  225.                             END IF 'rock is there
  226.                         NEXT ' rock
  227.                         IF b(i).live THEN fcirc b(i).x, b(i).y, 3, _RGB32(255, 255, 0) 'draws bullet
  228.                     ELSE
  229.                         b(i).live = 0 'out of bounds
  230.                     END IF ' bullet is in bounds
  231.                 END IF ' bullet live
  232.             NEXT ' bullet
  233.         END IF ' if ship still live
  234.         _DISPLAY
  235.         IF ship.live = 0 THEN SLEEP ELSE _LIMIT 60 ' if ship dies let's rest and regroup  before restart next life
  236.     WEND
  237.     lives = lives - 1
  238.     IF lives MOD 4 = 0 THEN rocks = rocks + 1
  239.     IF lives MOD 4 = 2 THEN alienN = alienN + 1
  240. IF points > HS THEN
  241.     OPEN "Asteroids High Score.txt" FOR OUTPUT AS #1
  242.     PRINT #1, points
  243.     CLOSE #1
  244. ship.x = -200: ship.y = -200 'get it out of the way
  245. i = 0
  246. DIM k$
  247. WHILE _KEYDOWN(ASC("q")) = 0
  248.     drawStars 0
  249.     i = i + 1
  250.     IF i MOD 30 = 29 AND rocks < nRocks THEN rocks = rocks + 1: r(rocks).live = 1
  251.     FOR r = 1 TO nRocks
  252.         IF r(r).live THEN drawRock r
  253.     NEXT
  254.     s$ = "Lives:" + STR$(lives) + "  Hits:" + STR$(hits) + "  Bullets:" + STR$(bullets) + "  Shooting:" + STR$(INT(hits * 100 / bullets)) + "%"
  255.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 - 20), s$
  256.     _FONT fnt2
  257.     s$ = STR$(points)
  258.     IF points > HS THEN s$ = s$ + " a New Record!" ELSE s$ = STR$(points) + hs$
  259.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2), s$
  260.     _FONT fnt
  261.     s$ = "Press q to quit, p or a to Play Again..."
  262.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 + 100), s$
  263.     IF _KEYDOWN(ASC("a")) OR _KEYDOWN(ASC("p")) THEN GOTO restart
  264.     _DISPLAY
  265.     _LIMIT 60
  266.  
  267. SUB drawStars (moving)
  268.     TYPE starType
  269.         x AS SINGLE
  270.         y AS SINGLE
  271.         size AS SINGLE
  272.         c AS INTEGER
  273.     END TYPE
  274.     STATIC beenHere, stars(600) AS starType, cy AS LONG
  275.     DIM i AS LONG
  276.     IF beenHere = 0 THEN 'static part
  277.         FOR i = 0 TO 200
  278.             stars(i).x = RND * xmax: stars(i).y = RND * ymax: stars(i).size = 0
  279.             stars(i).c = irnd&(80, 140)
  280.         NEXT
  281.         FOR i = 0 TO 200
  282.             stars(i).x = RND * xmax: stars(i).y = RND * ymax: stars(i).size = .3
  283.             stars(i).c = irnd&(80, 140)
  284.         NEXT
  285.  
  286.         FOR i = 1 TO 140
  287.             stars(i + 400).x = RND * xmax: stars(i + 400).y = RND * ymax: stars(i + 100).size = .6
  288.             stars(i).c = irnd&(110, 170)
  289.         NEXT
  290.         FOR i = 1 TO 50
  291.             stars(i + 540).x = RND * xmax: stars(i + 540).y = RND * ymax: stars(i + 170).size = 1.2
  292.             stars(i).c = irnd&(140, 200)
  293.         NEXT
  294.         FOR i = 1 TO 10
  295.             stars(i + 590).x = RND * xmax: stars(i + 590).y = RND * ymax: stars(i + 195).size = 2.4
  296.             stars(i).c = irnd&(170, 235)
  297.         NEXT
  298.         cy = ymax / 2
  299.         beenHere = 1
  300.     END IF
  301.     FOR i = 0 TO cy
  302.         LINE (0, i)-(xmax, i), _RGB32(0, 0, .1 * i + 4)
  303.         LINE (0, ymax - i)-(xmax, ymax - i), _RGB(0, 0, .1 * i + 4)
  304.     NEXT
  305.     FOR i = 0 TO 200
  306.         IF moving THEN
  307.             stars(i).x = stars(i).x + .2 * stars(i).size ^ stars(i).size
  308.             IF stars(i).x > xmax THEN stars(i).x = -1 * RND * 20
  309.         END IF
  310.         fcirc stars(i).x, stars(i).y, stars(i).size, _RGB32(stars(i).c - 10, stars(i).c, stars(i).c + 10)
  311.     NEXT
  312.  
  313. SUB newAlien (i AS LONG)
  314.     DIM side AS LONG, heading
  315.     RANDOMIZE TIMER * RND 'to avoid making twins
  316.     side = irnd&(1, 4) 'bring rock in from one side, need to set heading according to side
  317.     aliens(i).fireX = irnd(10, xmax - 10)
  318.     aliens(i).fireY = irnd(10, ymax - 10)
  319.     aliens(i).attackFrame = irnd(30, 400) ' EDIT a tweak to survive a little long before getting murdered with low lives over and over...
  320.     SELECT CASE side
  321.         CASE 1
  322.             aliens(i).x = -10
  323.             aliens(i).y = rrnd(20, ymax - 20)
  324.         CASE 2
  325.             aliens(i).x = xmax + 10
  326.             aliens(i).y = rrnd(20, ymax - 20)
  327.         CASE 3
  328.             aliens(i).x = rrnd(20, xmax - 20)
  329.             aliens(i).y = -10
  330.         CASE 4
  331.             aliens(i).x = rrnd(20, xmax - 20)
  332.             aliens(i).y = ymax + 10
  333.     END SELECT
  334.     heading = _ATAN2(aliens(i).fireY - aliens(i).y, aliens(i).fireX - aliens(i).x)
  335.     aliens(i).dx = 3.5 * COS(heading)
  336.     aliens(i).dy = 3.5 * SIN(heading)
  337.     aliens(i).live = 0
  338.     aliens(i).transform = 0
  339.     aliens(i).c = _RGB32(irnd(128, 255), irnd(0, 255), irnd(0, 255))
  340.  
  341. FUNCTION plasma~& (new AS LONG)
  342.     STATIC r, g, b, cnt, beenHere
  343.     IF beenHere = 0 OR new THEN
  344.         r = RND: g = RND: b = RND: beenHere = 1: cnt = 0
  345.     END IF
  346.     cnt = cnt + .2
  347.     plasma~& = _RGB32(127 + 127 * SIN(r * cnt), 127 + 127 * SIN(g * cnt), 127 + 127 * SIN(b * cnt))
  348.  
  349. SUB drawAliens (i AS LONG) 'shipType
  350.     DIM light AS LONG, heading, r AS LONG, g AS LONG, b AS LONG
  351.     IF aliens(i).live THEN
  352.         IF aliens(i).transform = 0 THEN
  353.             r = _RED32(aliens(i).c): g = _GREEN32(aliens(i).c): b = _BLUE32(aliens(i).c)
  354.             fellipse aliens(i).x, aliens(i).y, 6, 15, _RGB32(r, g - 120, b - 100)
  355.             fellipse aliens(i).x, aliens(i).y, 18, 11, _RGB32(r, g - 60, b - 50)
  356.             fellipse aliens(i).x, aliens(i).y, 30, 7, _RGB32(r, g, b)
  357.             FOR light = 1 TO 12
  358.                 fcirc aliens(i).x - 35 + 5 * light + aliens(i).ls, aliens(i).y, 1, _RGB32(aliens(i).ls * 50, aliens(i).ls * 50, aliens(i).ls * 50)
  359.             NEXT
  360.             aliens(i).ls = aliens(i).ls + 1
  361.             IF aliens(i).ls > 5 THEN aliens(i).ls = 0
  362.         ELSE
  363.             fcirc aliens(i).x, aliens(i).y, 30, aliens(i).c
  364.         END IF
  365.         'time to shoot?
  366.         aliens(i).x = aliens(i).x + aliens(i).dx
  367.         aliens(i).y = aliens(i).y + aliens(i).dy
  368.         IF SQR((aliens(i).fireX - aliens(i).x) ^ 2 + (aliens(i).fireY - aliens(i).y) ^ 2) < 5 THEN 'transform into the bolder of death
  369.             aliens(i).transform = 1
  370.             heading = _ATAN2(ship.y - aliens(i).y, ship.x - aliens(i).x)
  371.             aliens(i).dx = 10 * COS(heading)
  372.             aliens(i).dy = 10 * SIN(heading)
  373.         END IF
  374.         IF aliens(i).x < -10 OR aliens(i).x > xmax + 10 THEN
  375.             IF aliens(i).y < -10 OR aliens(i).y > ymax + 10 THEN '  out of bounds goodbye bolder of death!
  376.                 aliens(i).live = 0 'man we dodged a bullet here!!!!
  377.                 newAlien i 'reset the trap
  378.             END IF
  379.         END IF
  380.     ELSE
  381.         IF aliens(i).attackFrame THEN
  382.             aliens(i).attackFrame = aliens(i).attackFrame - 1
  383.             IF aliens(i).attackFrame = 0 THEN
  384.                 aliens(i).live = 1
  385.             END IF
  386.         END IF
  387.     END IF
  388.  
  389. FUNCTION freeRock&
  390.     DIM i AS LONG
  391.     FOR i = rocks + 1 TO nRocks ' look for inactive rock number
  392.         IF r(i).live = 0 AND r(i).explodeFrame = 0 THEN freeRock& = i: EXIT FUNCTION
  393.     NEXT
  394.  
  395. SUB explode (x AS LONG, y AS LONG, r AS LONG, frm AS LONG)
  396.     DIM maxParticles AS LONG, i AS LONG, rounds AS LONG, loopCount AS LONG
  397.     maxParticles = r * 4
  398.     FOR i = 1 TO r
  399.         NewDot i, x, y, r
  400.     NEXT
  401.     rounds = r
  402.     FOR loopCount = 0 TO frm
  403.         IF _KEYDOWN(27) THEN END
  404.         FOR i = 1 TO rounds
  405.             dots(i).x = dots(i).x + dots(i).dx
  406.             dots(i).y = dots(i).y + dots(i).dy
  407.             fcirc dots(i).x, dots(i).y, dots(i).size, dots(i).kolor
  408.         NEXT
  409.         IF rounds < maxParticles THEN
  410.             FOR i = 1 TO r
  411.                 NewDot (rounds + i), x, y, r
  412.             NEXT
  413.             rounds = rounds + r
  414.         END IF
  415.     NEXT
  416.  
  417. SUB NewDot (i AS LONG, x AS LONG, y AS LONG, r AS LONG)
  418.     DIM angle, rd
  419.     angle = pi * 2 * RND
  420.     rd = RND * 30
  421.     dots(i).x = x + rd * COS(angle)
  422.     dots(i).y = y + rd * SIN(angle)
  423.     dots(i).size = RND * r * .05
  424.     rd = RND 'STxAxTIC recommended for rounder spreads
  425.     dots(i).dx = rd * 10 * (10 - 2 * dots(i).size) * COS(angle)
  426.     dots(i).dy = rd * 10 * (10 - 2 * dots(i).size) * SIN(angle)
  427.     rd = 20 + RND * 70
  428.     dots(i).kolor = _RGBA32(rd, rd, rd, 80)
  429.  
  430. SUB drawship 'simple red iso triangle pointed towards radianAngle
  431.     DIM x1 AS LONG, y1 AS LONG, x2 AS LONG, y2 AS LONG, x3 AS LONG, y3 AS LONG
  432.     'calculate 3 tail points of triangle ship
  433.     x1 = ship.x + 40 * COS(ship.a - pi) '   middle
  434.     y1 = ship.y + 40 * SIN(ship.a - pi) '
  435.     x2 = ship.x + 60 * COS(ship.a + .9 * pi) ' wing
  436.     y2 = ship.y + 60 * SIN(ship.a + .9 * pi)
  437.     x3 = ship.x + 60 * COS(ship.a - .9 * pi) ' other wing
  438.     y3 = ship.y + 60 * SIN(ship.a - .9 * pi)
  439.     ftri ship.x, ship.y, x1, y1, x2, y2, _RGB32(80, 120, 80, 80)
  440.     ftri ship.x, ship.y, x1, y1, x3, y3, _RGB32(60, 100, 60, 80)
  441.     LINE (ship.x, ship.y)-(x1, y1), _RGB32(255, 255, 128)
  442.     LINE (ship.x, ship.y)-(x2, y2), _RGB32(180, 180, 120)
  443.     LINE (ship.x, ship.y)-(x3, y3), _RGB32(180, 180, 120)
  444.  
  445. SUB drawRock (iRock)
  446.     RANDOMIZE USING r(iRock).seed 'this prevents having to save a particular sequence of random number
  447.     DIM dx, dy, rad AS LONG, j AS LONG, rRad AS SINGLE, leg AS SINGLE, x0 AS LONG, y0 AS LONG, rc AS LONG, c~&, x1 AS LONG, y1 AS LONG, xoff, yoff, i AS LONG
  448.     DIM x2 AS LONG, y2 AS LONG
  449.     dx = r(iRock).speed * COS(r(iRock).heading)
  450.     dy = r(iRock).speed * SIN(r(iRock).heading) 'update location
  451.     r(iRock).ra = r(iRock).ra + r(iRock).spin
  452.     IF r(iRock).x + dx + r(iRock).r < 0 OR r(iRock).x + dx - r(iRock).r > xmax OR r(iRock).y + dy + r(iRock).r < 0 OR r(iRock).y + dy - r(iRock).r > ymax THEN
  453.         IF iRock <= rocks THEN newRock iRock ELSE r(iRock).live = 0
  454.         EXIT SUB ' reassigned get out of here
  455.     ELSE
  456.         r(iRock).x = r(iRock).x + dx
  457.         r(iRock).y = r(iRock).y + dy
  458.     END IF
  459.     IF ((r(iRock).x - ship.x) ^ 2 + (r(iRock).y - ship.y) ^ 2) ^ .5 < r(iRock).r + 30 THEN 'rock collides with ship?
  460.         FOR rad = 1 TO 200
  461.             fcirc ship.x, ship.y, rad, _RGB32(255 - rad, 255 - 2 * rad, 0)
  462.             _DISPLAY
  463.             _LIMIT 300
  464.         NEXT
  465.         ship.live = 0
  466.         IF iRock <= rocks THEN newRock iRock ELSE r(iRock).live = 0
  467.         EXIT SUB
  468.     END IF
  469.     FOR j = 10 TO 3 STEP -1 '                  rock drawing (see demo program where developed code)
  470.         rRad = .1 * j * r(iRock).r
  471.         leg = rRad * (RND * .7 + .3)
  472.         x0 = r(iRock).x + leg * COS(r(iRock).ra)
  473.         y0 = r(iRock).y + leg * SIN(r(iRock).ra)
  474.         rc = r(iRock).c + 30 * RND - 15
  475.         c~& = _RGB32(rc + 5, rc - 10, rc + 5)
  476.         x1 = x0
  477.         y1 = y0
  478.         xoff = RND * 20 - 10 + r(iRock).x
  479.         yoff = RND * 20 - 10 + r(iRock).y
  480.         FOR i = 1 TO 12
  481.             leg = rRad * (RND * .35 + .65)
  482.             IF i = 12 THEN
  483.                 x2 = x0: y2 = y0
  484.             ELSE
  485.                 x2 = xoff + leg * COS(i * polyAngle + r(iRock).ra)
  486.                 y2 = yoff + leg * SIN(i * polyAngle + r(iRock).ra)
  487.             END IF
  488.             ftri r(iRock).x, r(iRock).y, x1, y1, x2, y2, c~&
  489.             x1 = x2: y1 = y2
  490.         NEXT
  491.     NEXT
  492.  
  493. SUB newRock (iRock)
  494.     DIM side AS LONG
  495.     RANDOMIZE TIMER * RND 'to avoid making twins
  496.     side = irnd&(1, 4) 'bring rock in from one side, need to set heading according to side
  497.     SELECT CASE side
  498.         CASE 1
  499.             r(iRock).x = -10
  500.             r(iRock).y = rrnd(20, ymax - 20)
  501.             r(iRock).heading = 3 * pi / 2 + RND * pi
  502.         CASE 2
  503.             r(iRock).x = xmax + 10
  504.             r(iRock).y = rrnd(20, ymax - 20)
  505.             r(iRock).heading = pi / 2 + RND * pi
  506.         CASE 3
  507.             r(iRock).x = rrnd(20, xmax - 20)
  508.             r(iRock).y = -10
  509.             r(iRock).heading = RND * pi
  510.         CASE 4
  511.             r(iRock).x = rrnd(20, xmax - 20)
  512.             r(iRock).y = ymax + 10
  513.             r(iRock).heading = pi + RND * pi
  514.     END SELECT
  515.     r(iRock).speed = rrnd(2, 5) 'speed, rotation angle, radius, gray coloring, spin, seed, hit for explosion
  516.     r(iRock).ra = RND * 2 * pi
  517.     r(iRock).r = irnd&(30, 100)
  518.     r(iRock).c = irnd&(10, 60)
  519.     r(iRock).spin = rrnd(-pi / 20, pi / 20)
  520.     r(iRock).seed = INT(RND * 64000) - 32000
  521.     r(iRock).explodeFrame = 0
  522.     r(iRock).live = 1
  523.  
  524. FUNCTION irnd& (n1, n2) 'return an integer between 2 numbers
  525.     DIM l%, h%
  526.     IF n1 > n2 THEN l% = n2: h% = n1 ELSE l% = n1: h% = n2
  527.     irnd& = INT(RND * (h% - l% + 1)) + l%
  528.  
  529. FUNCTION rrnd (n1, n2) ' return number (expecting reals =_single, double, _float depending on default / define setup)
  530.     rrnd = (n2 - n1) * RND + n1
  531.  
  532. SUB fellipse (CX AS LONG, CY AS LONG, xr AS LONG, yr AS LONG, C AS _UNSIGNED LONG)
  533.     IF xr = 0 OR yr = 0 THEN EXIT SUB
  534.     DIM x AS LONG, y AS LONG
  535.     w2 = xr * xr: h2 = yr * yr: h2w2 = h2 * w2
  536.     LINE (CX - xr, CY)-(CX + xr, CY), C, BF
  537.     DO WHILE y < yr
  538.         y = y + 1
  539.         x = SQR((h2w2 - y * y * w2) \ h2)
  540.         LINE (CX - x, CY + y)-(CX + x, CY + y), C, BF
  541.         LINE (CX - x, CY - y)-(CX + x, CY - y), C, BF
  542.     LOOP
  543.  
  544. SUB ftri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  545.     DIM D AS LONG
  546.     STATIC a&
  547.     D = _DEST
  548.     IF a& = 0 THEN a& = _NEWIMAGE(1, 1, 32)
  549.     _DEST a&
  550.     _DONTBLEND a& '  '<<<< new 2019-12-16 fix
  551.     PSET (0, 0), K
  552.     _BLEND a& '<<<< new 2019-12-16 fix
  553.     _DEST D
  554.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  555.  
  556. SUB fcirc (x AS LONG, y AS LONG, R AS LONG, C AS _UNSIGNED LONG) 'vince version
  557.     DIM x0 AS LONG, y0 AS LONG, e AS LONG
  558.     x0 = R: y0 = 0: e = 0
  559.     DO WHILE y0 < x0
  560.         IF e <= 0 THEN
  561.             y0 = y0 + 1
  562.             LINE (x - x0, y + y0)-(x + x0, y + y0), C, BF
  563.             LINE (x - x0, y - y0)-(x + x0, y - y0), C, BF
  564.             e = e + 2 * y0
  565.         ELSE
  566.             LINE (x - y0, y - x0)-(x + y0, y - x0), C, BF
  567.             LINE (x - y0, y + x0)-(x + y0, y + x0), C, BF
  568.             x0 = x0 - 1: e = e - 2 * x0
  569.         END IF
  570.     LOOP
  571.     LINE (x - R, y)-(x + R, y), C, BF
  572.  

Just need font from OP (original post zip)

 
Asteroids 6 Play Again.PNG
« Last Edit: November 01, 2020, 09:10:37 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: b+ Asteroids makeover
« Reply #35 on: November 01, 2020, 10:28:49 pm »
Wow I like that one better, it's more relaxing to play. You also might want to add a key to press to hide the words and numbers. Then show it when the game is over. Just an idea. :)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: b+ Asteroids makeover
« Reply #36 on: November 01, 2020, 11:02:11 pm »
Wow I like that one better, it's more relaxing to play. You also might want to add a key to press to hide the words and numbers. Then show it when the game is over. Just an idea. :)

Yeah! OK. distracting specially with all that other stuff going on. Also I noticed I wasn't counting hits on Aliens or Boulders (dang I've been spelling it wrong) of Death. Plus I want to see the ship collisions. So another update coming.

Update: Oh man! I am looking at these collisions and I need to relocate my x, y for the ship to it's center.
« Last Edit: November 01, 2020, 11:40:26 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: b+ Asteroids makeover
« Reply #37 on: November 02, 2020, 02:05:35 am »
M7 now with Splash screen and other screen tweaks, much more info when loose ship in collision, redesigned ship to work better for collision detection.

Code: QB64: [Select]
  1. _TITLE "b+ Asteroids m7 Play Again" 'started 2018-07-13"
  2. ' 2020-10-27 remove the alternate subs and get down below 200 LOC almost there now! new shooter action font and background
  3. ' 2020-10-28 another makeover explosions and split asteroids
  4. ' 2020-10-29 fix baby rock management, break between lives
  5. ' 2020-10-29 fix left/right gun, fix explosions over many frames to eliminate pause in action, speed up 60 fps
  6. ' 2020-10-30 m3 SierraKen's idea to angle shooter with mousewheel also finish WASD options, more rocks, points system
  7. ' points:
  8. ' The higher the speed the better    speed range 2 to 5, diff = 3 * 33.3333 = 100          s - 2 * 33.3333
  9. ' The lower the color the better   color range 10 to 60, diff =      50 * 2 = 100  50 - (c - 10) * 2
  10. ' The small        er the size the better  size range 10 to 100, diff = 90 * 1.1111 = 100  90 - (sz -10) * 1.1111
  11. '        ((speed - 2) * 33.3333 + (50 - (c -10)) * 2 + (90 - (r - 10)) * 1.1111) / 3 = 100 best score per hit
  12. ' 2020-10-30 increase level of difficulty, fix double lives lost, add an ending after all lives spent.
  13. ' 2020-10-31 M4 They are Here - the aliens have accepted my invitaion for war games don't get caught in their beam.
  14. ' rework ending and variable LONG suffix. Aliens on the attack 100 points before or after transformed into the Bolder of Death.
  15. ' 2020-11-01 M5 FX Moving through space, Oh yeah, more aliens!
  16. ' 2020-11-01 M6 add play again and save high game , continuous shoot
  17. ' 2020-11-01 M7 fix hits count when hit alien ship or Bolder of Death. Fix lights on aliens ship. I want to see collsions with ship.
  18. ' Ken recommends removing text in middle of screen, yeah, distracting. Makeover ship as with mouse x, y it's center. Add Splash screen.
  19. ' Show mouse in between lives so can be in screen center when press key to start next run.
  20.  
  21. '================================================================================================================
  22.  
  23. '    NOTE: !!!!!!!!!!!!!!!   When there is a pause in action, just hit any key to reset next life.
  24.  
  25. '================================================================================================================
  26.  
  27. CONST xmax = 1200, ymax = 700, pi = _PI, polyAngle = _PI / 6, nRocks = 300, nBullets = 2000, bSpeed = 15
  28.  
  29. TYPE alienType
  30.     x AS SINGLE
  31.     y AS SINGLE
  32.     dx AS SINGLE
  33.     dy AS SINGLE
  34.     ls AS LONG ' lights offset
  35.     c AS _UNSIGNED LONG ' color
  36.     live AS LONG
  37.     attackFrame AS LONG
  38.     fireX AS LONG
  39.     fireY AS LONG
  40.     transform AS LONG
  41.  
  42. TYPE particle
  43.     x AS LONG
  44.     y AS LONG
  45.     dx AS SINGLE
  46.     dy AS SINGLE
  47.     size AS SINGLE
  48.     kolor AS _UNSIGNED LONG
  49.  
  50. TYPE bullet
  51.     x AS LONG
  52.     y AS LONG
  53.     dx AS SINGLE
  54.     dy AS SINGLE
  55.     live AS LONG
  56.  
  57. TYPE shipType
  58.     x AS LONG
  59.     y AS LONG
  60.     live AS LONG
  61.     a AS SINGLE '   rotated position usu gun left or right (mouse button), maybe up press w or down press z
  62.  
  63. TYPE rock
  64.     x AS LONG
  65.     y AS LONG
  66.     r AS LONG '            radius
  67.     ra AS SINGLE '         rotation position   a = a + spin
  68.     heading AS SINGLE '    heading from which dx, dy are calc with speed
  69.     speed AS SINGLE '      speed
  70.     spin AS SINGLE '       rotation direction and amount
  71.     seed AS LONG '         for drawing rocks with RND USING
  72.     c AS LONG '            color   rgb(c, c, c)
  73.     live AS LONG '         need this to track rocks still active like bullets
  74.     explodeFrame AS LONG ' after a rock is hit by bullet, it explodes and in more than one frame
  75.  
  76. REDIM SHARED aliens(1 TO 5) AS alienType
  77. DIM SHARED dots(2000) AS particle
  78. DIM SHARED b(nBullets) AS bullet
  79. DIM SHARED ship AS shipType
  80. DIM SHARED r(nRocks) AS rock
  81. DIM SHARED points AS LONG
  82. DIM SHARED rocks AS LONG 'rocks is the minimum number of parent rocks to have on screen  automatic replace when hit or out of bounds
  83.  
  84. DIM HS AS LONG, fnt AS LONG, fnt2 AS LONG ' file LOAD handles
  85. DIM i AS LONG, bullets AS LONG, fire AS LONG ' index and bullets
  86. DIM r AS LONG, newRockN AS LONG, maxBabyRocks AS LONG, br AS LONG, hits AS LONG ' rock stuff
  87. DIM ai AS LONG, alienN AS LONG ' alien index and number
  88. DIM hs$, s$, t, lastt ' general string and times
  89.  
  90. SCREEN _NEWIMAGE(xmax, ymax, 32)
  91. _SCREENMOVE 100, 20
  92.  
  93. fnt = _LOADFONT("ARLRDBD.ttf", 16, "MONOSPACE")
  94. fnt2 = _LOADFONT("ARLRDBD.ttf", 40, "MONOSPACE")
  95. _FONT fnt2
  96. COLOR &HFF00FFFF, &H00000000
  97.  
  98.  
  99. IF _FILEEXISTS("Asteroids High Score.txt") THEN
  100.     OPEN "Asteroids High Score.txt" FOR INPUT AS #1
  101.     INPUT #1, HS
  102.     CLOSE #1
  103. hs$ = "High Score:" + STR$(HS)
  104.  
  105. 'a little splash screen
  106. rocks = 7: alienN = 3
  107. FOR i = 1 TO nRocks
  108.     newRock i
  109.     IF i > rocks THEN r(i).live = 0
  110. FOR i = 1 TO alienN
  111.     newAlien i
  112. i = 0
  113.     drawStars 0
  114.     i = i + 1
  115.     IF i MOD 30 = 29 AND rocks < nRocks THEN rocks = rocks + 1: r(rocks).live = 1
  116.     FOR r = 1 TO nRocks
  117.         IF r(r).live THEN drawRock r
  118.     NEXT
  119.     FOR i = 1 TO alienN
  120.         drawAliens i
  121.     NEXT
  122.     _FONT fnt2
  123.     s$ = "Welcome to b+ Asteroids"
  124.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, 60), s$
  125.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(hs$)) / 2, 140), hs$
  126.     s$ = "To get ready,"
  127.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, 220), s$
  128.     s$ = "place mouse pointer"
  129.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, 300), s$
  130.     s$ = "in center of screen"
  131.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, 380), s$
  132.     s$ = "Press q to Quit,"
  133.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, 460), s$
  134.     s$ = "any other to Play"
  135.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, 540), s$
  136.     _FONT fnt
  137.     s$ = INKEY$
  138.     IF s$ = "q" THEN SYSTEM
  139.     _DISPLAY
  140.     _LIMIT 60
  141.  
  142. restart:
  143. IF _FILEEXISTS("Asteroids High Score.txt") THEN
  144.     OPEN "Asteroids High Score.txt" FOR INPUT AS #1
  145.     INPUT #1, HS
  146.     CLOSE #1
  147. hs$ = "  High Score:" + STR$(HS)
  148. lives = 10: alienN = 1: rocks = 4: ' always active rocks
  149. points = 0: hits = 0: bullets = 0
  150.  
  151. WHILE lives > 0 AND _KEYDOWN(27) = 0 ' init start restart
  152.     REDIM aliens(1 TO alienN) AS alienType
  153.     FOR ai = 1 TO alienN
  154.         newAlien ai
  155.     NEXT
  156.     FOR i = 1 TO nRocks 'reset rocks mainly clear baby rocks
  157.         newRock (i)
  158.         IF i > rocks THEN r(i).live = 0
  159.     NEXT
  160.     ship.x = xmax / 2 'avoids explosions top left corner at start, dang still get some!
  161.     ship.y = ymax / 2
  162.     ship.live = 1
  163.     WHILE ship.live AND _KEYDOWN(27) = 0
  164.         'draw everything then process bullets
  165.         drawStars 1
  166.  
  167.         FOR ai = 1 TO alienN
  168.             drawAliens ai
  169.         NEXT
  170.         FOR i = 1 TO nRocks
  171.             IF r(i).live THEN drawRock i ' while drawing rocks the ship could be blown up
  172.             IF ((r(i).x - ship.x) ^ 2 + (r(i).y - ship.y) ^ 2) ^ .5 < r(i).r + 30 THEN 'rock collides with ship?
  173.                 FOR br = 1 TO 200 STEP 5
  174.                     CIRCLE ((ship.x + r(i).x) / 2, (ship.y + r(i).y) / 2), br, _RGB32(255 - br, 255 - 2 * br, 0)
  175.                 NEXT
  176.                 drawRock i
  177.                 drawship
  178.                 ship.live = 0
  179.                 IF i <= rocks THEN newRock i ELSE r(i).live = 0
  180.             END IF
  181.         NEXT
  182.         FOR i = 1 TO nRocks 'smoke up the place with rock debris fields still flying out from hit frames ago
  183.             IF r(i).explodeFrame THEN
  184.                 r(i).explodeFrame = r(i).explodeFrame + 1
  185.                 IF r(i).explodeFrame > .5 * r(i).r THEN
  186.                     r(i).explodeFrame = 0
  187.                     IF i <= rocks THEN newRock i ' now replace the rock
  188.                 ELSE
  189.                     explode r(i).x, r(i).y, r(i).r, r(i).explodeFrame
  190.                 END IF
  191.             END IF
  192.         NEXT
  193.         IF ship.live THEN
  194.             FOR ai = 1 TO alienN
  195.                 IF SQR((aliens(ai).x - ship.x) ^ 2 + (aliens(ai).y - ship.y) ^ 2) < 60 THEN 'aliens and ship collisde boom boom
  196.                     FOR br = 1 TO 200 STEP 5
  197.                         CIRCLE ((ship.x + aliens(ai).x) / 2, (ship.y + aliens(ai).y) / 2), br, _RGB32(255 - br, 255 - 2 * br, 0)
  198.                     NEXT
  199.                     drawship
  200.                     ship.live = 0
  201.                     _CONTINUE
  202.                 ELSE
  203.                     drawship
  204.                 END IF
  205.             NEXT
  206.             WHILE _MOUSEINPUT
  207.                 ship.a = ship.a + _MOUSEWHEEL * pi / 8 ' 22.5  degree changes, Thank Ken for this :)
  208.             WEND 'update ship
  209.             ship.x = _MOUSEX: ship.y = _MOUSEY
  210.             IF _MOUSEBUTTON(1) THEN ship.a = pi 'this is new left and right guns
  211.             IF _MOUSEBUTTON(2) THEN ship.a = 0
  212.             IF _KEYDOWN(ASC("w")) THEN ship.a = 1.5 * pi ' well it works but ??
  213.             IF _KEYDOWN(ASC("a")) THEN ship.a = pi
  214.             IF _KEYDOWN(ASC("s")) THEN ship.a = .5 * pi
  215.             IF _KEYDOWN(ASC("d")) THEN ship.a = 0
  216.             fire = 0
  217.             'IF _KEYDOWN(32) THEN 'fire bullets
  218.             t = TIMER(.01)
  219.             IF lastt = 0 OR t - lastt > .2 THEN fire = 1: lastt = t
  220.             'END IF
  221.             FOR i = 0 TO nBullets 'handle bullets
  222.                 IF b(i).live = 0 AND fire = 1 THEN 'have inactive bullet to use
  223.                     b(i).x = ship.x + bSpeed * COS(ship.a)
  224.                     b(i).y = ship.y + bSpeed * SIN(ship.a)
  225.                     b(i).dx = bSpeed * COS(ship.a)
  226.                     b(i).dy = bSpeed * SIN(ship.a)
  227.                     b(i).live = -1
  228.                     bullets = bullets + 1
  229.                     fire = 0
  230.                 END IF
  231.                 IF b(i).live THEN 'new location
  232.                     b(i).x = b(i).x + b(i).dx
  233.                     b(i).y = b(i).y + b(i).dy
  234.                     IF b(i).x > 0 AND b(i).x < xmax AND b(i).y > 0 AND b(i).y < ymax THEN 'in bounds draw it
  235.  
  236.                         'bullet hit aliens?
  237.                         FOR ai = 1 TO alienN
  238.                             IF SQR((aliens(ai).x - b(i).x) ^ 2 + (aliens(ai).y - b(i).y) ^ 2) < 30 THEN
  239.                                 FOR br = 1 TO 120
  240.                                     CIRCLE (aliens(ai).x, aliens(ai).y), br / 3, plasma~&(0)
  241.                                 NEXT
  242.                                 _DISPLAY
  243.                                 _DELAY .05
  244.                                 hits = hits + 1
  245.                                 points = points + 100
  246.                                 aliens(ai).live = 0
  247.                                 newAlien ai
  248.                                 b(i).live = 0
  249.                                 _CONTINUE
  250.                             END IF
  251.                         NEXT
  252.                         FOR r = 1 TO nRocks 'check for collision with rock
  253.                             IF r(r).live THEN
  254.                                 IF SQR((r(r).x - b(i).x) ^ 2 + (r(r).y - b(i).y) ^ 2) < r(r).r THEN 'its a hit!
  255.                                     r(r).explodeFrame = 1 'linger with explosion
  256.                                     r(r).live = 0
  257.                                     hits = hits + 1
  258.                                     points = points + ((r(r).speed - 2) * 33.3333 + (50 - (r(r).c - 10)) * 2 + (90 - (r(r).r - 10)) * 1.1111) / 3
  259.                                     IF r(r).r > 30 THEN '       split rock  into ? new ones
  260.                                         maxBabyRocks = INT((r(r).r - 10) / 10)
  261.                                         maxBabyRocks = irnd&(2, maxBabyRocks) ' pick a number of baby Rocks
  262.                                         FOR br = 1 TO maxBabyRocks
  263.                                             '                        new rock
  264.                                             newRockN = freeRock& '                          get inactive rock number
  265.                                             newRock newRockN '                              new identity and activate
  266.                                             r(newRockN).r = (r(r).r - 10) / maxBabyRocks '  split in equal parts minus 20% mass
  267.                                             r(newRockN).x = r(r).x + irnd&(-30, 30) '       thrown from parent
  268.                                             r(newRockN).y = r(r).y + irnd&(-30, 30)
  269.                                             r(newRockN).c = r(r).c '                   same color as parent
  270.                                             r(newRockN).heading = rrnd(ship.a - .75 * pi, ship.a + .75 * pi)
  271.                                         NEXT
  272.                                     END IF ' big enough to split
  273.                                     b(i).live = 0 'kill bullet
  274.                                 END IF ' hit rock
  275.                             END IF 'rock is there
  276.                         NEXT ' rock
  277.                         IF b(i).live THEN fcirc b(i).x, b(i).y, 3, _RGB32(255, 255, 0) 'draws bullet
  278.                     ELSE
  279.                         b(i).live = 0 'out of bounds
  280.                     END IF ' bullet is in bounds
  281.                 END IF ' bullet live
  282.             NEXT ' bullet
  283.         END IF ' if ship still live
  284.         _DISPLAY
  285.         IF ship.live = 0 THEN
  286.             lives = lives - 1
  287.             IF lives MOD 4 = 0 THEN rocks = rocks + 1
  288.             IF lives MOD 4 = 2 THEN alienN = alienN + 1
  289.             s$ = "Lives:" + STR$(lives) + "  Hits:" + STR$(hits) + "  Bullets:" + STR$(bullets) + "  Shooting:" + STR$(INT(hits * 100 / bullets)) + "%"
  290.             _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 - 80), s$
  291.             _FONT fnt2
  292.             s$ = STR$(points) + hs$
  293.             _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2), s$
  294.             _FONT fnt
  295.             s$ = "Center mouse and press any"
  296.             _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 + 120), s$
  297.             _DISPLAY
  298.             _MOUSESHOW
  299.             SLEEP
  300.         ELSE
  301.             _LIMIT 60 ' if ship dies let's rest and regroup  before restart next life
  302.         END IF
  303.     WEND
  304.     _DISPLAY
  305. IF points > HS THEN
  306.     OPEN "Asteroids High Score.txt" FOR OUTPUT AS #1
  307.     PRINT #1, points
  308.     CLOSE #1
  309. ship.x = -200: ship.y = -200 'get it out of the way
  310. i = 0
  311.     drawStars 0
  312.     i = i + 1
  313.     IF i MOD 30 = 29 AND rocks < nRocks THEN rocks = rocks + 1: r(rocks).live = 1
  314.     FOR r = 1 TO nRocks
  315.         IF r(r).live THEN drawRock r
  316.     NEXT
  317.     s$ = "Lives:" + STR$(lives) + "  Hits:" + STR$(hits) + "  Bullets:" + STR$(bullets) + "  Shooting:" + STR$(INT(hits * 100 / bullets)) + "%"
  318.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 - 80), s$
  319.     _FONT fnt2
  320.     s$ = STR$(points)
  321.     IF points > HS THEN s$ = s$ + " a New Record!" ELSE s$ = STR$(points) + hs$
  322.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2), s$
  323.     _FONT fnt
  324.     s$ = "Press q to quit, p or a to Play Again..."
  325.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 + 120), s$
  326.     IF _KEYDOWN(ASC("a")) OR _KEYDOWN(ASC("p")) THEN GOTO restart
  327.     _DISPLAY
  328.     _LIMIT 60
  329.  
  330. SUB drawStars (moving)
  331.     TYPE starType
  332.         x AS SINGLE
  333.         y AS SINGLE
  334.         size AS SINGLE
  335.         c AS INTEGER
  336.     END TYPE
  337.     STATIC beenHere, stars(600) AS starType, cy AS LONG
  338.     DIM i AS LONG
  339.     IF beenHere = 0 THEN 'static part
  340.         FOR i = 0 TO 200
  341.             stars(i).x = RND * xmax: stars(i).y = RND * ymax: stars(i).size = 0
  342.             stars(i).c = irnd&(80, 140)
  343.         NEXT
  344.         FOR i = 0 TO 200
  345.             stars(i).x = RND * xmax: stars(i).y = RND * ymax: stars(i).size = .3
  346.             stars(i).c = irnd&(80, 140)
  347.         NEXT
  348.  
  349.         FOR i = 1 TO 140
  350.             stars(i + 400).x = RND * xmax: stars(i + 400).y = RND * ymax: stars(i + 100).size = .6
  351.             stars(i).c = irnd&(110, 170)
  352.         NEXT
  353.         FOR i = 1 TO 50
  354.             stars(i + 540).x = RND * xmax: stars(i + 540).y = RND * ymax: stars(i + 170).size = 1.2
  355.             stars(i).c = irnd&(140, 200)
  356.         NEXT
  357.         FOR i = 1 TO 10
  358.             stars(i + 590).x = RND * xmax: stars(i + 590).y = RND * ymax: stars(i + 195).size = 2.4
  359.             stars(i).c = irnd&(170, 235)
  360.         NEXT
  361.         cy = ymax / 2
  362.         beenHere = 1
  363.     END IF
  364.     FOR i = 0 TO cy
  365.         LINE (0, i)-(xmax, i), _RGB32(0, 0, .1 * i + 4)
  366.         LINE (0, ymax - i)-(xmax, ymax - i), _RGB(0, 0, .1 * i + 4)
  367.     NEXT
  368.     FOR i = 0 TO 200
  369.         IF moving THEN
  370.             stars(i).x = stars(i).x + .2 * stars(i).size ^ stars(i).size
  371.             IF stars(i).x > xmax THEN stars(i).x = -1 * RND * 20
  372.         END IF
  373.         fcirc stars(i).x, stars(i).y, stars(i).size, _RGB32(stars(i).c - 10, stars(i).c, stars(i).c + 10)
  374.     NEXT
  375.  
  376. SUB newAlien (i AS LONG)
  377.     DIM side AS LONG, heading
  378.     RANDOMIZE TIMER * RND 'to avoid making twins
  379.     side = irnd&(1, 4) 'bring rock in from one side, need to set heading according to side
  380.     aliens(i).fireX = irnd(10, xmax - 10)
  381.     aliens(i).fireY = irnd(10, ymax - 10)
  382.     aliens(i).attackFrame = irnd(30, 400) ' EDIT a tweak to survive a little long before getting murdered with low lives over and over...
  383.     SELECT CASE side
  384.         CASE 1
  385.             aliens(i).x = -10
  386.             aliens(i).y = rrnd(20, ymax - 20)
  387.         CASE 2
  388.             aliens(i).x = xmax + 10
  389.             aliens(i).y = rrnd(20, ymax - 20)
  390.         CASE 3
  391.             aliens(i).x = rrnd(20, xmax - 20)
  392.             aliens(i).y = -10
  393.         CASE 4
  394.             aliens(i).x = rrnd(20, xmax - 20)
  395.             aliens(i).y = ymax + 10
  396.     END SELECT
  397.     heading = _ATAN2(aliens(i).fireY - aliens(i).y, aliens(i).fireX - aliens(i).x)
  398.     aliens(i).dx = 3.5 * COS(heading)
  399.     aliens(i).dy = 3.5 * SIN(heading)
  400.     aliens(i).live = 0
  401.     aliens(i).transform = 0
  402.     aliens(i).c = _RGB32(irnd(128, 255), irnd(0, 255), irnd(0, 255))
  403.  
  404. FUNCTION plasma~& (new AS LONG)
  405.     STATIC r, g, b, cnt, beenHere
  406.     IF beenHere = 0 OR new THEN
  407.         r = RND: g = RND: b = RND: beenHere = 1: cnt = 0
  408.     END IF
  409.     cnt = cnt + .2
  410.     plasma~& = _RGB32(127 + 127 * SIN(r * cnt), 127 + 127 * SIN(g * cnt), 127 + 127 * SIN(b * cnt))
  411.  
  412. SUB drawAliens (i AS LONG) 'shipType
  413.     DIM light AS LONG, heading, r AS LONG, g AS LONG, b AS LONG
  414.     IF aliens(i).live THEN
  415.         IF aliens(i).transform = 0 THEN
  416.             r = _RED32(aliens(i).c): g = _GREEN32(aliens(i).c): b = _BLUE32(aliens(i).c)
  417.             fellipse aliens(i).x, aliens(i).y, 6, 15, _RGB32(r, g - 120, b - 100)
  418.             fellipse aliens(i).x, aliens(i).y, 18, 11, _RGB32(r, g - 60, b - 50)
  419.             fellipse aliens(i).x, aliens(i).y, 30, 7, _RGB32(r, g, b)
  420.             FOR light = 0 TO 5
  421.                 fcirc aliens(i).x - 30 + 11 * light + aliens(i).ls, aliens(i).y, 1, _RGB32(aliens(i).ls * 50, aliens(i).ls * 50, aliens(i).ls * 50)
  422.             NEXT
  423.             aliens(i).ls = aliens(i).ls + 1
  424.             IF aliens(i).ls > 5 THEN aliens(i).ls = 0
  425.         ELSE
  426.             fcirc aliens(i).x, aliens(i).y, 30, aliens(i).c
  427.         END IF
  428.         'time to shoot?
  429.         aliens(i).x = aliens(i).x + aliens(i).dx
  430.         aliens(i).y = aliens(i).y + aliens(i).dy
  431.         IF SQR((aliens(i).fireX - aliens(i).x) ^ 2 + (aliens(i).fireY - aliens(i).y) ^ 2) < 5 THEN 'transform into the bolder of death
  432.             aliens(i).transform = 1
  433.             heading = _ATAN2(ship.y - aliens(i).y, ship.x - aliens(i).x)
  434.             aliens(i).dx = 10 * COS(heading)
  435.             aliens(i).dy = 10 * SIN(heading)
  436.         END IF
  437.         IF aliens(i).x < -10 OR aliens(i).x > xmax + 10 THEN
  438.             IF aliens(i).y < -10 OR aliens(i).y > ymax + 10 THEN '  out of bounds goodbye bolder of death!
  439.                 aliens(i).live = 0 'man we dodged a bullet here!!!!
  440.                 newAlien i 'reset the trap
  441.             END IF
  442.         END IF
  443.     ELSE
  444.         IF aliens(i).attackFrame THEN
  445.             aliens(i).attackFrame = aliens(i).attackFrame - 1
  446.             IF aliens(i).attackFrame = 0 THEN
  447.                 aliens(i).live = 1
  448.             END IF
  449.         END IF
  450.     END IF
  451.  
  452. FUNCTION freeRock&
  453.     DIM i AS LONG
  454.     FOR i = rocks + 1 TO nRocks ' look for inactive rock number
  455.         IF r(i).live = 0 AND r(i).explodeFrame = 0 THEN freeRock& = i: EXIT FUNCTION
  456.     NEXT
  457.  
  458. SUB explode (x AS LONG, y AS LONG, r AS LONG, frm AS LONG)
  459.     DIM maxParticles AS LONG, i AS LONG, rounds AS LONG, loopCount AS LONG
  460.     maxParticles = r * 4
  461.     FOR i = 1 TO r
  462.         NewDot i, x, y, r
  463.     NEXT
  464.     rounds = r
  465.     FOR loopCount = 0 TO frm
  466.         IF _KEYDOWN(27) THEN END
  467.         FOR i = 1 TO rounds
  468.             dots(i).x = dots(i).x + dots(i).dx
  469.             dots(i).y = dots(i).y + dots(i).dy
  470.             fcirc dots(i).x, dots(i).y, dots(i).size, dots(i).kolor
  471.         NEXT
  472.         IF rounds < maxParticles THEN
  473.             FOR i = 1 TO r
  474.                 NewDot (rounds + i), x, y, r
  475.             NEXT
  476.             rounds = rounds + r
  477.         END IF
  478.     NEXT
  479.  
  480. SUB NewDot (i AS LONG, x AS LONG, y AS LONG, r AS LONG)
  481.     DIM angle, rd
  482.     angle = pi * 2 * RND
  483.     rd = RND * 30
  484.     dots(i).x = x + rd * COS(angle)
  485.     dots(i).y = y + rd * SIN(angle)
  486.     dots(i).size = RND * r * .05
  487.     rd = RND 'STxAxTIC recommended for rounder spreads
  488.     dots(i).dx = rd * 10 * (10 - 2 * dots(i).size) * COS(angle)
  489.     dots(i).dy = rd * 10 * (10 - 2 * dots(i).size) * SIN(angle)
  490.     rd = 20 + RND * 70
  491.     dots(i).kolor = _RGBA32(rd, rd, rd, 80)
  492.  
  493. SUB drawship 'simple red iso triangle pointed towards radianAngle
  494.     DIM x1 AS LONG, y1 AS LONG, x2 AS LONG, y2 AS LONG, x3 AS LONG, y3 AS LONG
  495.     'calculate 3 points of triangle ship
  496.     fcirc ship.x, ship.y, 30, &H05FFFFFF
  497.     x1 = ship.x + 30 * COS(ship.a) ' front point
  498.     y1 = ship.y + 30 * SIN(ship.a) '
  499.     x2 = ship.x + 30 * COS(ship.a + .6666 * pi) ' wing
  500.     y2 = ship.y + 30 * SIN(ship.a + .6666 * pi)
  501.     x3 = ship.x + 30 * COS(ship.a - .6666 * pi) ' other wing
  502.     y3 = ship.y + 30 * SIN(ship.a - .6666 * pi)
  503.     ftri ship.x, ship.y, x1, y1, x2, y2, _RGB32(80, 120, 80, 80)
  504.     ftri ship.x, ship.y, x1, y1, x3, y3, _RGB32(60, 100, 60, 80)
  505.     LINE (x1, y1)-(ship.x, ship.y), _RGB32(255, 255, 128)
  506.     LINE (x1, y1)-(x2, y2), _RGB32(180, 180, 120)
  507.     LINE (x1, y1)-(x3, y3), _RGB32(180, 180, 120)
  508.  
  509. SUB drawRock (iRock)
  510.     RANDOMIZE USING r(iRock).seed 'this prevents having to save a particular sequence of random number
  511.     DIM dx, dy, j AS LONG, rRad AS SINGLE, leg AS SINGLE, x0 AS LONG, y0 AS LONG, rc AS LONG, c~&, x1 AS LONG, y1 AS LONG, xoff, yoff, i AS LONG
  512.     DIM x2 AS LONG, y2 AS LONG
  513.     dx = r(iRock).speed * COS(r(iRock).heading)
  514.     dy = r(iRock).speed * SIN(r(iRock).heading) 'update location
  515.     r(iRock).ra = r(iRock).ra + r(iRock).spin
  516.     IF r(iRock).x + dx + r(iRock).r < 0 OR r(iRock).x + dx - r(iRock).r > xmax OR r(iRock).y + dy + r(iRock).r < 0 OR r(iRock).y + dy - r(iRock).r > ymax THEN
  517.         IF iRock <= rocks THEN newRock iRock ELSE r(iRock).live = 0
  518.         EXIT SUB ' reassigned get out of here
  519.     ELSE
  520.         r(iRock).x = r(iRock).x + dx
  521.         r(iRock).y = r(iRock).y + dy
  522.     END IF
  523.     FOR j = 10 TO 3 STEP -1 '                  rock drawing (see demo program where developed code)
  524.         rRad = .1 * j * r(iRock).r
  525.         leg = rRad * (RND * .7 + .3)
  526.         x0 = r(iRock).x + leg * COS(r(iRock).ra)
  527.         y0 = r(iRock).y + leg * SIN(r(iRock).ra)
  528.         rc = r(iRock).c + 30 * RND - 15
  529.         c~& = _RGB32(rc + 5, rc - 10, rc + 5)
  530.         x1 = x0
  531.         y1 = y0
  532.         xoff = RND * 20 - 10 + r(iRock).x
  533.         yoff = RND * 20 - 10 + r(iRock).y
  534.         FOR i = 1 TO 12
  535.             leg = rRad * (RND * .35 + .65)
  536.             IF i = 12 THEN
  537.                 x2 = x0: y2 = y0
  538.             ELSE
  539.                 x2 = xoff + leg * COS(i * polyAngle + r(iRock).ra)
  540.                 y2 = yoff + leg * SIN(i * polyAngle + r(iRock).ra)
  541.             END IF
  542.             ftri r(iRock).x, r(iRock).y, x1, y1, x2, y2, c~&
  543.             x1 = x2: y1 = y2
  544.         NEXT
  545.     NEXT
  546.  
  547. SUB newRock (iRock)
  548.     DIM side AS LONG
  549.     RANDOMIZE TIMER * RND 'to avoid making twins
  550.     side = irnd&(1, 4) 'bring rock in from one side, need to set heading according to side
  551.     SELECT CASE side
  552.         CASE 1
  553.             r(iRock).x = -10
  554.             r(iRock).y = rrnd(20, ymax - 20)
  555.             r(iRock).heading = 3 * pi / 2 + RND * pi
  556.         CASE 2
  557.             r(iRock).x = xmax + 10
  558.             r(iRock).y = rrnd(20, ymax - 20)
  559.             r(iRock).heading = pi / 2 + RND * pi
  560.         CASE 3
  561.             r(iRock).x = rrnd(20, xmax - 20)
  562.             r(iRock).y = -10
  563.             r(iRock).heading = RND * pi
  564.         CASE 4
  565.             r(iRock).x = rrnd(20, xmax - 20)
  566.             r(iRock).y = ymax + 10
  567.             r(iRock).heading = pi + RND * pi
  568.     END SELECT
  569.     r(iRock).speed = rrnd(2, 5) 'speed, rotation angle, radius, gray coloring, spin, seed, hit for explosion
  570.     r(iRock).ra = RND * 2 * pi
  571.     r(iRock).r = irnd&(30, 100)
  572.     r(iRock).c = irnd&(10, 60)
  573.     r(iRock).spin = rrnd(-pi / 20, pi / 20)
  574.     r(iRock).seed = INT(RND * 64000) - 32000
  575.     r(iRock).explodeFrame = 0
  576.     r(iRock).live = 1
  577.  
  578. FUNCTION irnd& (n1, n2) 'return an integer between 2 numbers
  579.     DIM l%, h%
  580.     IF n1 > n2 THEN l% = n2: h% = n1 ELSE l% = n1: h% = n2
  581.     irnd& = INT(RND * (h% - l% + 1)) + l%
  582.  
  583. FUNCTION rrnd (n1, n2) ' return number (expecting reals =_single, double, _float depending on default / define setup)
  584.     rrnd = (n2 - n1) * RND + n1
  585.  
  586. SUB fellipse (CX AS LONG, CY AS LONG, xr AS LONG, yr AS LONG, C AS _UNSIGNED LONG)
  587.     IF xr = 0 OR yr = 0 THEN EXIT SUB
  588.     DIM x AS LONG, y AS LONG
  589.     w2 = xr * xr: h2 = yr * yr: h2w2 = h2 * w2
  590.     LINE (CX - xr, CY)-(CX + xr, CY), C, BF
  591.     DO WHILE y < yr
  592.         y = y + 1
  593.         x = SQR((h2w2 - y * y * w2) \ h2)
  594.         LINE (CX - x, CY + y)-(CX + x, CY + y), C, BF
  595.         LINE (CX - x, CY - y)-(CX + x, CY - y), C, BF
  596.     LOOP
  597.  
  598. SUB ftri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  599.     DIM D AS LONG
  600.     STATIC a&
  601.     D = _DEST
  602.     IF a& = 0 THEN a& = _NEWIMAGE(1, 1, 32)
  603.     _DEST a&
  604.     _DONTBLEND a& '  '<<<< new 2019-12-16 fix
  605.     PSET (0, 0), K
  606.     _BLEND a& '<<<< new 2019-12-16 fix
  607.     _DEST D
  608.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  609.  
  610. SUB fcirc (x AS LONG, y AS LONG, R AS LONG, C AS _UNSIGNED LONG) 'vince version
  611.     DIM x0 AS LONG, y0 AS LONG, e AS LONG
  612.     x0 = R: y0 = 0: e = 0
  613.     DO WHILE y0 < x0
  614.         IF e <= 0 THEN
  615.             y0 = y0 + 1
  616.             LINE (x - x0, y + y0)-(x + x0, y + y0), C, BF
  617.             LINE (x - x0, y - y0)-(x + x0, y - y0), C, BF
  618.             e = e + 2 * y0
  619.         ELSE
  620.             LINE (x - y0, y - x0)-(x + y0, y - x0), C, BF
  621.             LINE (x - y0, y + x0)-(x + y0, y + x0), C, BF
  622.             x0 = x0 - 1: e = e - 2 * x0
  623.         END IF
  624.     LOOP
  625.     LINE (x - R, y)-(x + R, y), C, BF
  626.  

Font from OP is only asset needed.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: b+ Asteroids makeover
« Reply #38 on: November 02, 2020, 02:52:07 pm »
That's really cool!! My High Score is 15857. :)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: b+ Asteroids makeover
« Reply #39 on: November 02, 2020, 04:07:26 pm »
That's really cool!! My High Score is 15857. :)

Yeah, I haven't been able to get near 38,000 with m7, best is low 20's with this last update.

Last night I was exhausted and poor reaction times... today fresher I tried a couple and can't believe I am not lasting longer with lives 10, 9, 8 always running into some fragment of rock I can't see or I jerk away too far or get caught too close to an edge with new rocks raining in. Man! if you don't make serious points in 10, 9, 8 then you should start over, that is, if you are going for record. I am surprised how long I can last with 1 life left (sometimes)!

Do you like collisions with ship better? (Where now you can see exactly which rock or alien or Boulder of Death did you in.)

Should we save 10 best scores?

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: b+ Asteroids makeover
« Reply #40 on: November 02, 2020, 05:12:30 pm »
10 Best Scores would be awesome! Yeah I like how I can see what I run into. If you REALLY want to work on this a lot more to get it more like the arcade versions, you can remove the mouse movement, except the scroller wheel, and with the left mouse button fire up the engines and the longer you hold it down, the faster you go. It would be harder to play but that's more like the arcade version. You would have to make some kind of exhaust shooting out the back and adding sound to it would help too. But that's just if you want to work on this a lot more. But your version does have an originality to it for sure and it isn't too hard if you get used to the movement.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: b+ Asteroids makeover
« Reply #41 on: November 02, 2020, 05:28:59 pm »
Did arcades use joy sticks? I can't see maneuvering the ship with key presses, even if did something with numeric keypad. A joystick would be perfect because it wouldn't allow you to jump around.

Yeah I saw the rocket thrust flame in the video and tried again with mouse to angle and change position, it's one or the other so far but never say never... come to think, I did a Lander version with simplified rocket thrusters but I wonder if one could possibly switch directions that fast.

I leave sounds to anyone who wants to contribute. I will add them if not .ogg.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: b+ Asteroids makeover
« Reply #42 on: November 02, 2020, 05:54:48 pm »
Cool about sounds. Well, it doesn't change direction automatically, it's all physics like your lander was probably. Like if you were moving 10 mph and turned and blasted the engines, you would still be going that other direction for a short amount of time and then it would stop and go the new movement. I'm not sure if I know how to make that or not. It wouldn't require the keyboard. The arcade version had a joystick I believe but still worked in this manner. If would have to use both X and Y movement at the same time and just subtract or add X and Y with the new movement. I think I'm going to see if I can make that movement or not on a demo and post it here for you. I might not be able to.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: b+ Asteroids makeover
« Reply #43 on: November 02, 2020, 06:54:54 pm »
I will take a look at Lander thrusters and give it a go as well. Why does spellchecker not like thrusters?

https://www.google.com/search?client=opera&q=spell+thruster&sourceid=opera&ie=UTF-8&oe=UTF-8

Offline SierraKen

  • Forum Resident
  • Posts: 1454
Re: b+ Asteroids makeover
« Reply #44 on: November 02, 2020, 07:08:04 pm »
Here is a demo I just made for you B+. It's probably a lot like your lander but I wanted to see if I was able to make it myself. If you want to use this code, I'm sure you could make it less code and instead of 4 angles to turn like I have you could make it 8 or as many as you use in your game. Use the scroller wheel (lol spell checker doesn't like "scroller" either) to turn directions and the left mouse button to go. The gun turret shows which direction you are wanting to go. I might turn this into a game. :)
direction2 variable is what angle you are pointing and direction variable is what angle you are actually going.

This isn't like the Asteroids arcade game though. I couldn't figure out how to make it so the physics still makes your guy go one way but slows down as you are wanting to go another way. I thought this would do it but I just noticed it doesn't. But mine does average out the different direction variables so it goes diagonally.

Code: QB64: [Select]
  1. 'Tank Demo using mouse button and mouse scroller wheel.
  2.  
  3. SCREEN _NEWIMAGE(800, 600, 32)
  4. x = 400
  5. y = 300
  6. direction = 1 'North
  7.  
  8.  
  9.     _LIMIT 20
  10.     mouseWheel = 0
  11.         mouseX = _MOUSEX
  12.         mouseY = _MOUSEY
  13.         mouseLeftButton = _MOUSEBUTTON(1)
  14.         mouseRightButton = _MOUSEBUTTON(2)
  15.         mouseMiddleButton = _MOUSEBUTTON(3)
  16.         mouseWheel = mouseWheel + _MOUSEWHEEL
  17.     LOOP
  18.     IF mouseWheel < 0 THEN direction2 = direction2 - 1
  19.     IF mouseWheel > 0 THEN direction2 = direction2 + 1
  20.     IF direction2 > 4 THEN direction2 = 1
  21.     IF direction2 < 1 THEN direction2 = 4
  22.  
  23.     IF direction2 = 1 AND direction = 2 THEN y = y - speed: x = x + speed: amount = amount - 1
  24.     IF direction2 = 1 AND direction = 4 THEN y = y - speed: x = x - speed: amount = amount - 1
  25.     IF direction2 = 1 AND direction = 3 THEN y = y - speed: amount = amount - 1
  26.     IF direction2 = 2 AND direction = 1 THEN x = x + speed: y = y - speed: amount = amount - 1
  27.     IF direction2 = 2 AND direction = 3 THEN x = x + speed: y = y + speed: amount = amount - 1
  28.     IF direction2 = 2 AND direction = 4 THEN x = x + speed: amount = amount - 1
  29.     IF direction2 = 3 AND direction = 2 THEN y = y + speed: x = x + speed: amount = amount - 1
  30.     IF direction2 = 3 AND direction = 4 THEN y = y + speed: x = x - speed: amount = amount - 1
  31.     IF direction2 = 3 AND direction = 1 THEN y = y + speed: amount = amount - 1
  32.     IF direction2 = 4 AND direction = 1 THEN x = x - speed: y = y - speed: amount = amount - 1
  33.     IF direction2 = 4 AND direction = 3 THEN x = x - speed: y = y + speed: amount = amount - 1
  34.     IF direction2 = 4 AND direction = 2 THEN x = x - speed: amount = amount - 1
  35.     IF direction = 1 AND direction2 = 1 THEN y = y - speed: amount = amount - 1
  36.     IF direction = 2 AND direction2 = 2 THEN x = x + speed: amount = amount - 1
  37.     IF direction = 3 AND direction2 = 3 THEN y = y + speed: amount = amount - 1
  38.     IF direction = 4 AND direction2 = 4 THEN x = x - speed: amount = amount - 1
  39.  
  40.     IF direction2 = 1 AND speed = 0 THEN direction = 1
  41.     IF direction2 = 2 AND speed = 0 THEN direction = 2
  42.     IF direction2 = 3 AND speed = 0 THEN direction = 3
  43.     IF direction2 = 4 AND speed = 0 THEN direction = 4
  44.  
  45.     IF mouseLeftButton THEN speed = speed + 5: amount = 100: mouseLeftButton = 0
  46.     IF amount < 50 AND speed > 0 THEN speed = speed - .25
  47.     IF speed < 0 THEN speed = 0: amount = 0
  48.     IF x > 800 THEN x = 0
  49.     IF x < 0 THEN x = 800
  50.     IF y > 600 THEN y = 0
  51.     IF y < 0 THEN y = 600
  52.  
  53.     IF amount = 0 THEN speed = 0: direction = direction2
  54.  
  55.     'Tank
  56.     FOR sz = .25 TO 5 STEP .25
  57.         CIRCLE (x, y), sz, _RGB32(255, 255, 255)
  58.     NEXT sz
  59.  
  60.     'Gun Turrent
  61.     IF direction2 = 1 THEN LINE (x, y)-(x, y - 15), _RGB32(255, 255, 255)
  62.     IF direction2 = 2 THEN LINE (x, y)-(x + 15, y), _RGB32(255, 255, 255)
  63.     IF direction2 = 3 THEN LINE (x, y)-(x, y + 15), _RGB32(255, 255, 255)
  64.     IF direction2 = 4 THEN LINE (x, y)-(x - 15, y), _RGB32(255, 255, 255)
  65.  
  66.     _DISPLAY
  67.     CLS
  68.  
  69.  
  70.  

« Last Edit: November 02, 2020, 07:14:57 pm by SierraKen »