python 乒乓球比赛中的碰撞

Collisions in python ping pong game

所以,我在 pygame Python 乒乓球游戏中遇到了碰撞问题。就在那段代码中

#computer
    if (x_ball > (x*9) and x_ball < (x*9)+15) and (y_ball < y+55 and y_ball > y-55):
        print(f"col at x={x_ball} y= {y_ball}")
        x_ball = 890
        speed_x*=-1

所以这是基本的电脑运动,重复球的y位置。但是当我实施 AI 运动时,球会通过计算机托盘,有时会弹开。如何做对?我真的疯了。

import pygame
from pygame.constants import DROPTEXT
pygame.init()
#window
w_width = 1000
w_height = 600
screen = pygame.display.set_mode((w_width, w_height))
clock = pygame.time.Clock()
open = True
#player
x,y = 100,250
#define player action variables
speed = 5
speed_x,speed_y = -5,3
moving_down = False
moving_up = False
#define ball action variables
x_ball,y_ball = 500,250
radius = 10
class palette(pygame.sprite.Sprite):
    global x,y

    def __init__(self, x, y, speed):
        self.speed = speed
        pygame.sprite.Sprite.__init__(self)
        self.player_rect = pygame.Rect(x,y,30,100)

    def draw(self):
        pygame.draw.rect(screen, 'White', self.player_rect)

    def move(self, moving_up, moving_down):
        #reset movement variables
        global dy
        dy = 0

        #assing movement variables if moving up or down
        if moving_up:
            dy = -self.speed
        if moving_down:
            dy = self.speed

        #update pallete possition
        self.player_rect.y += dy
class EnemyPalette(pygame.sprite.Sprite):
    global x,y

    def __init__(self, x, y, speed):
        self.speed = speed
        pygame.sprite.Sprite.__init__(self)
        self.enemy_rect = pygame.Rect(x,y,30,100)

    def draw(self):
        pygame.draw.rect(screen, 'White', self.enemy_rect)
    #ai move
    def move(self, speed,x_ball,y_ball):
        self.speed = speed
        self.x_ball = x_ball
        self.y_ball = y_ball
        global dy
        dy = 0
        dy = y_ball-50
        #update enemy pallete possition
        self.enemy_rect.y = dy

def ball():
    global speed_x,speed_y,x_ball,y_ball
    #update pos of bal
    x_ball += speed_x
    y_ball += speed_y
    #basic colision with screen
    y = player.player_rect.y
    x = player.player_rect.x
    #turn off left and right collisions
    # if x_ball>=w_width-(0.5*radius) or x_ball <=0+(0.5*radius):
    #     speed_x*=-1
    if y_ball>=w_height-(0.5*radius) or y_ball <=0+(0.5*radius):
        speed_y*=-1
    #set ball on middle when crosses screen
    if x_ball>=w_width or x_ball<=0:
        x_ball=500
    #collision with pallettes
    #player
    if (x_ball < x+30 and x_ball > x) and (y_ball < y+120 and y_ball > y):
        print(f"left paddle col at x={x_ball} y= {y_ball}")
        x_ball = x+30
        speed_x*=-1
    #computer
    if (x_ball > (x*9) and x_ball < (x*9)+15) and (y_ball < y+55 and y_ball > y-55):
        print(f"right paddle col at x={x_ball} y= {y_ball}")
        x_ball = 890
        speed_x*=-1
    pygame.draw.circle(screen, (255,255,255), (x_ball,y_ball), radius, 5)
    return x_ball,y_ball
#ai movement

#build players and enemies
player = palette(x,y, speed)
enemy = EnemyPalette(x*9,y,speed)
#game
while open:
    for event in pygame.event.get():
        #quit game
        if event.type == pygame.QUIT:
            open = False
        #keyboard presses
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_w:
                moving_up = True
            if event.key == pygame.K_s:
                moving_down = True
            if event.key == pygame.K_ESCAPE:
                open = False
        #keyboard button released
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_w:
                moving_up = False
            if event.key == pygame.K_s:
                moving_down = False
    
    screen.fill((0,0,0))
    clock.tick(60)
    pygame.display.flip

    #init players
    player.draw()
    enemy.draw()
    player.move(moving_up, moving_down)
    enemy.move(speed,x_ball,y_ball)
    ball()

    pygame.display.update()

你必须针对敌人的矩形进行测试。在碰撞测试之前获取敌人矩形的 xy 坐标:

y = enemy.enemy_rect.y
x = enemy.enemy_rect.x
if (x_ball > x and x_ball < x+15) and (y_ball < y+100 and y_ball > y):
    print(f"right paddle col at x={x_ball} y= {y_ball}")
    x_ball = 890
    speed_x*=-1

使用链接Comparisons简化代码:

y = enemy.enemy_rect.y
x = enemy.enemy_rect.x
if x < x_ball < x+15 and y < y_ball < y+100:
    # [...]

甚至更好pygame.Rect.collidepoint:

if enemy.enemy_rect.collidepoint(x_ball, y_ball):
    # [...]

我推荐阅读How do I detect collision in pygame? and