如何让球从球拍上弹起?

0 投票
2 回答
2904 浏览
提问于 2025-04-18 01:38

我正在制作一个简单的乒乓球游戏(底部有一个矩形的挡板,球从屏幕顶部掉下来)。我希望球只有在碰到挡板时才会反弹回去。目前,我已经写了代码让球能在屏幕的上下边缘反弹,但我在让球能从挡板反弹上来这方面遇到了困难。

我需要修改传递给我的测试碰撞方法(test_collide_ball)的参数。如果球的当前x坐标在挡板的范围内,那么球就会反弹回去。

我一直在想解决办法,我的想法是如果球碰到了挡板的y坐标(高度),那么它就会反弹回去。但它还必须在挡板的x坐标范围内(也就是挡板的宽度)。

但是当我这样做时,球就卡在原地了。任何反馈都很受欢迎!提前谢谢大家。

这是我关于球的类和方法的代码:

import pygame

class Ball:
   def __init__(self, x, y, radius, color, dx, dy):
      self.x = x
      self.y = y
      self.radius = radius
      self.color = color
      self.dx = dx
      self.dy = dy

   def draw_ball(self, screen):
      pygame.draw.ellipse(screen, self.color,
         pygame.Rect(self.x, self.y, self.radius, self.radius))

   def update_ball(self):
      self.x += self.dx
      self.y += self.dy

   def test_collide_top_ball(self, top_height):
      if (self.y <= top_height):
         self.dy *= -1

   def test_collide_bottom_ball(self, paddle):
      if (self.y == paddle.y) and (self.x >= paddle.x) and (self.x <= paddle.x + paddle.width):
         self.dy *= -1

2 个回答

0

就像@MrDoomBringer说的,你需要防止球卡在垫子里。

解决这个问题的一个简单方法是检查self.dy是否为正值——也就是说,球是往下移动的。这样你也可以对Y坐标做和X坐标一样的“在里面”的检查。否则,要让球和一个精确的Y坐标发生碰撞是相当困难的,除非你使用了合适的速度等等。

还有一点,如果你有一个球,你很可能想把它的大小考虑进去。这样你可能需要使用一些更复杂的碰撞检测技术,比如这个:http://www.migapro.com/circle-and-rotated-rectangle-collision-detection/

0

看起来发生的事情是,你的球进入了碰撞区域,然后改变了方向。不过,球仍然在碰撞区域内,所以它又改变了一次方向。

你需要关注的是一个叫去抖动检查的东西。简单来说,这段代码可以防止某个事情发生两次或多次(就是去掉重复的效果)。

从你的代码示例来看,球在进入球拍区域时会改变方向。你可以加一个布尔值标志,来判断你是否已经检测到球进入了这个区域。当第一次检测到时,把这个标志设为真。当球移出这个区域时,再把标志设回假。只有当标志为假时,才改变球的方向。

所以,(请原谅我生疏的Python)

def test_collide_bottom_ball(self, paddle):
  if (self.y == paddle.y) and (self.x >= paddle.x) and (self.x <= paddle.x + paddle.width) and (!self.hitPaddle):
     self.dy *= -1
     self.hitPaddle = true
  else
     self.hitPaddle = false

在你的实体中:

self.hitPaddle = false

撰写回答