简体   繁体   中英

Pong in PyGame, Moving paddles causes the ball to stop regenerating when hitting the side

So I am trying to create a simple single player Pong game with pygame. The ball starts and when it hits the wall it will regenerate.... as long as I don't move the paddle. When I move the paddle the ball then just bounces off all the walls and doesn't even take into account if the paddle is there or not. any code to fix this would be greatly appreciated. Thanks!

import sys
import pygame
pygame.init()

size = width, height = 1000, 800
screenColor = 0, 0, 0
outline = 0, 0, 255

paddleOne = pygame.image.load("PONGPADDLE.png")
ball = pygame.image.load("Bullet.png")
ballRect = ball.get_rect()
speed = [1, 1]
paddleOne_x = 980
paddleOne_y = 400

paddleOnePos_x = 0
paddleOnePos_y = 0

screen = pygame.display.set_mode(size)

while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                paddleOnePos_y = -1
            if event.key == pygame.K_DOWN:
                paddleOnePos_y = +1

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                paddleOnePos_y = 0
            if event.key == pygame.K_DOWN:
                paddleOnePos_y = 0

    ballRect = ballRect.move(speed)

    if ballRect.left < 0:
        speed[0] = -speed[0]
    if ballRect.top < 0 or ballRect.bottom > height:
        speed[1] = -speed[1]
    if ballRect.right == 980:
        if ballRect.right > paddleOne_y & ballRect.right < paddleOne_y:
            speed[0] = -speed[0]
        else:
            ballRect = ball.get_rect()

    paddleOne_y += paddleOnePos_y

    screen.fill(screenColor)
    screen.blit(paddleOne, (paddleOne_x, paddleOne_y))
    screen.blit(ball, ballRect)
    pygame.draw.rect(screen, outline, ((0, 0), (width, height)), 5)
    pygame.display.flip()

Okay, so I did some debugging on your code and the reason appears to be this line.

if ballRect.right > paddleOne_y & ballRect.right < paddleOne_y:

I'll copy paste some debugging I did to help explain. I inserted these lines into your code.

if ballRect.right == 980:
    print('ballRect.right > paddleOne_y ' + str(ballRect.right) + '>' + str(paddleOne_y) + str(paddleOne_y & ballRect.right > paddleOne_y))
    print('ballRect.right < paddleOne_y ' + str(ballRect.right) + '<' + str(paddleOne_y) + str(paddleOne_y & ballRect.right < paddleOne_y))
    print(str(paddleOne_y & ballRect.right) + ' paddleOne_y & ballRect.right')
    print('ballRect.right > paddleOne_y & ballRect.right < paddleOne_y')
    print(str(ballRect.right) + '>' + str(paddleOne_y & ballRect.right) + '<' + str(paddleOne_y))
    print()
    if ballRect.right > paddleOne_y & ballRect.right < paddleOne_y:
        speed[0] = -speed[0]
    else:
        ballRect = ball.get_rect()

The following code is what happens when you do NOT move the paddle.

ballRect.right > paddleOne_y 980>400 False
ballRect.right < paddleOne_y 980<400 False
400 paddleOne_y & ballRect.right
ballRect.right > paddleOne_y & ballRect.right < paddleOne_y
980 > 400 < 400

The line if ballRect.right > paddleOne_y & ballRect.right < paddleOne_y: evaluates paddleOne_y & ballRect.right first, and if you dont move the paddle, paddleOne_y = 400 dont ask me why, maybe someone else could help out, but paddleOne_y & ballRect.right if you dont move your paddle evaluates to 980 & 400 which evaluates to 400 I guess. So the reason why it never enters the for loop and bounces is because ballRect.right > paddleOne_y & ballRect.right < paddleOne_y evaluates to 980 > 400 < 400 and 400 is not less than 400. On the flip side, when you move the paddle up for instance you get numbers such as.

ballRect.right > paddleOne_y 980>231 False
ballRect.right < paddleOne_y 980<231 True
196 paddleOne_y & ballRect.right
ballRect.right > paddleOne_y & ballRect.right < paddleOne_y
980 > 196 < 231

If you move the paddle down you get.

ballRect.right > paddleOne_y 980>710 False
ballRect.right < paddleOne_y 980<710 True
708 paddleOne_y & ballRect.right
ballRect.right > paddleOne_y & ballRect.right < paddleOne_y
980 > 708 < 710

As long as the paddle is on screen you the middle number is always in between the other two numbers and therefore it always satisfies the if statement.

I hope that this helps to clarify things. As a side note, you have a very good start on a pong game, I recommend making sure that the paddle is in bounds before you update your paddle movement, other than that great job!

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