Reputation: 43
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?
Upvotes: -1
Views: 5365
Reputation: 210889
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 have to test many collisions between circles you should compare the square of the distances to avoid the time consuming square root calculation necessary to calculate Euclidean distance. With distance_squared_to()
there is also a function for this:
v1 = pygame.math.Vector2(x1, y1)
v2 = pygame.math.Vector2(x2, y2)
if v1.distance_squared_to(v2) < (r1 + r2)**2:
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()
Upvotes: 6
Reputation: 125
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
Upvotes: -2