I want to make a script in pygame where two balls fly towards each other and when they collide they should bounce off from each other but I don't know how to do this so can you help me?
-
4Please post the code you currently have – Mike67 Jul 29 '20 at 02:40
-
1Does this answer your question? [Pygame circle collision?](https://stackoverflow.com/questions/27642234/pygame-circle-collision) – AutMai Jul 29 '20 at 08:24
-
[duplicate] https://stackoverflow.com/questions/27642234/pygame-circle-collision – AutMai Jul 29 '20 at 08:24
-
to compute the redirection after collision (bounce effect) you should check some tutorials that will explain visually how this works. Just found out this one: https://www.youtube.com/watch?v=nlwtgvZCz0k which seems to be short and clear. It's not python but the concepts will be the same – Apolo Jul 29 '20 at 12:49
-
also, you might want to check this community which is more about game dev: https://gamedev.stackexchange.com/ – Apolo Jul 29 '20 at 12:50
2 Answers
To detect if 2 circles (respectively balls) are colliding, you've to test, if the Euclidean distance between the circles center points is less than the sum of the radii. I recommend to use pygame.math.Vector2
/ distance_to()
for the computation.
In the following the 1 circle is defined by the center point (x1, y1) and the radius r1. The 2nd circle is defined by (x2, y2) and r2:
v1 = pygame.math.Vector2(x1, y1)
v2 = pygame.math.Vector2(x2, y2)
if v1.distance_to(v2) < r1 + r2:
print("hit")
If you want to make the circles bounce, you have to reflect the motion vector of the circle at the normal vector of the intersection like a billiard ball. Use pygame.math.Vector2
/ reflect_ip()
or reflect()
to compute the new direction of the circle.
The movements of the circles are given by (mx1, my1) and (mx2, my2):
nv = v2 - v1
m1 = pygame.math.Vector2(mx1, my1).reflect(nv)
m2 = pygame.math.Vector2(mx2, my2).reflect(nv)
mx1, my1 = m1.x, m1.y
mx2, my2 = m2.x, m2.y
Minimal example: repl.it/@Rabbid76/PyGame-CirclesBounceOff
import pygame
pygame.init()
width, height = 400, 400
window = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
x1, y1, r1, mx1, my1 = 200, 200, 50, 2, 0.5
x2, y2, r2, mx2, my2 = 300, 200, 50, -1, -1.5
def move(c, v, r, m):
c += v
if c < r: c, v = r, -v
if c > m-r: c, v = m-r, -v
return c, v
hit_count = 0
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
x1, mx1 = move(x1, mx1, r1, width)
y1, my1 = move(y1, my1, r1, height)
x2, mx2 = move(x2, mx2, r2, width)
y2, my2 = move(y2, my2, r2, height)
v1 = pygame.math.Vector2(x1, y1)
v2 = pygame.math.Vector2(x2, y2)
if v1.distance_to(v2) < r1 + r2 - 2:
hit_count += 1
print("hit:", hit_count)
nv = v2 - v1
m1 = pygame.math.Vector2(mx1, my1).reflect(nv)
m2 = pygame.math.Vector2(mx2, my2).reflect(nv)
mx1, my1 = m1.x, m1.y
mx2, my2 = m2.x, m2.y
window.fill((127, 127, 127))
pygame.draw.circle(window, (255, 0, 0), (round(x1), round(y1)), r1, 4)
pygame.draw.circle(window, (0, 0, 255), (round(x2), round(y2)), r2, 4)
pygame.display.flip()

- 202,892
- 27
- 131
- 174
Its pretty easy you just check if the x coordinate is in the same spot as the other x coordinate. For example if you had one of the x coordinated called x, and another one called i(there are 2 x coordinates for both of the balls) then you could just say if oh and before I say anything esle this example is fi your pygame window is a 500,500. You could say if x == 250: x -= 15. And the other way around for i. If i == 250: i += 15. Ther you go!. Obviously there are a few changes you have to do, but this is the basic code, and I think you would understand this

- 131
- 10