【发布时间】:2020-08-14 13:09:04
【问题描述】:
我正在尝试使用 Pygame 在 Python 上编写乒乓球游戏。奇怪的是,游戏运行良好,球在边缘反弹,使用空间重生,桨移动(向上/向下箭头和 i/k 键)而不离开屏幕。大多数情况下,球会与桨发生碰撞,但有时球会出现奇怪的动作或瞬移。
我认为问题可能与碰撞逻辑有关。这就是我要分享的内容,如果您想要更多内容,请点击下面的链接。
P1 和 P2 代表桨。基本上我检查 x 是否在桨附近,然后检查 y 是否在桨范围内(从 topPaddleY 到 bottomPaddleY) 有关更多代码,我将与 codeskulptor3 共享它。 https://py3.codeskulptor.org/#user305_Voqctw5Vzh_0.py
class Ball:
def __init__(self, radius, center, color):
self.radius = radius
self.initial_attributes = center
self.center = list(center)
self.color = color
self.vel = [random.choice(VELOCITIES), random.choice(VELOCITIES)]
def draw(self):
pygame.draw.circle(screen, self.color, tuple(self.center), self.radius )
def update(self, p1, p2):
x = self.center[0]
y = self.center[1]
y_adjusted = (y+self.radius, y-self.radius)
if y_adjusted[0] >= HEIGHT or y_adjusted[1] <= 0:
self.vel[1] = -self.vel[1]
if x <= 28 or x >= WIDTH - 28:
p1_range = [p1.pos[1], p1.pos[1] + 100]
if p1_range[0] <= y <= p1_range[1]:
self.vel[0] = (-self.vel[0])
p2_range = [p2.pos[1], p2.pos[1] + 100]
if p2_range[0] <= y <= p2_range[1]:
self.vel[0] = (-self.vel[0])
def move(self, p1, p2):
self.center[0] = self.center[0] + self.vel[0]
self.center[1] = self.center[1] + self.vel[1]
self.update(p1, p2)
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
self.spawn()
def spawn(self):
self.center = list(self.initial_attributes)
self.vel = [random.choice(VELOCITIES), random.choice(VELOCITIES)]
编辑:我可以通过按照建议使用 y_adjusted + 添加打印语句来检查碰撞期间球的位置来修复它。在碰撞过程中速度似乎不止一次改变所以我添加了一个反射标志。现在看来进展顺利。谢谢。
def update(self, p1, p2):
x = self.center[0]
y = self.center[1]
y_adjusted = (y+self.radius, y-self.radius)
reflected = False
if y_adjusted[0] >= HEIGHT or y_adjusted[1] <= 0:
self.vel[1] = -self.vel[1]
if x <= 28 or x >= WIDTH - 28:
p1_range = [p1.pos[1], p1.pos[1] + 100]
if ((p1_range[0] <= y_adjusted[0] <= p1_range[1]) or (p1_range[0] <= y_adjusted[1] <= p1_range[1])) and (not(reflected)):
self.vel[0] = (-self.vel[0])
reflected = True
p2_range = [p2.pos[1], p2.pos[1] + 100]
if ((p2_range[0] <= y_adjusted[0] <= p2_range[1]) or (p2_range[0] <= y_adjusted[1] <= p2_range[1])) and (not(reflected)):
self.vel[0] = (-self.vel[0])
reflected = True
else :
reflected = False
【问题讨论】:
-
我没有检查您代码中的错误,但强烈建议使用 pygames 自己的碰撞检测方法。
-
欢迎来到 SO。正如您所写的那样,您的问题感觉有点宽泛。这不是论坛。您应该尽可能将示例缩减为minimal reproducible example。请阅读How to Ask 和该页面上的其他链接。当满足碰撞标准时,您是否尝试过触发事件并在屏幕上显示 flag?您是否尝试过同时减慢物体的速度?
-
if p2_range[0] <= y <= p2_range[1]:没有像上面那样使用y_adjusted的原因是什么? -
或者,您是否设置了一个比碰撞区域更大的区域的标准,然后记录位置和速度,而在那个更大的区域(接近碰撞)它可能会让您感觉可能会发生什么正在发生 - 这可能是一个时间问题,一个 step 它已接近下一步它仍然接近但在另一边。也许碰撞区域需要针对速度进行调整/缩放。物体以离散的步骤移动 - 速度/时间 - 数字而非模拟。
标签: python pygame collision-detection pong