Author Topic: Collision  (Read 1720 times)

0 Members and 1 Guest are viewing this topic.

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
Collision
« on: August 28, 2020, 08:07:18 pm »
I am attempting to convert an old Naalaa Pong game  to QB64 (bplus... stop laughing...) and figured I had best use a decent collision detection routine. I decided to go with AABB as the ball size is quite small.

The following routine works but I would appreciate any advice that would make it more efficient.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3. box1top = 190
  4. box1bottom = 290
  5. box1left = 270
  6. box1right = 370
  7.  
  8.  
  9.     CLS
  10.  
  11.     k = _KEYHIT
  12.  
  13.     LOOP
  14.  
  15.     mx = _MOUSEX
  16.     my = _MOUSEY
  17.  
  18.     box2left = mx - 50
  19.     box2top = my - 50
  20.     box2right = mx + 50
  21.     box2bottom = my + 50
  22.  
  23.     COLOR _RGB32(255, 128, 0)
  24.     LINE (box2left, box2top)-(box2right, box2bottom), , B
  25.  
  26.     IF collide(box1bottom, box1top, box1left, box1right, box2bottom, box2top, box2left, box2right) = 1 THEN
  27.         COLOR _RGB32(255, 255, 0)
  28.         LINE (box1left, box1top)-(box1right, box1bottom), , BF
  29.         COLOR _RGB32(255, 128, 0)
  30.         LINE (box2left, box2top)-(box2right, box2bottom), , BF
  31.     ELSE
  32.         COLOR _RGB32(255, 255, 0)
  33.         LINE (box1left, box1top)-(box1right, box1bottom), , B
  34.         COLOR _RGB32(255, 128, 0)
  35.         LINE (box2left, box2top)-(box2right, box2bottom), , B
  36.     END IF
  37.  
  38.     _DISPLAY
  39. LOOP UNTIL k = 27
  40.  
  41. '====================================================
  42. '
  43. '   Axis Aligned Bounding Box Collision Detection
  44. '
  45. FUNCTION collide (box1bottom, box1top, box1left, box1right, box2bottom, box2top, box2left, box2right)
  46.     IF (box1bottom < box2top) OR (box1top > box2bottom) OR (box1left > box2right) OR (box1right < box2left) THEN
  47.         collide = 0
  48.     ELSE
  49.         collide = 1
  50.     END IF
  51. '====================================================
  52.  

I know. I know. Pong. Why bother? It's not the game per se but to find out if I can successfully convert it...
SDLBasic and RCBasic conversions worked... Now it's QB64's turn... Moo ha ha...
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Collision
« Reply #1 on: August 28, 2020, 09:07:56 pm »
@johnno56

Do you intend a square ball?

Collision routine for round ball should be all that is needed for Ping Pong, should be much simpler. Paddles are usually vertical or horizontal, same with walls so when the ball is less than it's radius away from either, it should be considered collided and sent in the opposite direction.

Your collision for rectangles is excellent and I've still got code (from YOU!) years ago doing nearly same as yours above.

Code: QB64: [Select]
  1. _TITLE "Bounding Box Collision Detection"
  2. ' 2020-03-03 update for Toolbox
  3. ' 2019-08-30 rewrite this so mouse box never gets inside the sides of box for maze study
  4.  
  5. '
  6. '   Collision - Test 1  orig by johnno copied and mod b+ 2018-06-10
  7. '
  8. '   Bounding Box
  9. '
  10. ' 2018-06-10 mod by B+ change for x, y, w, h of images
  11. ' by readjusting all the variables and use STEP for box drawing
  12. ' Generalize the specific gosub routine from this one app so can reuse IN ANY APP using sprites / tiles / images
  13.  
  14. ' 2020-08-28 WTH happened to this code? OH! If collision = 1 not -1 or just If Collision... fixed
  15.  
  16. CONST box1Width = 400, box1Height = 100, box1Left = 400 - box1Width / 2, box1Top = 300 - box1Height / 2 ' center box
  17. CONST mouseboxWidth = 50, mouseboxHeight = 40 ' mouse controled box
  18.  
  19. SCREEN _NEWIMAGE(800, 600, 32) '<<< something more standard center is 400, 300
  20. DIM hey$(5), k$, ombx, omby, mouseBoxX, mouseBoxY, r$, f&, b&, lim
  21. hey$(0) = "Hey!"
  22. hey$(1) = "I beg your pardon."
  23. hey$(2) = "Bang!"
  24. hey$(3) = "Yikes!"
  25. hey$(4) = "Ouch!"
  26. hey$(5) = "Watch where you are going."
  27.     k$ = INKEY$
  28.     WHILE _MOUSEINPUT: WEND '<<< this is all the loop needed for mouse input
  29.     CLS
  30.     LINE (box1Left, box1Top)-STEP(box1Width, box1Height), _RGB32(255, 255, 255), BF
  31.  
  32.     ombx = mouseBoxX: omby = mouseBoxY 'old mouse x, y
  33.  
  34.     mouseBoxX = _MOUSEX - mouseboxWidth / 2
  35.     mouseBoxY = _MOUSEY - mouseboxHeight / 2
  36.  
  37.     IF collision%(box1Left, box1Top, box1Width, box1Height, mouseBoxX, mouseBoxY, mouseboxWidth, mouseboxHeight) THEN
  38.         BEEP
  39.         COLOR _RGB32(100, 0, 85), _RGB32(255, 255, 255)
  40.         r$ = hey$(INT(RND * 6))
  41.         _PRINTSTRING (box1Left + (box1Width - LEN(r$) * 8) / 2, 292), r$
  42.         COLOR f&, b&
  43.         mouseBoxX = ombx: mouseBoxY = omby
  44.         lim = 1
  45.     ELSE
  46.         lim = 200
  47.     END IF
  48.     LINE (mouseBoxX, mouseBoxY)-STEP(mouseboxWidth, mouseboxHeight), _RGB32(255, 128, 0), BF '<<< use step with width and height
  49.     _DISPLAY
  50.     _LIMIT lim '<<< save the fan
  51. LOOP UNTIL k$ = CHR$(27)
  52.  
  53. ' Description:
  54. ' Check for the collison of 2 rectangles given their top left x, y and width, height.
  55. ' Returns true value -1, if they overlap and false 0 if they don't.
  56. FUNCTION collision% (b1x, b1y, b1w, b1h, b2x, b2y, b2w, b2h)
  57.     ' x, y represent the box left most x and top most y
  58.     ' w, h represent the box width and height which is the usual way sprites / tiles / images are described
  59.     ' such that boxbottom = by + bh
  60.     '        and boxright = bx + bw
  61.     'so the specific gosub above is generalized to a function procedure here!
  62.     IF (b1y + b1h < b2y) OR (b1y > b2y + b2h) OR (b1x > b2x + b2w) OR (b1x + b1w < b2x) THEN
  63.         collision% = 0
  64.     ELSE
  65.         collision% = -1 ' Collsion is true
  66.     END IF
  67.  
  68.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Collision
« Reply #2 on: August 28, 2020, 11:01:03 pm »
If you haven't seen Infinite Pong the Movie, here is the trailer:
Code: QB64: [Select]
  1. _TITLE "Infinite Pong the Movie.bas for QB64 B+ 2018-09-16"
  2. p1y = 1: p2y = 25 'paddle y
  3. bx = 30: by = 10: bdx = 2: bdy = 1 'ball x, y, dx, dy
  4.     CLS
  5.     FOR row = 2 TO 24
  6.         LOCATE row, 5: PRINT "|";
  7.         LOCATE row, 75: PRINT "|";
  8.     NEXT
  9.     p1x = bx - 5: _PRINTSTRING (p1x, p1y), "1111111111" ' draw paddle 1
  10.     p2x = bx - 5: _PRINTSTRING (p2x, p2y), "2222222222" ' draw paddle 2
  11.     IF bx + bdx < 6 THEN bdx = bdx * -1 + INT(RND * 3) - 1
  12.     IF bx + bdx > 74 THEN bdx = bdx * -1 + INT(RND * 3) - 1
  13.     IF by + bdy < 2 THEN bdy = bdy * -1: bdx = bdx + INT(RND * 3) - 1
  14.     IF by + bdy > 24 THEN bdy = bdy * -1: bdx = bdx + INT(RND * 3) - 1
  15.     bx = bx + bdx: by = by + bdy
  16.     _PRINTSTRING (bx, by), "O"
  17.     _LIMIT 10
  18.  

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
Re: Collision
« Reply #3 on: August 29, 2020, 02:16:55 am »
Those players have 'amazing' eye and hand co-ordination! lol
Logic is the beginning of wisdom.