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

0 Members and 1 Guest are viewing this topic.

FellippeHeitor

  • Guest
Re: b+ Asteroids makeover
« Reply #15 on: October 30, 2020, 03:32:02 pm »
Very fun to play, bplus!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: b+ Asteroids makeover
« Reply #16 on: October 30, 2020, 04:23:27 pm »
AWESOME Explosions! I also really like your physics on the broken up asteroids, great job! The keys are a bit awkward for me though, I can use the mouse buttons and the W and Z keys, but is there any other keys? All of the Asteroids games I've ever played lets you rotate your ship in both directions to fire. But of course different is good too if you like this better. But you are doing an amazing job, better artist than I am on everything. :)

Ken, check out eRATication 5 here is copy:
https://www.qb64.org/forum/index.php?topic=3164.msg124309#msg124309

The mouse/cheese wedge points in the direction you move the mouse, so the bullets are always headed the same direction you move the mouse. I would go with this method except! the point is so wobbly! too wobbly for any good aim and shoot even machine gun style. Try hitting the smaller rats.

I have not found a way to get rid of the wobbly, plus you have to move the point towards the thing you want to shoot at.

I am kind of liking the shooter here, flip the gun left and right, you know exactly where you're pointing when you shoot.

PS I don't recommend w, z I just put it there for... that WASDZ guy ;-))  I should do the other directions too.

Big fan of left hand space bar = fire!, right hand mouse = flipping gun with mouse buttons and driving the ship.
« Last Edit: October 30, 2020, 04:50:20 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: b+ Asteroids makeover
« Reply #17 on: October 30, 2020, 04:29:54 pm »
Very fun to play, bplus!

Good! that's what I am going for :)

Fun to blow up things. Say, should we try more little rocks?

Oh I was going to work out a points system: Highest Points for smallest, darkest, fastest rocks. Next to no points for giant, light, slow moving elephant like rocks.

And of course we have to invite some aliens over for war games ;-))
« Last Edit: October 30, 2020, 04:31:34 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: b+ Asteroids makeover
« Reply #18 on: October 30, 2020, 04:40:42 pm »
LOL I just tried your eRATication, I see your point about turning too fast. One thing you can try is instead of turning by the movement of your mouse, you can turn by turning your mouse wheel. One direction would go one way and the other direction could go another way. I'm sure you could figure it out. If you need help, get mine or your old clock codes and see how the second hand turns around the clock. If you want. :)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: b+ Asteroids makeover
« Reply #19 on: October 30, 2020, 04:47:05 pm »
LOL I just tried your eRATication, I see your point about turning too fast. One thing you can try is instead of turning by the movement of your mouse, you can turn by turning your mouse wheel. One direction would go one way and the other direction could go another way. I'm sure you could figure it out. If you need help, get mine or your old clock codes and see how the second hand turns around the clock. If you want. :)

Oh yeah, let's try that! We can keep Left and Right guns and use wheel to fine tune.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: b+ Asteroids makeover
« Reply #20 on: October 30, 2020, 06:13:21 pm »
w is up, z is down.

Now should it be a / d for left and right and leave s for shooting

or

leave space bar alone for shooting and use a / s for left and right?

I am unfamiliar with this system.

The _MOUSEWHEEL works great! Using pi/8 increments so you have all 90 and 45 degree angles covered plus one in between.

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: b+ Asteroids makeover
« Reply #21 on: October 30, 2020, 06:23:20 pm »
Sweet! I can't wait to play it. If you want to use the regular WASD keys, they are W = up, S = down, A = left, D = right. Z is really hard on the hands to use on a regular keyboard. X is OK for down if you want to use that, but the farther away the keys, the harder it is. I would use WASD.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: b+ Asteroids makeover
« Reply #22 on: October 30, 2020, 07:06:39 pm »
Oh thanks, guess I was off!

Here Ken, this block is all that's changed at moment:
Code: QB64: [Select]
  1.             WHILE _MOUSEINPUT
  2.                 ship.a = ship.a + _MOUSEWHEEL * pi / 8 ' 22.5  degree changes, Thank Ken for this :)
  3.             WEND 'update ship
  4.             ship.x = _MOUSEX: ship.y = _MOUSEY
  5.             IF _MOUSEBUTTON(1) THEN ship.a = pi 'this is new left and right guns
  6.             IF _MOUSEBUTTON(2) THEN ship.a = 0
  7.             IF _KEYDOWN(ASC("w")) THEN ship.a = 1.5 * pi ' well it works but ??
  8.             IF _KEYDOWN(ASC("a")) THEN ship.a = pi
  9.             IF _KEYDOWN(ASC("s")) THEN ship.a = .5 * pi
  10.             IF _KEYDOWN(ASC("d")) THEN ship.a = 0
  11.  
« Last Edit: October 30, 2020, 07:12:06 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: b+ Asteroids makeover
« Reply #23 on: October 30, 2020, 07:44:43 pm »
LOL I love it! When you are ready to add sound, I would use small .mp3 explosion sounds, since QB64 can't access Windows drumset midi sounds, I wish it could, unless it's a library to access?
And like you said, another set of even smaller asteroids to shoot would be cool too, and the alien ship. :D This is coming out really good. It's like the old 90's games that added Windows behavior to 80's arcade games.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: b+ Asteroids makeover
« Reply #24 on: October 30, 2020, 11:18:03 pm »
OK here are some more changes for today, more rocks potentially when hit a big one, Point system, increase level of difficulty, get stoned ending (speaking literally of course!).

Code: QB64: [Select]
  1. _TITLE "b+ Asteroids m3" '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 smaller 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.  
  14. '================================================================================================================
  15.  
  16. '    NOTE: !!!!!!!!!!!!!!!   When there is a pause in action, just hit any key to reset next life.
  17.  
  18. '================================================================================================================
  19.  
  20. CONST xmax = 1200, ymax = 700, pi = _PI, polyAngle = _PI / 6, nRocks = 300, nBullets = 2000, bSpeed = 15
  21.  
  22. TYPE particle
  23.     x AS LONG
  24.     y AS LONG
  25.     dx AS SINGLE
  26.     dy AS SINGLE
  27.     size AS SINGLE
  28.     kolor AS _UNSIGNED LONG
  29.  
  30. TYPE bullet
  31.     x AS LONG
  32.     y AS LONG
  33.     dx AS SINGLE
  34.     dy AS SINGLE
  35.     live AS LONG
  36.  
  37. TYPE shipType
  38.     x AS LONG
  39.     y AS LONG
  40.     live AS LONG
  41.     a AS SINGLE '   rotated position usu gun left or right (mouse button), maybe up press w or down press z
  42.  
  43. TYPE rock
  44.     x AS LONG
  45.     y AS LONG
  46.     r AS LONG '            radius
  47.     ra AS SINGLE '         rotation position   a = a + spin
  48.     heading AS SINGLE '    heading from which dx, dy are calc with speed
  49.     speed AS SINGLE '      speed
  50.     spin AS SINGLE '       rotation direction and amount
  51.     seed AS LONG '         for drawing rocks with RND USING
  52.     c AS LONG '            color   rgb(c, c, c)
  53.     live AS LONG '         need this to track rocks still active like bullets
  54.     explodeFrame AS LONG ' after a rock is hit by bullet, it explodes and in more than one frame
  55.  
  56. DIM SHARED dots(2000) AS particle
  57. DIM SHARED b(nBullets) AS bullet
  58. DIM SHARED ship AS shipType
  59. DIM SHARED r(nRocks) AS rock
  60. DIM SHARED lives&, points&, rocks& 'rocks is the minimum number of parent rocks to have on screen  automatic replace when hit or out of bounds
  61. DIM i AS LONG, bullets AS LONG, fire AS LONG, stars&, fnt&, fnt2&, s$, hits&, t, lastt, r AS LONG, newRockN AS LONG, maxBabyRocks AS LONG, br AS LONG
  62.  
  63. SCREEN _NEWIMAGE(xmax, ymax, 32)
  64. _SCREENMOVE 100, 20
  65.  
  66. stars& = _LOADIMAGE("stars.png", 32)
  67. fnt& = _LOADFONT("ARLRDBD.ttf", 16, "MONOSPACE")
  68. fnt2& = _LOADFONT("ARLRDBD.ttf", 40, "MONOSPACE")
  69. _FONT fnt&
  70. COLOR &HFF00FFFF, &H00000000
  71. rocks& = 6 ' always active rocks
  72. lives& = 5
  73.  
  74. WHILE lives& > 0 AND _KEYDOWN(27) = 0 ' init start restart
  75.     FOR i = 1 TO nRocks 'reset rocks mainly clear baby rocks
  76.         newRock (i)
  77.         IF i > rocks& THEN r(i).live = 0
  78.     NEXT
  79.     ship.x = xmax / 2 'avoids explosions top left corner at start, dang still get some!
  80.     ship.y = ymax / 2
  81.     ship.live = 1
  82.     WHILE ship.live AND _KEYDOWN(27) = 0
  83.         'draw everything then process bullets
  84.         _PUTIMAGE , stars&
  85.         _FONT fnt&
  86.         s$ = "Lives:" + STR$(lives&) + "  Hits:" + STR$(hits&) + "  Bullets:" + STR$(bullets) + "  Shooting:" + STR$(INT(hits& * 100 / bullets)) + "%"
  87.         _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 - 20), s$
  88.         _FONT fnt2&
  89.         s$ = STR$(points&)
  90.         _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2), s$
  91.         FOR i = 1 TO nRocks
  92.             IF r(i).live THEN drawRock i ' while drawing rocks the ship could be blown up
  93.         NEXT
  94.         FOR i = 1 TO nRocks 'smoke up the place with rock debris fields still flying out from hit frames ago
  95.             IF r(i).explodeFrame THEN
  96.                 r(i).explodeFrame = r(i).explodeFrame + 1
  97.                 IF r(i).explodeFrame > .5 * r(i).r THEN
  98.                     r(i).explodeFrame = 0
  99.                     IF i <= rocks& THEN newRock i ' now replace the rock
  100.                 ELSE
  101.                     explode r(i).x, r(i).y, r(i).r, r(i).explodeFrame
  102.                 END IF
  103.             END IF
  104.         NEXT
  105.         IF ship.live THEN
  106.             drawship
  107.  
  108.             WHILE _MOUSEINPUT
  109.                 ship.a = ship.a + _MOUSEWHEEL * pi / 8 ' 22.5  degree changes, Thank Ken for this :)
  110.             WEND 'update ship
  111.             ship.x = _MOUSEX: ship.y = _MOUSEY
  112.             IF _MOUSEBUTTON(1) THEN ship.a = pi 'this is new left and right guns
  113.             IF _MOUSEBUTTON(2) THEN ship.a = 0
  114.             IF _KEYDOWN(ASC("w")) THEN ship.a = 1.5 * pi ' well it works but ??
  115.             IF _KEYDOWN(ASC("a")) THEN ship.a = pi
  116.             IF _KEYDOWN(ASC("s")) THEN ship.a = .5 * pi
  117.             IF _KEYDOWN(ASC("d")) THEN ship.a = 0
  118.             fire = 0
  119.             IF _KEYDOWN(32) THEN 'fire bullets
  120.                 t = TIMER(.01)
  121.                 IF lastt = 0 OR t - lastt > .2 THEN fire = 1: lastt = t
  122.             END IF
  123.             FOR i = 0 TO nBullets 'handle bullets
  124.                 IF b(i).live = 0 AND fire = 1 THEN 'have inactive bullet to use
  125.                     b(i).x = ship.x + bSpeed * COS(ship.a)
  126.                     b(i).y = ship.y + bSpeed * SIN(ship.a)
  127.                     b(i).dx = bSpeed * COS(ship.a)
  128.                     b(i).dy = bSpeed * SIN(ship.a)
  129.                     b(i).live = -1
  130.                     bullets = bullets + 1
  131.                     fire = 0
  132.                 END IF
  133.                 IF b(i).live THEN 'new location
  134.                     b(i).x = b(i).x + b(i).dx
  135.                     b(i).y = b(i).y + b(i).dy
  136.                     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
  137.                         FOR r = 1 TO nRocks 'check for collision with rock
  138.                             IF r(r).live THEN
  139.                                 IF SQR((r(r).x - b(i).x) ^ 2 + (r(r).y - b(i).y) ^ 2) < r(r).r THEN 'its a hit!
  140.                                     r(r).explodeFrame = 1 'linger with explosion
  141.                                     r(r).live = 0
  142.                                     hits& = hits& + 1
  143.                                     points& = points& + ((r(r).speed - 2) * 33.3333 + (50 - (r(r).c - 10)) * 2 + (90 - (r(r).r - 10)) * 1.1111) / 3
  144.                                     IF r(r).r > 30 THEN '       split rock  into ? new ones
  145.                                         maxBabyRocks = INT((r(r).r - 10) / 10)
  146.                                         maxBabyRocks = irnd&(2, maxBabyRocks) ' pick a number of baby Rocks
  147.                                         FOR br = 1 TO maxBabyRocks
  148.                                             '                        new rock
  149.                                             newRockN = freeRock& '                          get inactive rock number
  150.                                             newRock newRockN '                              new identity and activate
  151.                                             r(newRockN).r = (r(r).r - 10) / maxBabyRocks '  split in equal parts minus 20% mass
  152.                                             r(newRockN).x = r(r).x + irnd&(-30, 30) '       thrown from parent
  153.                                             r(newRockN).y = r(r).y + irnd&(-30, 30)
  154.                                             r(newRockN).c = r(r).c '                   same color as parent
  155.                                             r(newRockN).heading = rrnd(ship.a - .75 * pi, ship.a + .75 * pi)
  156.                                         NEXT
  157.                                     END IF ' big enough to split
  158.                                     b(i).live = 0 'kill bullet
  159.                                 END IF ' hit rock
  160.                             END IF 'rock is there
  161.                         NEXT ' rock
  162.                         IF b(i).live THEN fcirc b(i).x, b(i).y, 3, _RGB32(255, 255, 0) 'draws bullet
  163.                     ELSE
  164.                         b(i).live = 0 'out of bounds
  165.                     END IF ' bullet is in bounds
  166.                 END IF ' bullet live
  167.             NEXT ' bullet
  168.         END IF ' if ship still live
  169.         _DISPLAY
  170.         IF ship.live = 0 THEN SLEEP ELSE _LIMIT 60 ' if ship dies let's rest and regroup  before restart next life
  171.     WEND
  172.     lives& = lives& - 1
  173.     rocks& = rocks& + 1
  174. ship.x = -200: ship.y = -200 'get it out of the way
  175. WHILE rocks& < nRocks
  176.     _PUTIMAGE , stars&
  177.     rocks& = rocks& + 1
  178.     newRock rocks&
  179.     FOR r = 1 TO nRocks
  180.         drawRock r
  181.     NEXT
  182.     _FONT fnt&
  183.     s$ = "Lives:" + STR$(lives&) + "  Hits:" + STR$(hits&) + "  Bullets:" + STR$(bullets) + "  Shooting:" + STR$(INT(hits& * 100 / bullets)) + "%"
  184.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2 - 20), s$
  185.     _FONT fnt2&
  186.     s$ = STR$(points&)
  187.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(s$)) / 2, ymax / 2), s$
  188.     _FONT fnt&
  189.     _DISPLAY
  190.     _LIMIT 30
  191.  
  192. FUNCTION freeRock&
  193.     DIM i AS LONG
  194.     FOR i = rocks& + 1 TO nRocks ' look for inactive rock number
  195.         IF r(i).live = 0 AND r(i).explodeFrame = 0 THEN freeRock& = i: EXIT FUNCTION
  196.     NEXT
  197.  
  198. SUB explode (x AS LONG, y AS LONG, r AS LONG, frm AS LONG)
  199.     DIM maxParticles AS LONG, i AS LONG, rounds AS LONG, loopCount AS LONG
  200.     maxParticles = r * 4
  201.     FOR i = 1 TO r
  202.         NewDot i, x, y, r
  203.     NEXT
  204.     rounds = r
  205.     FOR loopCount = 0 TO frm
  206.         IF _KEYDOWN(27) THEN END
  207.         FOR i = 1 TO rounds
  208.             dots(i).x = dots(i).x + dots(i).dx
  209.             dots(i).y = dots(i).y + dots(i).dy
  210.             fcirc dots(i).x, dots(i).y, dots(i).size, dots(i).kolor
  211.         NEXT
  212.         IF rounds < maxParticles THEN
  213.             FOR i = 1 TO r
  214.                 NewDot (rounds + i), x, y, r
  215.             NEXT
  216.             rounds = rounds + r
  217.         END IF
  218.     NEXT
  219.  
  220. SUB NewDot (i AS LONG, x AS LONG, y AS LONG, r AS LONG)
  221.     DIM angle, rd
  222.     angle = pi * 2 * RND
  223.     rd = RND * 30
  224.     dots(i).x = x + rd * COS(angle)
  225.     dots(i).y = y + rd * SIN(angle)
  226.     dots(i).size = RND * r * .05
  227.     rd = RND 'STxAxTIC recommended for rounder spreads
  228.     dots(i).dx = rd * 10 * (10 - 2 * dots(i).size) * COS(angle)
  229.     dots(i).dy = rd * 10 * (10 - 2 * dots(i).size) * SIN(angle)
  230.     rd = 20 + RND * 70
  231.     dots(i).kolor = _RGBA32(rd, rd, rd, 80)
  232.  
  233. SUB drawship 'simple red iso triangle pointed towards radianAngle
  234.     DIM x1 AS LONG, y1 AS LONG, x2 AS LONG, y2 AS LONG, x3 AS LONG, y3 AS LONG
  235.     'calculate 3 tail points of triangle ship
  236.     x1 = ship.x + 40 * COS(ship.a - pi) '   middle
  237.     y1 = ship.y + 40 * SIN(ship.a - pi) '
  238.     x2 = ship.x + 60 * COS(ship.a + .9 * pi) ' wing
  239.     y2 = ship.y + 60 * SIN(ship.a + .9 * pi)
  240.     x3 = ship.x + 60 * COS(ship.a - .9 * pi) ' other wing
  241.     y3 = ship.y + 60 * SIN(ship.a - .9 * pi)
  242.     ftri ship.x, ship.y, x1, y1, x2, y2, _RGB32(80, 120, 80, 80)
  243.     ftri ship.x, ship.y, x1, y1, x3, y3, _RGB32(60, 100, 60, 80)
  244.     LINE (ship.x, ship.y)-(x1, y1), _RGB32(255, 255, 128)
  245.     LINE (ship.x, ship.y)-(x2, y2), _RGB32(180, 180, 120)
  246.     LINE (ship.x, ship.y)-(x3, y3), _RGB32(180, 180, 120)
  247.  
  248. SUB drawRock (iRock)
  249.     RANDOMIZE USING r(iRock).seed 'this prevents having to save a particular sequence of random number
  250.     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
  251.     DIM x2 AS LONG, y2 AS LONG
  252.     dx = r(iRock).speed * COS(r(iRock).heading)
  253.     dy = r(iRock).speed * SIN(r(iRock).heading) 'update location
  254.     r(iRock).ra = r(iRock).ra + r(iRock).spin
  255.     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
  256.         IF iRock <= rocks& THEN newRock iRock ELSE r(iRock).live = 0
  257.         EXIT SUB ' reassigned get out of here
  258.     ELSE
  259.         r(iRock).x = r(iRock).x + dx
  260.         r(iRock).y = r(iRock).y + dy
  261.     END IF
  262.     IF ((r(iRock).x - ship.x) ^ 2 + (r(iRock).y - ship.y) ^ 2) ^ .5 < r(iRock).r + 30 THEN 'rock collides with ship?
  263.         FOR rad = 1 TO 200
  264.             fcirc ship.x, ship.y, rad, _RGB32(255 - rad, 255 - 2 * rad, 0)
  265.             _DISPLAY
  266.             _LIMIT 300
  267.         NEXT
  268.         ship.live = 0
  269.         IF iRock <= rocks& THEN newRock iRock ELSE r(iRock).live = 0
  270.         EXIT SUB
  271.     END IF
  272.     FOR j = 10 TO 3 STEP -1 '                  rock drawing (see demo program where developed code)
  273.         rRad = .1 * j * r(iRock).r
  274.         leg = rRad * (RND * .7 + .3)
  275.         x0 = r(iRock).x + leg * COS(r(iRock).ra)
  276.         y0 = r(iRock).y + leg * SIN(r(iRock).ra)
  277.         rc = r(iRock).c + 30 * RND - 15
  278.         c~& = _RGB32(rc + 5, rc - 10, rc + 5)
  279.         x1 = x0
  280.         y1 = y0
  281.         xoff = RND * 20 - 10 + r(iRock).x
  282.         yoff = RND * 20 - 10 + r(iRock).y
  283.         FOR i = 1 TO 12
  284.             leg = rRad * (RND * .35 + .65)
  285.             IF i = 12 THEN
  286.                 x2 = x0: y2 = y0
  287.             ELSE
  288.                 x2 = xoff + leg * COS(i * polyAngle + r(iRock).ra)
  289.                 y2 = yoff + leg * SIN(i * polyAngle + r(iRock).ra)
  290.             END IF
  291.             ftri r(iRock).x, r(iRock).y, x1, y1, x2, y2, c~&
  292.             x1 = x2: y1 = y2
  293.         NEXT
  294.     NEXT
  295.  
  296. SUB newRock (iRock)
  297.     DIM side AS LONG
  298.     RANDOMIZE TIMER * RND 'to avoid making twins
  299.     side = irnd&(1, 4) 'bring rock in from one side, need to set heading according to side
  300.     SELECT CASE side
  301.         CASE 1
  302.             r(iRock).x = -10
  303.             r(iRock).y = rrnd(20, ymax - 20)
  304.             r(iRock).heading = 3 * pi / 2 + RND * pi
  305.         CASE 2
  306.             r(iRock).x = xmax + 10
  307.             r(iRock).y = rrnd(20, ymax - 20)
  308.             r(iRock).heading = pi / 2 + RND * pi
  309.         CASE 3
  310.             r(iRock).x = rrnd(20, xmax - 20)
  311.             r(iRock).y = -10
  312.             r(iRock).heading = RND * pi
  313.         CASE 4
  314.             r(iRock).x = rrnd(20, xmax - 20)
  315.             r(iRock).y = ymax + 10
  316.             r(iRock).heading = pi + RND * pi
  317.     END SELECT
  318.     r(iRock).speed = rrnd(2, 5) 'speed, rotation angle, radius, gray coloring, spin, seed, hit for explosion
  319.     r(iRock).ra = RND * 2 * pi
  320.     r(iRock).r = irnd&(30, 100)
  321.     r(iRock).c = irnd&(10, 60)
  322.     r(iRock).spin = rrnd(-pi / 20, pi / 20)
  323.     r(iRock).seed = INT(RND * 64000) - 32000
  324.     r(iRock).explodeFrame = 0
  325.     r(iRock).live = 1
  326.  
  327. FUNCTION irnd& (n1, n2) 'return an integer between 2 numbers
  328.     DIM l%, h%
  329.     IF n1 > n2 THEN l% = n2: h% = n1 ELSE l% = n1: h% = n2
  330.     irnd& = INT(RND * (h% - l% + 1)) + l%
  331.  
  332. FUNCTION rrnd (n1, n2) ' return number (expecting reals =_single, double, _float depending on default / define setup)
  333.     rrnd = (n2 - n1) * RND + n1
  334.  
  335. SUB ftri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  336.     DIM D AS LONG
  337.     STATIC a&
  338.     D = _DEST
  339.     IF a& = 0 THEN a& = _NEWIMAGE(1, 1, 32)
  340.     _DEST a&
  341.     _DONTBLEND a& '  '<<<< new 2019-12-16 fix
  342.     PSET (0, 0), K
  343.     _BLEND a& '<<<< new 2019-12-16 fix
  344.     _DEST D
  345.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  346.  
  347. SUB fcirc (x AS LONG, y AS LONG, R AS LONG, C AS _UNSIGNED LONG) 'vince version
  348.     DIM x0 AS LONG, y0 AS LONG, e AS LONG
  349.     x0 = R: y0 = 0: e = 0
  350.     DO WHILE y0 < x0
  351.         IF e <= 0 THEN
  352.             y0 = y0 + 1
  353.             LINE (x - x0, y + y0)-(x + x0, y + y0), C, BF
  354.             LINE (x - x0, y - y0)-(x + x0, y - y0), C, BF
  355.             e = e + 2 * y0
  356.         ELSE
  357.             LINE (x - y0, y - x0)-(x + y0, y - x0), C, BF
  358.             LINE (x - y0, y + x0)-(x + y0, y + x0), C, BF
  359.             x0 = x0 - 1: e = e - 2 * x0
  360.         END IF
  361.     LOOP
  362.     LINE (x - R, y)-(x + R, y), C, BF
  363.  
« Last Edit: October 30, 2020, 11:54:21 pm by bplus »

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: b+ Asteroids makeover
« Reply #25 on: October 30, 2020, 11:47:49 pm »
Works great! I like the smaller asteroids. I hope others play this too, it's amazing.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: b+ Asteroids makeover
« Reply #26 on: November 01, 2020, 01:04:20 am »
Happy Halloween! The aliens have accepted my invitation to come play war games. One moment they are just another spaceship, the next they are transformed into The Bolder of Death.

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

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: b+ Asteroids makeover
« Reply #27 on: November 01, 2020, 01:29:32 am »
Those last two versions are pretty cool. 'Explosions' were a nice touch... The introduction of the "alien" was a pure touch of deviousness! Space shooters. Ya gotta love 'em... Well done!!
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: b+ Asteroids makeover
« Reply #28 on: November 01, 2020, 11:50:18 am »
What more aliens, and moving through space (for 100% drawn animation)? sure we can do that :)

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: b+ Asteroids makeover
« Reply #29 on: November 01, 2020, 03:15:40 pm »
LOL awesome saucers! It's getting harder too. Is there a way to keep the game moving when the saucer blows up?