碰撞检测问题 - PyGame

时间:2017-02-01 03:27:26

标签: python pygame collision-detection collision

我对Python和PyGame很陌生。我做了一个球和两个桨(两个桨由两个球员控制)。我的问题是当球击中球员2的球拍时,它不会反弹。问题出现在代码的底部,其中有一条评论说:#WITH PLAYER 2

# 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 个答案:

答案 0 :(得分:0)

问题似乎是你在球的矩形的左上角进行碰撞检测。左侧桨叶靠在左侧,因此(不准确但通常)不那么差,但右侧桨叶靠近右侧,因此球形矩形的左角仅在球员2的桨叶内部时球已经穿过桨,此时,墙检测程序(在桨检测之前)将触发重置,因为它得分。

所以玩家2的球拍是无关紧要的,因为它会检测到远角,并且只要它发现碰撞,它就会检测到一个分数并在测试碰撞之前重置球的位置。

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