2017-02-01 39 views
3

我是Python和PyGame的新手。我制作了一个球和两个桨(两个桨由两名球员控制)。我的问题是当球击中球员2的球时,球没有反弹。问题出在代码底部,其中有一条评论说:#WITH PLAYER 2碰撞检测问题 - PyGame

# IMPORTS 
import pygame, time; 

# INIT PYGAME 
pygame.init(); 

# GLOBALS 
global screen, display_w, display_h; 
global clock, FPS; 
global gameOver; 
global ball, player_1, player_2; 

# ASSIGN GLOBALS 
def assign_globals(): 
    global screen, display_w, display_h; 
    global clock, FPS; 
    global gameOver; 
    global ball, player_1, player_2; 

    display_w = 800; 
    display_h = 600; 
    screen = pygame.display.set_mode((display_w, display_h)); 

    clock = pygame.time.Clock(); 
    FPS = 60; 

    gameOver = False; 

    ball = Ball(); 
    player_1 = Player(); 
    player_1.x = 0; 
    player_1.color = (255, 0, 0); 
    player_2 = Player(); 
    player_2.x = display_w - 15; 
    player_2.color = (0, 255, 0); 

# MAIN 
def main(): 
    assign_globals(); 
    setup(); 
    game_loop(); 
    set_fps(); 

# GAME LOOP 
def game_loop(): 
    global gameOver; 

    while(not gameOver): 
     for event in pygame.event.get(): 
      if(event.type == pygame.QUIT): 
       gameOver = True; 

      if(event.type == pygame.KEYDOWN): 
       # PLAYER 1 
       if(event.key == pygame.K_w): 
        player_1.velY -= 1; 
       if(event.key == pygame.K_s): 
        player_1.velY += 1; 
       # PLAYER 2 
       if(event.key == pygame.K_UP): 
        player_2.velY -= 1; 
       if(event.key == pygame.K_DOWN): 
        player_2.velY += 1; 

      if(event.type == pygame.KEYUP): 
       # PLAYER 1 
       if(event.key == pygame.K_w or event.key == pygame.K_s): 
        player_1.velY = 0; 
       # PLAYER 2 
       if(event.key == pygame.K_UP or event.key == pygame.K_DOWN): 
        player_2.velY = 0; 

     draw(); 
     animate(); 
     collision(); 

# DRAW 
def draw(): 
    global screen; 

    screen.fill((0, 0, 0)); 
    ball.draw(); 
    player_1.draw(); 
    player_2.draw(); 

    pygame.display.update(); 

# ANIMATE 
def animate(): 
    ball.animate(); 
    player_1.animate(); 
    player_2.animate(); 

# COLLISION 
def collision(): 
    ball.collision(); 
    player_1.collision(); 
    player_2.collision(); 

# SETUP 
def setup(): 
    pygame.display.set_caption("Pong"); 

# CLASSES 
class Ball(): 
    def __init__(self, x=0, y=0, w=0, h=0, velX=0, velY=0, color=()): 
     global display_w, display_h; 

     self.x = display_w/2; 
     self.y = display_w/2; 
     self.w = 20; 
     self.h = 20; 
     self.color = (0, 0, 255); 
     self.velX = 0.4; 
     self.velY = 0.4; 

    def reset(self): 
     self.x = display_w/2; 
     self.y = display_w/2; 
     self.velX = 0.4; 
     self.velY = 0.4; 

    def draw(self): 
     global screen; 

     pygame.draw.ellipse(screen, self.color, (self.x, self.y, self.w, self.h)); 

    def animate(self): 
     self.x += self.velX; 
     self.y += self.velY; 

    def collision(self): 
     global display_w, display_h; 

     # WITH WALL 
     if(self.x >= display_w - self.w): 
      self.reset(); 
     if(self.x <= 0): 
      self.reset(); 
     if(self.y >= display_h - self.h): 
      self.velY *= -1; 
     if(self.y <= 0): 
      self.velY *= -1; 

     # WITH PLAYER 1 
     if(self.x <= player_1.x + player_1.w and 
      self.x >= player_1.x and 
      self.y >= player_1.y and 
      self.y <= player_1.y + player_1.h): 
       ball.velX *= -1; 

     # WITH PLAYER 2 
     if(self.x <= player_2.x + player_2.w and 
      self.x >= player_2.x and 
      self.y >= player_2.y and 
      self.y <= player_2.y + player_2.h): 
       ball.velX *= -1; 

class Player(): 
    def __init__(self, x=0, y=0, w=0, h=0, velY=0, color=()): 
     global display_w, display_h; 

     self.w = 15; 
     self.h = 100; 
     self.x = color; 
     self.y = display_h/2 - self.h/2; 
     self.velY = 0; 
     self.color = color; 

    def draw(self): 
     global screen; 

     pygame.draw.rect(screen, self.color, (self.x, self.y, self.w, self.h)); 

    def animate(self): 
     self.y += self.velY; 

    def collision(self): 
     global display_h; 

     # WITH WALL 
     if(self.y + self.h > display_h): 
      self.velY = 0; 
     elif(self.y < 0): 
      self.velY = 0; 


# SET FPS 
def set_fps(): 
    global clock, FPS; 

    clock.tick(FPS); 

# CALL MAIN 
if(__name__ == "__main__"): 
    main(); 

# QUIT 
pygame.quit(); 
quit(); 
+1

在python中,您不必使用';'结束语句,并且即使它被允许,它通常也是不鼓励的。这同样适用于围绕'if'语句中的条件的括号。不要害怕在事件循环中使用'elif',事件只能是一种类型,每次迭代都有一个键。最后,尽量保持你的命名一致,所以你不要对某些变量使用'lowercase_and_underscore',对其他变量使用'camelCase'。这些只是用于使代码在程序员之间更易读的常规约定[(PEP8)](https://www.python.org/dev/peps/pep-0008/)。 –

回答

1

这个问题似乎是,你正在碰撞检测基础上的球的矩形的左上角。左边的桨是靠在左侧,所以这是(不准确,但通常)不是很糟糕,但右侧桨对着右侧,所以球长方形的左侧角将只在球员2的桨内球已经穿透桨,并且在那一点上,壁检测程序(其在桨检测之前出现)将触发重置,因为它得分。

因此,玩家2的桨是无关紧要的,因为它检测到远角,并且任何时候它会检测到碰撞,它会检测到一个分数,并在测试碰撞之前重置球的位置。

所以,你需要考虑到球的整体形状,或至少使检测点对称。如果你使用中锋,这将是公平的,但它也会在球的边缘错过。理想情况下,您可以测试桨是否与球的椭圆相交。