Pygame 如何让球碰撞
Pygame how to let balls collide
我想在 pygame 中制作一个脚本,其中两个球相互飞向,当它们碰撞时它们应该相互弹开,但我不知道该怎么做所以你能帮我吗?
要检测 2 个圆(分别是球)是否发生碰撞,您必须测试 Euclidean distance between the circles center points is less than the sum of the radii. I recommend to use pygame.math.Vector2
/ distance_to()
是否用于计算。
在下文中,1 圆由圆心 (x1, y1) 和半径 r1 定义。第二个圆由 (x2, y2) 和 r2:
定义
v1 = pygame.math.Vector2(x1, y1)
v2 = pygame.math.Vector2(x2, y2)
if v1.distance_to(v2) < r1 + r2:
print("hit")
如果想让圆圈弹跳,就得像台球一样,把圆圈的运动矢量反射到交点的法向量上。使用 pygame.math.Vector2
/ reflect_ip()
or reflect()
计算圆的新方向。
圆圈的运动由 (mx1, my1) 和 (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
最小示例: 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()
这很简单,您只需检查 x 坐标是否与另一个 x 坐标位于同一位置。例如,如果你有一个 x 坐标称为 x,另一个称为 i(两个球都有 2 个 x 坐标)那么你可以只说如果哦,在我说什么之前,这个例子是你的 pygame window 是 500,500。你可以说 if x == 250: x -= 15. 反之亦然。如果我 == 250:我 += 15。你去吧!。显然您需要做一些更改,但这是基本代码,我想您会理解这一点
我想在 pygame 中制作一个脚本,其中两个球相互飞向,当它们碰撞时它们应该相互弹开,但我不知道该怎么做所以你能帮我吗?
要检测 2 个圆(分别是球)是否发生碰撞,您必须测试 Euclidean distance between the circles center points is less than the sum of the radii. I recommend to use pygame.math.Vector2
/ distance_to()
是否用于计算。
在下文中,1 圆由圆心 (x1, y1) 和半径 r1 定义。第二个圆由 (x2, y2) 和 r2:
v1 = pygame.math.Vector2(x1, y1)
v2 = pygame.math.Vector2(x2, y2)
if v1.distance_to(v2) < r1 + r2:
print("hit")
如果想让圆圈弹跳,就得像台球一样,把圆圈的运动矢量反射到交点的法向量上。使用 pygame.math.Vector2
/ reflect_ip()
or reflect()
计算圆的新方向。
圆圈的运动由 (mx1, my1) 和 (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
最小示例:
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()
这很简单,您只需检查 x 坐标是否与另一个 x 坐标位于同一位置。例如,如果你有一个 x 坐标称为 x,另一个称为 i(两个球都有 2 个 x 坐标)那么你可以只说如果哦,在我说什么之前,这个例子是你的 pygame window 是 500,500。你可以说 if x == 250: x -= 15. 反之亦然。如果我 == 250:我 += 15。你去吧!。显然您需要做一些更改,但这是基本代码,我想您会理解这一点