【问题标题】:Verify Pong collision logic on pygame在 pygame 上验证 Pong 碰撞逻辑
【发布时间】: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] &lt;= y &lt;= p2_range[1]: 没有像上面那样使用y_adjusted 的原因是什么?
  • 或者,您是否设置了一个比碰撞区域更大的区域的标准,然后记录位置和速度,而在那个更大的区域(接近碰撞)它可能会让您感觉可能会发生什么正在发生 - 这可能是一个时间问题,一个 step 它已接近下一步它仍然接近但在另一边。也许碰撞区域需要针对速度进行调整/缩放。物体以离散的步骤移动 - 速度/时间 - 数字而非模拟。

标签: python pygame collision-detection pong


【解决方案1】:

我可以通过使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多