Как заставить мяч подпрыгивать, только если он ударяет по веслу в Python, Pygame (Breakout Recreation)

Кто-нибудь может мне с этим помочь? У меня возникли проблемы при создании простого способа определить, попал ли мяч в лопатку, а затем отскочить от него, изменив переменную rect_change_y. Вот код, который работает, но мяч не взаимодействует с веслом и не умирает, когда попадает на дно игры.

import pygame

black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)

rect_x = 10
rect_y = 250

pad_x = 350
pad_y = 480

ball = 3

rect_change_x = 1
rect_change_y = 1

pad_x_c = 0

pygame.init()

size=[700,500]
screen=pygame.display.set_mode(size)

pygame.mouse.set_visible(0)

pygame.display.set_caption("Breakout Recreation WIP")

done=False

clock=pygame.time.Clock()
# -------- Main Program Loop -----------
while ball != 0:
    # ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENT
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done=True # Flag that we are done so we exit this loop
        keys = pygame.key.get_pressed()  #checking pressed keys
        if keys[pygame.K_LEFT]:
            pad_x_c -= 2
        elif keys[pygame.K_RIGHT]:
            pad_x_c += 2  
        else :
            pad_x_c = 0
    # ALL EVENT PROCESSING SHOULD GO ABOVE THIS COMMENT
    # ALL GAME LOGIC SHOULD GO BELOW THIS COMMENT
    # ALL GAME LOGIC SHOULD GO ABOVE THIS COMMENT
    # ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
    # First, clear the screen to white. Don't put other drawing commands
    # above this, or they will be erased with this command.
    screen.fill(black)
    # Draw the rectangle
    pygame.draw.rect(screen,white,[rect_x,rect_y,15,15])
    pygame.draw.rect(screen,white,[pad_x,pad_y,50,10])
    # Move the rectangle starting point
    rect_x += rect_change_x
    rect_y += rect_change_y
    pad_x += pad_x_c
    # Bounce the ball if needed
    if rect_y > 480 or rect_y < 10:
        rect_change_y = rect_change_y * -1
    if rect_x > 680 or rect_x < 5:
        rect_change_x = rect_change_x * -1    
    if pad_x <= 5 :
        pad_x_c = 0
    if pad_x >= 645 :
        pad_x_c = 0
    # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT

    pygame.display.flip()

    clock.tick(100)

pygame.quit ()

и вот код, который должен работать (для меня), но не работает.

import pygame

black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)

rect_x = 10
rect_y = 250

pad_x = 350
pad_y = 480

ball = 3

rect_change_x = 1
rect_change_y = 1

pad_x_c = 0

pygame.init()

size=[700,500]
screen=pygame.display.set_mode(size)

pygame.mouse.set_visible(0)

pygame.display.set_caption("Breakout Recreation WIP")

done=False

clock=pygame.time.Clock()
# -------- Main Program Loop -----------
while ball != 0:
    # ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENT
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done=True # Flag that we are done so we exit this loop
        keys = pygame.key.get_pressed()  #checking pressed keys
        if keys[pygame.K_LEFT]:
            pad_x_c -= 2
        elif keys[pygame.K_RIGHT]:
            pad_x_c += 2  
        else :
            pad_x_c = 0
    # ALL EVENT PROCESSING SHOULD GO ABOVE THIS COMMENT
    # ALL GAME LOGIC SHOULD GO BELOW THIS COMMENT
    # ALL GAME LOGIC SHOULD GO ABOVE THIS COMMENT
    # ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
    # First, clear the screen to white. Don't put other drawing commands
    # above this, or they will be erased with this command.
    screen.fill(black)
    # Draw the rectangle
    pygame.draw.rect(screen,white,[rect_x,rect_y,15,15])
    pygame.draw.rect(screen,white,[pad_x,pad_y,50,10])
    # Move the rectangle starting point
    rect_x += rect_change_x
    rect_y += rect_change_y
    pad_x += pad_x_c
    # Bounce the ball if needed
    if rect_y == pad_y:
        if rect_x == pad_x:
            rect_change_y = rect_change_y * -1
    if rect_y > 490:
        ball -= 1
        rect_y = 250
        rect_x = 10
        rect_change_x = 1
        rect_change_y = 1
    if rect_y < 10:
        rect_change_y = rect_change_y * -1
    if rect_x > 680 or rect_x < 5:
        rect_change_x = rect_change_x * -1       
    if pad_x <= 5 :
        pad_x_c = 0
    if pad_x >= 645 :
        pad_x_c = 0
    # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT

    pygame.display.flip()

    clock.tick(100)

pygame.quit ()

наконец, какие-либо предложения о том, как сделать блоки и сделать с ними то же самое, кроме уничтожения их вместо мяча?

Спасибо всем!

1 ответ

Решение

Вы можете использовать Rect класс для представления мяча и весла, а также для использования методов, предоставляемых этим классом:

  • Rect.move_ip чтобы переместить прямоугольники на место:

    myrect = pygame.Rect(0, 0, 10, 10)
    myrect.move_ip(100, 50)
    

    Мой верхний левый угол находится в точке (100, 50) и имеет одинаковую ширину и высоту.

  • Rect.clamp_ip чтобы убедиться, что прямоугольники находятся внутри экрана.

    myrect = pygame.Rect(100, 0, 10, 10)
    bounds = pygame.Rect(0, 0, 50, 50)
    myrect.clamp_ip(bounds)
    

    Мой верхний левый угол находится в (40, 0), а его нижний правый угол - в (10, 50), внутри прямоугольника границ.

  • Rect.colliderect проверить, сталкиваются ли шар и весло.

    myrect = pygame.Rect(0, 0, 10, 10)
    another = pygame.Rect(5, 5, 10, 10)
    print(myrect.colliderect(another)) # 1
    

    Так как myrect и еще одно совпадение, когда вы звоните colliderect он возвращает 1, что указывает на столкновение между двумя прямоугольниками.


Мне действительно нравится Pygame, поэтому я не против переписать вашу программу, используя эти предложения. Надеюсь, поможет:

import pygame

# Constants
WIDTH = 700
HEIGHT = 500
SCREEN_AREA = pygame.Rect(0, 0, WIDTH, HEIGHT)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

# Initialization
pygame.init()
screen = pygame.display.set_mode([WIDTH, HEIGHT])
pygame.mouse.set_visible(0)
pygame.display.set_caption("Breakout Recreation WIP")
clock = pygame.time.Clock()

# Variables
paddle = pygame.Rect(350, 480, 50, 10)
ball = pygame.Rect(10, 250, 15, 15)
paddle_movement_x = 0
ball_direction = (1, 1)
balls = 3
done = False

while not done and balls > 0:

    # Process events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            paddle_movement_x = -2
        elif keys[pygame.K_RIGHT]:
            paddle_movement_x = 2
        else:
            paddle_movement_x = 0

    # Move paddle
    paddle.move_ip(paddle_movement_x, 0)
    paddle.clamp_ip(SCREEN_AREA)

    # Move ball
    ball.move_ip(*ball_direction)
    if ball.right > WIDTH or ball.left < 0:
        ball_direction = -ball_direction[0], ball_direction[1]
    elif ball.top < 0 or ball.bottom > HEIGHT or paddle.colliderect(ball):
        ball_direction = ball_direction[0], -ball_direction[1]
    ball.clamp_ip(SCREEN_AREA)

    # Redraw screen
    screen.fill(BLACK)
    pygame.draw.rect(screen, WHITE, paddle)
    pygame.draw.rect(screen, WHITE, ball)
    pygame.display.flip()
    clock.tick(100)

pygame.quit()
Другие вопросы по тегам