Не могу сделать хитбокс для моей пинг-игры в пинг-понг - PullRequest
3 голосов
/ 21 марта 2019

Вот мой сценарий, нужно создать хитбокс, чтобы мяч отскочил от предмета.Это очень простая игра в пинг-понг.Я пробовал с координатами и пробовал смотреть другие видео и форумы, я был бы очень признателен, если бы кто-то мог мне помочь.Я просто не понимаю, это школьное задание.Я ленив, но не мог бы кто-нибудь сделать для меня коробку от столкновений.Или хотя бы помогите мне.

Вот сценарий:

import pygame
pygame.init()

width = 500
height = 400
#pygame.title("Ping Pong Level 1")
screen = pygame.display.set_mode((width, height))
y = 30
g = 30
x = 40
f = 100
velxX = 2
velfF = 2
velX = 50
velF = 20

clock = pygame.time.Clock()


def draw():
    screen.fill((0, 0, 0))
    player = pygame.draw.rect(screen, (255, 255, 255), (30, y, 30, 100))
    player1 = pygame.draw.rect(screen, (255, 255, 255), (440, g, 30, 100))
    line = pygame.draw.rect(screen, (0, 0, 255), (250, 0, 10, 400))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()


    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_w] and y > 0:
        y -= 5
    if pressed[pygame.K_s] and y < height - 100:
        y += 5
    if pressed[pygame.K_UP] and g > 0:
        g -= 5
    if pressed[pygame.K_DOWN] and g < height - 100:
        g += 5


    velF += velfF
    velX += velxX

    if velF < 0 or velF > height - 5:
        velfF *= -1
    if velX < 0 or velX > width - 5:
        velxX *= -1

    pygame.draw.circle(screen, (0, 255, 0), (velX, velF), 5)
    clock.tick(60)
    pygame.display.flip()

    draw()

screen.mainloop()

1 Ответ

3 голосов
/ 21 марта 2019

Хорошо, давайте пройдемся по этому шагу за шагом.

Сначала давайте изменим порядок вашего кода, чтобы у нас был хороший стандартный основной цикл event handling -> state update -> draw.Мы видим, что у вас есть функция draw, но вы не рисуете все в этой функции.Кроме того, вы звоните pygame.display.flip() до draw.screen.mainloop() не имеет смысла, и sys.exit() также не будет работать, потому что вы не импортируете sys.

Шаг 1:

import pygame

def main():
    pygame.init()

    width = 500
    height = 400
    #pygame.title("Ping Pong Level 1")
    screen = pygame.display.set_mode((width, height))
    y = 30
    g = 30
    x = 40
    f = 100
    velxX = 2
    velfF = 2
    velX = 50
    velF = 20

    clock = pygame.time.Clock()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                return

        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_w] and y > 0:
            y -= 5
        if pressed[pygame.K_s] and y < height - 100:
            y += 5
        if pressed[pygame.K_UP] and g > 0:
            g -= 5
        if pressed[pygame.K_DOWN] and g < height - 100:
            g += 5

        velF += velfF
        velX += velxX

        if velF < 0 or velF > height - 5:
            velfF *= -1
        if velX < 0 or velX > width - 5:
            velxX *= -1

        screen.fill((0, 0, 0))
        pygame.draw.circle(screen, (0, 255, 0), (velX, velF), 5)
        player = pygame.draw.rect(screen, (255, 255, 255), (30, y, 30, 100))
        player1 = pygame.draw.rect(screen, (255, 255, 255), (440, g, 30, 100))
        line = pygame.draw.rect(screen, (0, 0, 255), (250, 0, 10, 400))
        pygame.display.flip()

        clock.tick(60)

if __name__ == '__main__':
    main()

Далее,давайте посмотрим на ваше состояние игры и рисунок.У вас есть куча переменных со странными именами и переменные, которые вы не используете или не имеете смысла (например, velxX, f или player1). Вы также рисуете некоторые ректы, так что давайте исправим это с помощьюиспользуя правильные структуры данных: полезные Rect и Vector2 классы.

Шаг 2:

import pygame

def main():
    pygame.init()

    screen = pygame.display.set_mode((500, 400))
    screen_rect = screen.get_rect()

    left_paddle = pygame.Rect((30, 30, 30, 100))
    right_paddle = pygame.Rect((440, 30, 30, 100))

    ball_position = pygame.Vector2((50, 20))
    ball_direction = pygame.Vector2((1, 1)).normalize()
    ball_speed = 5

    clock = pygame.time.Clock()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                return

        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_w]: left_paddle.move_ip(0, -5)
        if pressed[pygame.K_s]: left_paddle.move_ip(0, 5)
        if pressed[pygame.K_UP]: right_paddle.move_ip(0, -5)
        if pressed[pygame.K_DOWN]: right_paddle.move_ip(0, 5)

        # keep paddles on the screen
        left_paddle.clamp_ip(screen_rect)
        right_paddle.clamp_ip(screen_rect)

        ball_position += ball_direction * ball_speed

        # flip direction on edge
        if ball_position[1] < 0 or ball_position[1] > screen_rect.height - 5:
            ball_direction = pygame.Vector2(ball_direction[0], -ball_direction[1])

        if ball_position[0] < 0 or ball_position[0] > screen_rect.width - 5:
            ball_direction = pygame.Vector2(-ball_direction[0], ball_direction[1])

        screen.fill((0, 0, 0))
        pygame.draw.rect(screen, (255, 255, 255), left_paddle)
        pygame.draw.rect(screen, (255, 255, 255), right_paddle)
        pygame.draw.rect(screen, (0, 0, 255), (250, 0, 10, 400))
        pygame.draw.circle(screen, (0, 255, 0), [int(v) for v in ball_position], 5)
        pygame.display.flip()

        clock.tick(60)

if __name__ == '__main__':
    main()

Все идет нормально.Теперь реализовать обнаружение столкновений легко.Мы могли бы рассчитать, где мяч будет на следующем шаге, а затем проверить, не столкнутся ли они с веслом.Поскольку мы используем класс Rect, легко проверить наличие столкновений (collidepoint) и увеличить их (inflate,потому что размер шара больше одного пикселя).

Шаг 3:

import pygame

def main():
    pygame.init()

    screen = pygame.display.set_mode((500, 400))
    screen_rect = screen.get_rect()

    left_paddle = pygame.Rect((30, 30, 30, 100))
    right_paddle = pygame.Rect((440, 30, 30, 100))

    ball_position = pygame.Vector2((150, 120))
    ball_direction = pygame.Vector2((1, 1)).normalize()
    ball_speed = 5

    clock = pygame.time.Clock()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                return

        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_w]: left_paddle.move_ip(0, -5)
        if pressed[pygame.K_s]: left_paddle.move_ip(0, 5)
        if pressed[pygame.K_UP]: right_paddle.move_ip(0, -5)
        if pressed[pygame.K_DOWN]: right_paddle.move_ip(0, 5)

        # keep paddles on the screen
        for paddle in (left_paddle, right_paddle):
            paddle.clamp_ip(screen_rect)

        ball_position += ball_direction * ball_speed

        # flip direction on edge
        if ball_position[1] < 0 or ball_position[1] > screen_rect.height - 5:
            ball_direction = pygame.Vector2(ball_direction[0], -ball_direction[1])

        if ball_position[0] < 0 or ball_position[0] > screen_rect.width - 5:
            ball_direction = pygame.Vector2(-ball_direction[0], ball_direction[1])

        next_ball_position = ball_position + ball_direction * ball_speed
        for paddle in (left_paddle, right_paddle):
            if paddle.inflate(5, 5).collidepoint(next_ball_position):
                ball_direction = pygame.Vector2(-ball_direction[0], ball_direction[1])

        screen.fill((0, 0, 0))
        for paddle in (left_paddle, right_paddle):
            pygame.draw.rect(screen, (255, 255, 255), paddle)
        pygame.draw.rect(screen, (0, 0, 255), (250, 0, 10, 400))
        pygame.draw.circle(screen, (0, 255, 0), [int(v) for v in ball_position], 5)
        pygame.display.flip()

        clock.tick(60)

if __name__ == '__main__':
    main()

enter image description here

Обратите внимание, что это работаеттолько если мяч ударяет по лопатке спереди, но вы можете легко проверить положение шара относительно лопатки, чтобы определить, хотите ли вы изменить направление y или x направления мяча.

И так какмы используем вектор для направления шара, также легко позволить шару двигаться под углами, отличными от 45 °.

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