Иногда мяч не отскакивает от ракетки в игре в понг. - PullRequest
0 голосов
/ 12 июля 2020

У меня есть простая игра в понг, которая в основном работает хорошо. Но иногда бывает, что мяч не отскакивает от ракетки. Мяч качается и скользит по лопасти, и кажется, что лопасть притягивает мяч магнитным действием, как показано на анимации:

Every time when the rectangle which surrounds the ball, collides the the paddle rectangle, the the direction of the ball is changed:

if ball.colliderect(paddleLeft):
    move_x *=-1
if ball.colliderect(paddleRight):
    move_x *=-1

Что вызывает такое поведение?

Проблема может быть воспроизведена с помощью следующего полного, минимального и поддающегося проверке примера. Положение мяча установлено таким образом, что неправильное поведение возникает сразу же, если не перемещать правую ракетку:

import pygame

pygame.init()
width, height = 600, 400
window = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
radius, move_x, move_y = 10, 3, 3
ball = pygame.Rect(width//2+125, 20, radius*2, radius)
paddleHeight = 80
paddleLeft = pygame.Rect(20, (height-paddleHeight)//2, 10, paddleHeight)
paddleRight = pygame.Rect(width-30, (height-paddleHeight)//2, 10, paddleHeight)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT: run = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_w] and paddleLeft.top > 0: paddleLeft.y -= 5
    if keys[pygame.K_s] and paddleLeft.bottom < height: paddleLeft.y += 5
    if keys[pygame.K_UP] and paddleRight.top > 0: paddleRight.y -= 5
    if keys[pygame.K_DOWN] and paddleRight.bottom < height: paddleRight.y += 5
    ball.x += move_x
    ball.y += move_y
    if ball.left <= 0 or ball.right >= width: move_x *=-1
    if ball.top <= 0 or ball.bottom >= height: move_y *=-1

    if ball.colliderect(paddleLeft): move_x *=-1
    if ball.colliderect(paddleRight): move_x *=-1

    window.fill(0)
    pygame.draw.rect(window, (255, 255, 255), paddleLeft)
    pygame.draw.rect(window, (255, 255, 255), paddleRight)
    pygame.draw.circle(window, (255, 255, 255), ball.center, radius)
    pygame.display.flip()

1 Ответ

2 голосов
/ 12 июля 2020

Поведение происходит, когда мяч попадает в ракетку не спереди, а сверху или снизу. Фактически обнаруживается столкновение между ракеткой и мячом, и направление изменяется. Но мяч проник в ракетку настолько глубоко, что на следующем шаге мяч не может покинуть зону столкновения с ракеткой. Это приводит к тому, что столкновение снова обнаруживается в следующем кадре, и направление мяча снова изменяется. Теперь мяч движется в том же направлении, что и до первого столкновения. Этот процесс продолжается до тех пор, пока мяч не покинет ракетку внизу. Это вызывает зигзагообразное движение вдоль передней стороны лопасти.

There are different solution. One option is not to reverse the direction, but to set the direction to the left when the right paddle is hit a nd to set the direction to the right when the left paddle is hit:

if ball.colliderect(paddleLeft):
    move_x = abs(move_x)
if ball.colliderect(paddleRight):
    move_x = -abs(move_x) 

Another option is to adjust the position to the ball. If the right paddle is hit, the right side of the ball must be placed to the left of the paddle. If the left paddle is hit, then the left side of the ball must be placed to the right of the paddle:

if ball.colliderect(paddleLeft):
    move_x *= -1
    ball.left = paddleLeft.right
if ball.colliderect(paddleRight):
    move_x *= -1
    ball.right = paddleRight.left

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...