我对 Python 和 PyGame 还很陌生。我做了一个球和两个桨(两个桨由 2 个玩家控制)。我的问题是当球击中玩家 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();
最佳答案
问题似乎是您将碰撞检测基于球矩形的左上角。左 Racket 对着左侧,所以(不准确但通常)还不错,但是右 Racket 对着右边,所以球矩形的左角只会在玩家 2 的 Racket 内球已经穿透 Racket ,此时,墙壁检测例程(在 Racket 检测之前出现)将触发重置,因为它得分了。
所以玩家 2 的 Racket 变得无关紧要,因为它检测到远角,并且只要检测到碰撞,它就会检测得分,并在测试碰撞之前重置球的位置。
所以,你需要考虑球的整体形状,或者至少让检测点对称。如果你使用中心点,它会很公平,但它也会错过球的边缘。理想情况下,您可以测试 Racket 是否与球的椭圆相交。
关于python - 碰撞检测问题 - PyGame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41971403/