Author Topic: Ball Breaker  (Read 4707 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Ball Breaker
« on: April 04, 2019, 12:33:29 pm »
Code: QB64: [Select]
  1. CONST Blue = &HFF0000FF~& ' _RGB32(0,0,255)
  2. CONST Brown = &HFFA52A2A~& ' _RGB32(165,42,42)
  3. CONST BrickRed = &HFFCB4154~& '_RGB32(203,65,84)
  4. CONST Red = &HFFFF0000~&
  5. CONST SkyBlue = &HFF87CEEB~& ' _RGB32(135,206,235)
  6.  
  7.  
  8. DEFLNG A-Z
  9. WS = _NEWIMAGE(640, 480, 32)
  10.  
  11. TYPE BulletInfo
  12.     valid AS INTEGER
  13.     x AS INTEGER
  14.     y AS INTEGER
  15.  
  16. TYPE BallInfo
  17.     valid AS INTEGER
  18.     originalsize AS INTEGER
  19.     size AS INTEGER
  20.     x AS INTEGER
  21.     y AS INTEGER
  22.     movex AS INTEGER
  23.     movey AS INTEGER
  24.  
  25. DIM SHARED Ball(100) AS BallInfo
  26. DIM SHARED Bullet(100) AS BulletInfo
  27. DIM SHARED GameOver AS LONG
  28. DIM SHARED score
  29.  
  30. CLS , SkyBlue
  31. LINE (0, 479)-(639, 460), Brown, BF
  32. PCOPY 0, 1 'Save as the background
  33. x = 290
  34. ROF = 50
  35. Ammo = 1000
  36.  
  37.     PCOPY 1, 0
  38.     _LIMIT 180
  39.     IF _KEYDOWN(19200) THEN
  40.         x = x - 1
  41.     ELSEIF _KEYDOWN(19712) THEN
  42.         x = x + 1
  43.     END IF
  44.     IF x < 0 THEN x = 0
  45.     IF x > 570 THEN x = 570
  46.     IF _KEYDOWN(27) THEN GameOver = -1
  47.     IF _KEYDOWN(32) THEN Shoot x
  48.  
  49.     GenerateBall
  50.  
  51.     DrawBalls
  52.     DrawPlayer x
  53.     DrawBullets
  54.  
  55.     DrawStatus
  56.     _DISPLAY
  57. LOOP UNTIL GameOver
  58.  
  59.     _LIMIT 30
  60.  
  61. SUB DrawBalls
  62.     FOR i = 1 TO 100
  63.         IF Ball(i).valid THEN
  64.             Ball(i).x = Ball(i).x - Ball(i).movex
  65.             Ball(i).y = Ball(i).y - Ball(i).movey
  66.             IF Ball(i).x < Ball(i).size THEN Ball(i).x = Ball(i).size: Ball(i).movex = -Ball(i).movex
  67.             IF Ball(i).y < -Ball(i).size THEN Ball(i).y = -Ball(i).size: Ball(i).movey = -Ball(i).movey
  68.             IF Ball(i).x > 640 - Ball(i).size THEN Ball(i).x = 640 - Ball(i).size: Ball(i).movex = -Ball(i).movex
  69.             IF Ball(i).y > 460 - Ball(i).size THEN Ball(i).y = 460 - Ball(i).size: Ball(i).movey = -Ball(i).movey
  70.             CircleFill Ball(i).x, Ball(i).y, Ball(i).size, _RGB32(0, 0, 255 - i * 2)
  71.         END IF
  72.     NEXT
  73.  
  74.  
  75. SUB GenerateBall
  76.     STATIC Spawn AS _FLOAT
  77.     IF ExtendedTimer > Spawn + 2 THEN
  78.         Spawn = ExtendedTimer
  79.         FOR i = 1 TO 100
  80.             IF Ball(i).valid = 0 THEN
  81.                 Ball(i).valid = -1
  82.                 Ball(i).x = RND * 640 + 1
  83.                 Ball(i).size = RND * 91 + 10
  84.                 Ball(i).y = -Ball(i).size
  85.                 Ball(i).originalsize = Ball(i).size
  86.                 Ball(i).movey = -RND * 3 + 1
  87.                 Ball(i).movex = 1 - RND * 3
  88.                 EXIT SUB
  89.             END IF
  90.         NEXT
  91.     END IF
  92.  
  93.  
  94. SUB DrawStatus
  95.     _PRINTSTRING (10, 462), "AMMO:" + STR$(Ammo)
  96.     _PRINTSTRING (560, 462), TIME$
  97.     _PRINTSTRING (200, 462), "SCORE:" + STR$(score)
  98.  
  99. SUB DrawPlayer (x)
  100.     FOR x1 = x TO x + 69
  101.         FOR y1 = 445 TO 459
  102.             IF POINT(x1, y1) <> SkyBlue THEN GameOver = -1
  103.         NEXT
  104.     NEXT
  105.     FOR x1 = x + 10 TO x + 59
  106.         FOR y1 = 425 TO 444
  107.             IF POINT(x1, y1) <> SkyBlue THEN GameOver = -1
  108.         NEXT
  109.     NEXT
  110.     FOR x1 = x + 30 TO x + 39
  111.         FOR y1 = 415 TO 424
  112.             IF POINT(x1, y1) <> SkyBlue THEN GameOver = -1
  113.         NEXT
  114.     NEXT
  115.     LINE (x, 445)-STEP(70, 15), Red, BF
  116.     LINE (x + 10, 425)-STEP(50, 20), Red, BF
  117.     LINE (x + 30, 415)-STEP(10, 10), Red, BF
  118.  
  119. SUB DrawBullets
  120.     FOR i = 1 TO 100
  121.         IF Bullet(i).valid THEN
  122.             Bullet(i).y = Bullet(i).y - 1
  123.             IF Bullet(i).y < 0 THEN Bullet(i).valid = 0: _CONTINUE
  124.             P = POINT(Bullet(i).x, Bullet(i).y)
  125.             IF P <> SkyBlue THEN
  126.                 Bullet(i).valid = 0
  127.                 B = (255 - _BLUE32(P)) / 2
  128.                 Ball(B).size = Ball(B).size - 1: score = score + 1
  129.                 IF Ball(B).size < 10 THEN Ball(B).valid = 0: Ammo = Ammo + Ball(B).originalsize
  130.                 _CONTINUE
  131.             END IF
  132.  
  133.             LINE (Bullet(i).x, Bullet(i).y)-STEP(3, 5), BrickRed, BF
  134.         END IF
  135.     NEXT
  136.     IF Ammo = 0 THEN
  137.         FOR i = 1 TO 100
  138.             IF Bullet(i).valid THEN EXIT SUB
  139.         NEXT
  140.         GameOver = -1 'once you're out of bullets and there's none left on the screen, the game is over.
  141.     END IF
  142.  
  143.  
  144. SUB Shoot (x)
  145.     STATIC Delay AS _FLOAT
  146.     IF ExtendedTimer > Delay + ROF / 1000 THEN 'only shoot once every Rate Of Fire
  147.         FOR i = 1 TO 100
  148.             IF Bullet(i).valid = 0 THEN
  149.                 Bullet(i).valid = -1
  150.                 Bullet(i).x = x + 33
  151.                 Bullet(i).y = 410
  152.                 Ammo = Ammo - 1
  153.                 Delay = ExtendedTimer
  154.                 EXIT SUB
  155.             END IF
  156.         NEXT
  157.     END IF
  158.  
  159.  
  160. FUNCTION ExtendedTimer##
  161.     d$ = DATE$
  162.     l = INSTR(d$, "-")
  163.     l1 = INSTR(l + 1, d$, "-")
  164.     m = VAL(LEFT$(d$, l))
  165.     d = VAL(MID$(d$, l + 1))
  166.     y = VAL(MID$(d$, l1 + 1)) - 1970
  167.     FOR i = 1 TO m
  168.         SELECT CASE i 'Add the number of days for each previous month passed
  169.             CASE 1: d = d 'January doestn't have any carry over days.
  170.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  171.             CASE 3: d = d + 28
  172.             CASE 5, 7, 10, 12: d = d + 30
  173.         END SELECT
  174.     NEXT
  175.     FOR i = 1 TO y
  176.         d = d + 365
  177.     NEXT
  178.     FOR i = 2 TO y STEP 4
  179.         IF m > 2 THEN d = d + 1 'add an extra day for leap year every 4 years, starting in 2016
  180.     NEXT
  181.     s~&& = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  182.     ExtendedTimer## = (s~&& + TIMER)
  183.  
  184. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  185.     ' CX = center x coordinate
  186.     ' CY = center y coordinate
  187.     '  R = radius
  188.     '  C = fill color
  189.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  190.     DIM X AS INTEGER, Y AS INTEGER
  191.     Radius = ABS(R)
  192.     RadiusError = -Radius
  193.     X = Radius
  194.     Y = 0
  195.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  196.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  197.     WHILE X > Y
  198.         RadiusError = RadiusError + Y * 2 + 1
  199.         IF RadiusError >= 0 THEN
  200.             IF X <> Y + 1 THEN
  201.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  202.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  203.             END IF
  204.             X = X - 1
  205.             RadiusError = RadiusError - X * 2
  206.         END IF
  207.         Y = Y + 1
  208.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  209.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  210.     WEND
  211.  
  212.  

A little shooter game which I was playing around with making, though it seems a little too difficult with the current settings.  Spawn timer may need to be reduced to create new balls at a slightly slower rate, and ball move speed might need to be decreased a bit to keep the game going, but as it is, it's a nice workable game already -- just not one where you can play for more than a few moments at a time.  :P

Move left/right with the arrow keys.
Shoot with the space bar.
Bullets use Ammo, but each successful hit on a ball shrinks it in size.  Once the ball "pops" and you destroy it, you get the ball's original size back to increase your ammo.
You get hit with a ball and it's game over.
Run out of ammo and it's game over.
You earn 1 point for each bullet which hits the target balls.

And that's it!  :P
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Ball Breaker
« Reply #1 on: April 04, 2019, 12:55:24 pm »
A slightly tweaked version which spawns balls at an ever increasing rate as you play, and in which the player shooter is a little more responsive to movements.

Code: QB64: [Select]
  1. CONST Blue = &HFF0000FF~& ' _RGB32(0,0,255)
  2. CONST Brown = &HFFA52A2A~& ' _RGB32(165,42,42)
  3. CONST BrickRed = &HFFCB4154~& '_RGB32(203,65,84)
  4. CONST Red = &HFFFF0000~&
  5. CONST SkyBlue = &HFF87CEEB~& ' _RGB32(135,206,235)
  6.  
  7.  
  8. DEFLNG A-Z
  9. WS = _NEWIMAGE(640, 480, 32)
  10.  
  11. TYPE BulletInfo
  12.     valid AS INTEGER
  13.     x AS INTEGER
  14.     y AS INTEGER
  15.  
  16. TYPE BallInfo
  17.     valid AS INTEGER
  18.     originalsize AS INTEGER
  19.     size AS INTEGER
  20.     x AS _FLOAT
  21.     y AS _FLOAT
  22.     movex AS _FLOAT
  23.     movey AS _FLOAT
  24.  
  25. DIM SHARED Ball(100) AS BallInfo
  26. DIM SHARED Bullet(100) AS BulletInfo
  27. DIM SHARED GameOver AS LONG
  28. DIM SHARED score
  29.  
  30. CLS , SkyBlue
  31. LINE (0, 479)-(639, 460), Brown, BF
  32. PCOPY 0, 1 'Save as the background
  33. x = 290
  34. ROF = 50
  35. Ammo = 1000
  36.  
  37.     PCOPY 1, 0
  38.     _LIMIT 180
  39.     IF _KEYDOWN(19200) THEN
  40.         x = x - 3
  41.     ELSEIF _KEYDOWN(19712) THEN
  42.         x = x + 3
  43.     END IF
  44.     IF x < 0 THEN x = 0
  45.     IF x > 570 THEN x = 570
  46.     IF _KEYDOWN(27) THEN GameOver = -1
  47.     IF _KEYDOWN(32) THEN Shoot x
  48.  
  49.     GenerateBall
  50.     DrawBalls
  51.     DrawPlayer x
  52.     DrawBullets
  53.  
  54.     DrawStatus
  55.     _DISPLAY
  56. LOOP UNTIL GameOver
  57.  
  58.     _LIMIT 30
  59.  
  60. SUB DrawBalls
  61.     FOR i = 1 TO 100
  62.         IF Ball(i).valid THEN
  63.             Ball(i).x = Ball(i).x - Ball(i).movex
  64.             Ball(i).y = Ball(i).y - Ball(i).movey
  65.             IF Ball(i).x < Ball(i).size THEN Ball(i).x = Ball(i).size: Ball(i).movex = -Ball(i).movex
  66.             IF Ball(i).y < -Ball(i).size THEN Ball(i).y = -Ball(i).size: Ball(i).movey = -Ball(i).movey
  67.             IF Ball(i).x > 640 - Ball(i).size THEN Ball(i).x = 640 - Ball(i).size: Ball(i).movex = -Ball(i).movex
  68.             IF Ball(i).y > 460 - Ball(i).size THEN Ball(i).y = 460 - Ball(i).size: Ball(i).movey = -Ball(i).movey
  69.             CircleFill Ball(i).x, Ball(i).y, Ball(i).size, _RGB32(0, 0, 255 - i * 2)
  70.         END IF
  71.     NEXT
  72.  
  73.  
  74. SUB GenerateBall
  75.     STATIC Spawn AS _FLOAT
  76.     STATIC StartTime AS _FLOAT
  77.     DIM SpawnTime AS _FLOAT
  78.     IF Spawn = 0 THEN
  79.         StartTime = ExtendedTimer
  80.     END IF
  81.     SELECT CASE ExtendedTimer - StartTime
  82.         CASE IS < 30: SpawnTime = 8
  83.         CASE IS < 60: SpawnTime = 6.5
  84.         CASE IS < 120: SpawnTime = 5
  85.         CASE IS < 300: SpawnTime = 3
  86.         CASE IS < 600: SpawnTime = 2
  87.         CASE ELSE: SpawnTime = 1
  88.     END SELECT
  89.     IF ExtendedTimer > Spawn + SpawnTime THEN
  90.         Spawn = ExtendedTimer
  91.         FOR i = 1 TO 100
  92.             IF Ball(i).valid = 0 THEN
  93.                 Ball(i).valid = -1
  94.                 Ball(i).x = RND * 640 + 1
  95.                 Ball(i).size = RND * 91 + 10
  96.                 Ball(i).y = -Ball(i).size
  97.                 Ball(i).originalsize = Ball(i).size
  98.                 DO
  99.                     Ball(i).movey = -RND * 3 + 1
  100.                 LOOP UNTIL Ball(i).movey <> 0
  101.                 Ball(i).movex = 1 - RND * 3
  102.                 EXIT SUB
  103.             END IF
  104.         NEXT
  105.     END IF
  106.  
  107.  
  108. SUB DrawStatus
  109.     _PRINTSTRING (10, 462), "AMMO:" + STR$(Ammo)
  110.     _PRINTSTRING (560, 462), TIME$
  111.     _PRINTSTRING (200, 462), "SCORE:" + STR$(score)
  112.  
  113. SUB DrawPlayer (x)
  114.     FOR x1 = x TO x + 69
  115.         FOR y1 = 445 TO 459
  116.             IF POINT(x1, y1) <> SkyBlue THEN GameOver = -1
  117.         NEXT
  118.     NEXT
  119.     FOR x1 = x + 10 TO x + 59
  120.         FOR y1 = 425 TO 444
  121.             IF POINT(x1, y1) <> SkyBlue THEN GameOver = -1
  122.         NEXT
  123.     NEXT
  124.     FOR x1 = x + 30 TO x + 39
  125.         FOR y1 = 415 TO 424
  126.             IF POINT(x1, y1) <> SkyBlue THEN GameOver = -1
  127.         NEXT
  128.     NEXT
  129.     LINE (x, 445)-STEP(70, 15), Red, BF
  130.     LINE (x + 10, 425)-STEP(50, 20), Red, BF
  131.     LINE (x + 30, 415)-STEP(10, 10), Red, BF
  132.  
  133. SUB DrawBullets
  134.     FOR i = 1 TO 100
  135.         IF Bullet(i).valid THEN
  136.             Bullet(i).y = Bullet(i).y - 1
  137.             IF Bullet(i).y < 0 THEN Bullet(i).valid = 0: _CONTINUE
  138.             P = POINT(Bullet(i).x, Bullet(i).y)
  139.             IF P <> SkyBlue THEN
  140.                 Bullet(i).valid = 0
  141.                 B = (255 - _BLUE32(P)) / 2
  142.                 Ball(B).size = Ball(B).size - 1: score = score + 1
  143.                 IF Ball(B).size < 10 THEN Ball(B).valid = 0: Ammo = Ammo + Ball(B).originalsize
  144.                 _CONTINUE
  145.             END IF
  146.  
  147.             LINE (Bullet(i).x, Bullet(i).y)-STEP(3, 5), BrickRed, BF
  148.         END IF
  149.     NEXT
  150.     IF Ammo = 0 THEN
  151.         FOR i = 1 TO 100
  152.             IF Bullet(i).valid THEN EXIT SUB
  153.         NEXT
  154.         GameOver = -1 'once you're out of bullets and there's none left on the screen, the game is over.
  155.     END IF
  156.  
  157.  
  158. SUB Shoot (x)
  159.     STATIC Delay AS _FLOAT
  160.     IF ExtendedTimer > Delay + ROF / 1000 THEN 'only shoot once every Rate Of Fire
  161.         FOR i = 1 TO 100
  162.             IF Bullet(i).valid = 0 THEN
  163.                 Bullet(i).valid = -1
  164.                 Bullet(i).x = x + 33
  165.                 Bullet(i).y = 410
  166.                 Ammo = Ammo - 1
  167.                 Delay = ExtendedTimer
  168.                 EXIT SUB
  169.             END IF
  170.         NEXT
  171.     END IF
  172.  
  173.  
  174. FUNCTION ExtendedTimer##
  175.     d$ = DATE$
  176.     l = INSTR(d$, "-")
  177.     l1 = INSTR(l + 1, d$, "-")
  178.     m = VAL(LEFT$(d$, l))
  179.     d = VAL(MID$(d$, l + 1))
  180.     y = VAL(MID$(d$, l1 + 1)) - 1970
  181.     FOR i = 1 TO m
  182.         SELECT CASE i 'Add the number of days for each previous month passed
  183.             CASE 1: d = d 'January doestn't have any carry over days.
  184.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  185.             CASE 3: d = d + 28
  186.             CASE 5, 7, 10, 12: d = d + 30
  187.         END SELECT
  188.     NEXT
  189.     FOR i = 1 TO y
  190.         d = d + 365
  191.     NEXT
  192.     FOR i = 2 TO y STEP 4
  193.         IF m > 2 THEN d = d + 1 'add an extra day for leap year every 4 years, starting in 2016
  194.     NEXT
  195.     s~&& = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  196.     ExtendedTimer## = (s~&& + TIMER)
  197.  
  198. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  199.     ' CX = center x coordinate
  200.     ' CY = center y coordinate
  201.     '  R = radius
  202.     '  C = fill color
  203.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  204.     DIM X AS INTEGER, Y AS INTEGER
  205.     Radius = ABS(R)
  206.     RadiusError = -Radius
  207.     X = Radius
  208.     Y = 0
  209.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  210.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  211.     WHILE X > Y
  212.         RadiusError = RadiusError + Y * 2 + 1
  213.         IF RadiusError >= 0 THEN
  214.             IF X <> Y + 1 THEN
  215.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  216.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  217.             END IF
  218.             X = X - 1
  219.             RadiusError = RadiusError - X * 2
  220.         END IF
  221.         Y = Y + 1
  222.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  223.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  224.     WEND
  225.  
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Ball Breaker
« Reply #2 on: April 04, 2019, 01:14:38 pm »
And that's it!  :P

I hope, for your sake, the name isn't based on your marital experience. If so, I'd recommend LOCATE apostrophe, +2 to the quoted line above.

Hey, nice game! I also liked the scoring. I've always thought more shooting games should incorporate a conservation of ammo instead of games like Defender, where you could just paste the trigger lever down and concentrate all day on just flying and positioning the spaceship. I've considered models where you have a certain amount of ammo per a time period. Run out before the reload time, and you're left dodging opponents until that time elapses. A reload vehicle could even appear on the scene, but if you can't get to it, or it gets destroyed, you have to wait for the next shipment. Although I don't make games anymore, I do get that the best ideas are usually ones that are simple. In other words a bare bones version is still lots of fun to play, you don't need to tweak or add much to have a winner like Pac Man, etc.

Pete

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

Offline qb4ever

  • Newbie
  • Posts: 40
  • LOCATE 15,15: COLOR 14: PRINT "Hello World!"
    • View Profile
Re: Ball Breaker
« Reply #3 on: April 05, 2019, 02:59:37 am »
A slightly tweaked version which spawns balls at an ever increasing rate as you play, and in which the player shooter is a little more responsive to movements.

Great mix between space invaders and breakout.
Very nice idea !
Have a nice day.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Ball Breaker
« Reply #4 on: April 05, 2019, 03:35:27 am »
Nice job! But it is a bit hard to play this game. :D
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Ball Breaker
« Reply #5 on: April 05, 2019, 08:42:04 am »
Reminds of the little game called Pang... Cool...
Logic is the beginning of wisdom.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Ball Breaker
« Reply #6 on: April 05, 2019, 05:35:30 pm »
Yes it remembers to me this one https://www.youtube.com/watch?v=kE-jzDmt1SI called SuperPang

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