简体   繁体   中英

Collisions in python ping pong game

So, im having this trouble with collisions in my pygame Python Ping-pong game. Exactly in that fragment of code

#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

So it is basic computer movement, repeating the y position of ball. But when i implemented AI movement, ball is going through the computer pallete, sometimes bouncing away. How to make it right? I lost my mind tbh.

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()

You have to test against the enemy rectangle. Get the x and y coordinate form the enemy rectangle before the collision test:

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

Simplify the code with chained Comparisons :

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

Or even better pygame.Rect.collidepoint :

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

I recommend reading How do I detect collision in pygame? and Sometimes the ball doesn't bounce off the paddle in pong game .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM