我有一个围绕屏幕移动的旋转方块,任务是(1)设置边界使其保持在屏幕内,以及(2)使用类似的旋转方块进行碰撞检测。我需要第一个问题的帮助。
P.S。对于我的老师(如果您正在阅读),我已经针对这个特定问题进行了6个多小时的讨论,因此必须寻求他人的帮助。某些问题可以承受持续思考的冲击,失败不是成功的延误-仅仅是失败,技能不是99%的努力+ 1%的才能-相反,等等。
注意:很抱歉格式不正确。这是我第一次使用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
答案 0 :(得分:0)
轴对齐的宽度和高度大于旋转矩形的原始高度。
旋转后的矩形的边界存储在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)
对于2个旋转矩形的碰撞,我建议使用pygame.mask.Mask
对象和pygame.mask.Mask.overlap()
或pygame.sprite.Sprite
和pygame.sprite.collide_mask()
。
进一步了解:
Collision between masks in pygame
How can I made a collision mask?
Pygame mask collision