Pygame: Как мне установить границы для вращающегося квадрата? - PullRequest
1 голос
/ 08 апреля 2020

У меня есть вращающийся квадрат, который перемещается по экрану, и мне поручено (1) установить границы, чтобы держать его внутри экрана, и (2) обнаружение столкновений с аналогичным вращающимся квадратом. Мне нужна помощь с первым вопросом.

PS Моему учителю (если вы читаете это) я уже более 6 часов занимаюсь этой конкретной проблемой c и должен обратиться за помощью к другим. Некоторые проблемы могут выдержать нападение на устойчивое мышление, неудача - это не задержка успеха - это просто неудача, умение - это не 99% усилий + 1% таланта - это наоборот, и т. Д. c. и др c.

Примечание. Извините за плохое форматирование. Я впервые использую Stack Overflow; Раньше я использовал Y! A, но в разделе программирования там не так много людей

import pygame 
import random

pygame.init()  # Initialize py-game
screen = pygame.display.set_mode((800, 500))  # Create screen
color = (255, 240, 245)

# Initial Coordinates
objectX, objectY = random.randint(100, 700), random.randint(100, 400)

fps = pygame.time.Clock()
velocity = [8, 6]  # speed
velocity2 = [6, 8]
size = 0  # size
drag = False

# Rotating the object
sat_orig = pygame.Surface((70, 70))
sat_orig.set_colorkey((0, 0, 0))
sat_orig.fill(color)
sat = sat_orig.copy()
sat.set_colorkey((0, 0, 0))
rect = sat.get_rect()
rect.center = (800 // 2, 500 // 2)
rotation = 0
rotation_speed = 2


# --------------------------------------------------------------------------


running = True
while running:  # Game Loop

    screen.fill((0, 0, 0))
    pygame.display.set_caption('Collision Interactions ' + str(pygame.mouse.get_pos()))  # caption

    # exit button
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                drag = False
                rotation_speed = 2

        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                drag = True
                rotation_speed = 0

    size = 70

    old_center = rect.center
    rotation = (rotation + rotation_speed) % 360
    new_image = pygame.transform.rotate(sat_orig, rotation)
    rect = new_image.get_rect()
    rect.center = old_center
    screen.blit(new_image, (objectX, objectY))
    objectArea = rect

    ############
    # Movement #
    ############
    if drag:  # Manual
        if objectArea.collidepoint(event.pos):
            objectX, objectY = pygame.mouse.get_pos()
            objectX -= size // 2
            objectY -= size // 2
    else:  # Automatic
        objectX += velocity[0]
        objectY += velocity[1]

        ##############
        # Boundaries #
        ##############
        if objectX + size > 800 or objectX + size < 0:
            velocity[0] = -velocity[0]
        if objectY + size > 500 or objectY + size < 0:
            velocity[1] = -velocity[1]

    fps.tick(80)

    pygame.display.update()  # Displays updates

1 Ответ

0 голосов
/ 08 апреля 2020

Выровненная по оси ширина и высота повернутого прямоугольника больше, чем размер исходного рециркуляции. Границы повернутого прямоугольника хранятся в objectArea. Используйте повернутый прямоугольник для теста на столкновение:

while running:  # Game Loop
    # [...]

    if drag:  # Manual
        # [...]

    else:  # Automatic

        objectX += velocity[0]
        objectY += velocity[1]

        # set new location of rotated rectangle
        objectArea.topleft = (objectX, objectY)

        # bounce on bounds
        if objectArea.right > 800 or objectArea.left < 0:
            velocity[0] = -velocity[0]
        if objectArea.bottom > 500 or objectArea.top < 0:
            velocity[1] = -velocity[1]#

Обратите внимание, поскольку перемещение прямоугольника больше 1, оно может немного превысить границу. Чтобы предотвратить подгонку прямоугольника к границам:

while running:  # Game Loop
    # [...]

    if drag:  # Manual
        # [...]

        objectX += velocity[0]
        objectY += velocity[1]
        objectArea.topleft = (objectX, objectY)

        if objectArea.left < 0:
            velocity[0] *= -1
            objectX = 0
        elif objectArea.right > screen.get_width():
            velocity[0] *= -1
            objectX = screen.get_width() - objectArea.width 

        if objectArea.top < 0:
            velocity[1] *= -1
            objectY = 0
        elif objectArea.bottom > screen.get_height():
            velocity[1] *= -1
            objectY = screen.get_height() - objectArea.height

Я рекомендую нарисовать прямоугольную (и всю) сцену в конце основного приложения l oop. Таким образом, отображается текущая позиция прямоугольника, а не позиция перед движением:

while running:

    # handle the events
    for event in pygame.event.get():
        # [...]


    # do all the computations
    # [...]

    # draw the scene
    screen.fill((0, 0, 0))
    screen.blit(new_image, (objectX, objectY))
    pygame.display.update()  # Displays updates
    fps.tick(80)

Полный пример:

import pygame 
import random

pygame.init()  # Initialize py-game
screen = pygame.display.set_mode((800, 500))  # Create screen
color = (255, 240, 245)

# Initial Coordinates
objectX, objectY = random.randint(100, screen.get_width()-100), random.randint(100, screen.get_height()-100)

fps = pygame.time.Clock()
velocity = [8, 6]  # speed
velocity2 = [6, 8]
size = 0  # size
drag = False

# Rotating the object
sat_orig = pygame.Surface((70, 70))
sat_orig.set_colorkey((0, 0, 0))
sat_orig.fill(color)
sat = sat_orig.copy()
sat.set_colorkey((0, 0, 0))
rect = sat.get_rect()
rect.center = (screen.get_width() // 2, screen.get_height() // 2)
rotation = 0
rotation_speed = 2


# --------------------------------------------------------------------------

pygame.display.set_caption('Collision Interactions ' + str(pygame.mouse.get_pos()))  # caption

running = True
while running:  # Game Loop

    # exit button
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                drag = False
                rotation_speed = 2

        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                drag = True
                rotation_speed = 0

    size = 70
    old_center = rect.center
    rotation = (rotation + rotation_speed) % 360
    new_image = pygame.transform.rotate(sat_orig, rotation)
    rect = new_image.get_rect()
    rect.center = old_center
    objectArea = rect

    ############
    # Movement #
    ############
    if drag:  # Manual
        if objectArea.collidepoint(event.pos):
            objectX, objectY = pygame.mouse.get_pos()
            objectX -= size // 2
            objectY -= size // 2
    else:  # Automatic

        objectX += velocity[0]
        objectY += velocity[1]
        objectArea.topleft = (objectX, objectY)

        if objectArea.left < 0:
            velocity[0] *= -1
            objectX = 0
        elif objectArea.right > screen.get_width():
            velocity[0] *= -1
            objectX = screen.get_width() - objectArea.width 

        if objectArea.top < 0:
            velocity[1] *= -1
            objectY = 0
        elif objectArea.bottom > screen.get_height():
            velocity[1] *= -1
            objectY = screen.get_height() - objectArea.height 

    screen.fill((0, 0, 0))
    screen.blit(new_image, (objectX, objectY))
    pygame.display.update()  # Displays updates
    fps.tick(80)

Для столкновения 2 повернутых прямоугольников я рекомендую использовать pygame.mask.Mask объектов и pygame.mask.Mask.overlap() или pygame.sprite.Sprite и pygame.sprite.collide_mask().

См. Далее:
Столкновение масок в пигаме
Как создать маску столкновения?
Пигамей маска столкновения

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