如何限制球拍移动?

1 投票
3 回答
1427 浏览
提问于 2025-04-18 01:39

我想让这个乒乓球游戏里的球拍不能超过游戏窗口的边缘,也就是说球拍不能移动得太远,既不能往右也不能往左。虽然我写了一些代码,确保球拍不会完全移出屏幕,但还是有一部分球拍能移出屏幕。

我该怎么修改我的代码,才能让球拍完全不移出屏幕呢?我的游戏窗口设置为600乘600的大小,我是用update_paddle来移动球拍的。

这是我的球拍类和方法:

import pygame

class Paddle:
   def __init__(self, x, y, c, w, h):
       self.x = x
       self.y = y
       self.color = c
       self.width = w
       self.height = h

   def draw_paddle(self, screen):
      pygame.draw.rect(screen, self.color,
         pygame.Rect(self.x, self.y, self.width, self.height), 0)

   def update_paddle(self, dir, dx):
      if (dir == 'left') and (self.x >= 0):
         self.x = self.x - dx
      elif (dir == 'right') and (self.x + self.width <= 600):
         self.x += dx

   def get_left(self):
      if (self.x < 300):
         return self.x

   def get_right(self):
      if (self.x >= 300):
         return self.x

3 个回答

1

问题在于,你测试的是你是否已经离开了屏幕,而不是测试你在移动后是否会离开屏幕。比如说,如果self.x是1,你向左移动10个像素,按照现在的代码,你最终的位置会是-9,这就已经超出屏幕了。

我建议你直接进行移动,然后再调整位置,确保它在屏幕范围内。

def update_paddle(self, dir, dx):
   if (dir == 'left'): # always move by dx, even if that moves you off the screen
      self.x -= dx
   else: # (dir == 'right')
      self.x += dx

   self.x = min(max(self.x, 0), 600 - self.width) # clamp to screen afterwards

另外,和屏幕边界问题无关,我还建议用负的dx来表示向左移动,而不是使用dir这个参数。函数的第一部分可以简单写成self.x += dx,这样无论是向左还是向右移动都可以用同样的方式处理。

1

你的最终位置需要检查一下,右边的位置是 self.x + self.width / 2,左边的位置是 self.x - self.width / 2。对于上下也是一样,顶部的位置是 self.y - self.height / 2,底部的位置是 self.y + self.height / 2。这些计算都是基于 self.x 和 self.y 是球拍的中心。因为你要确保球拍的中心不会离开屏幕,所以你会发现球拍的边缘在屏幕的边缘,而剩下的部分则会在屏幕外面。

2

我们想要表达的是,挡板的位置(它的左上角)应该放置得当,以确保挡板永远不会离开屏幕。更具体地说:

  • 挡板的左边不能移动得比屏幕的左边缘更左,
  • 挡板的右边也不能移动得比屏幕的右边缘更右。

接下来,我们来看看调整挡板左右位置的方法。只有一个方法,就是 update_paddle(),它有两个不同的路径来处理向左和向右的移动。我们先从左边开始,看看你的代码有什么问题:

if (dir == 'left') and (self.x >= 0):
    self.x = self.x - dx

x 正好为零时,所有的测试都通过了,这样挡板就可以继续向左移动,甚至可能稍微超出屏幕;我们不希望这样,我们希望它完全不离开屏幕。更好的做法是让它移动到屏幕的最左边,但要确保它仍然在屏幕上:

if dir == 'left':
    self.x = max(self.x - dx, 0)

向右移动时也会出现同样的问题:

else:  # LEM: dir == 'right':
   self.x = min(self.x + dx, 600 - self.width)

撰写回答