Pygame:如何设置旋转正方形的边界?

2024-06-17 09:31:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个旋转的正方形在屏幕上移动,我的任务是(1)设置边界,使其保持在屏幕内,(2)使用类似的旋转正方形进行碰撞检测。我在第一个问题上需要帮助

顺便告诉我的老师(如果你正在读这篇文章的话),我已经研究这个具体问题6个多小时了,必须求助于其他人的帮助。有些问题可以承受持续思考的冲击,失败不是延迟成功——它只是失败,技能不是99%的努力+1%的天赋——而是相反,等等

注意:很抱歉格式不好。这是我第一次使用堆栈溢出;我在用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

Tags: recteventsizegetifscreensatpygame
1条回答
网友
1楼 · 发布于 2024-06-17 09:31:40

旋转矩形的轴对齐宽度和高度大于原始重新调整矩形的大小。 旋转矩形的边界存储在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

我建议在主应用程序循环的末尾绘制矩形(和整个)场景。因此,矩形的当前位置是可视化的,而不是移动前的位置:

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)

对于两个旋转矩形的碰撞,我建议使用^{}对象和^{}^{}^{}

进一步参见:
Collision between masks in pygame
How can I made a collision mask?
Pygame mask collision

相关问题 更多 >