在 PyGame 中,可以使用pygame.Rect
对象来完成基本的碰撞检测。该Rect
对象提供了用于检测对象之间碰撞的各种方法。请注意,即使在乒乓球游戏中矩形物体与圆形物体(例如球拍和球)的碰撞也可以通过两个矩形物体(球拍和球的边界矩形)之间的碰撞来粗略检测。
一些例子:
pygame.Rect.collidepoint
:
测试一个点是否在矩形内
repl.it/@Rabbid76/PyGame-collidepoint
import pygame
pygame.init()
window = pygame.display.set_mode((250, 250))
rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(100, 100)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
point = pygame.mouse.get_pos()
collide = rect.collidepoint(point)
color = (255, 0, 0) if collide else (255, 255, 255)
window.fill(0)
pygame.draw.rect(window, color, rect)
pygame.display.flip()
pygame.quit()
exit()
pygame.Rect.colliderect
测试两个矩形是否重叠
另请参阅如何在 pygame 中检测两个矩形对象或图像之间的碰撞
repl.it/@Rabbid76/PyGame-colliderect
import pygame
pygame.init()
window = pygame.display.set_mode((250, 250))
rect1 = pygame.Rect(*window.get_rect().center, 0, 0).inflate(75, 75)
rect2 = pygame.Rect(0, 0, 75, 75)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
rect2.center = pygame.mouse.get_pos()
collide = rect1.colliderect(rect2)
color = (255, 0, 0) if collide else (255, 255, 255)
window.fill(0)
pygame.draw.rect(window, color, rect1)
pygame.draw.rect(window, (0, 255, 0), rect2, 6, 1)
pygame.display.flip()
pygame.quit()
exit()
此外pygame.Rect.collidelist
和pygame.Rect.collidelistall
可用于矩形和矩形列表之间的碰撞测试。pygame.Rect.collidedict
并可pygame.Rect.collidedictall
用于矩形与矩形字典之间的碰撞碰撞测试。
pygame.sprite.Sprite
和对象的碰撞pygame.sprite.Group
,可以通过pygame.sprite.spritecollide()
、pygame.sprite.groupcollide()
或来检测pygame.sprite.spritecollideany()
。使用这些方法时,可以通过collided
参数指定碰撞检测算法:
collided 参数是一个回调函数,用于计算两个精灵是否发生碰撞。
可能collided
的可调用对象是collide_rect
, collide_rect_ratio
, collide_circle
, collide_circle_ratio
,collide_mask
一些例子:
pygame.sprite.spritecollide()
repl.it/@Rabbid76/PyGame-spritecollide
import pygame
pygame.init()
window = pygame.display.set_mode((250, 250))
sprite1 = pygame.sprite.Sprite()
sprite1.image = pygame.Surface((75, 75))
sprite1.image.fill((255, 0, 0))
sprite1.rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(75, 75)
sprite2 = pygame.sprite.Sprite()
sprite2.image = pygame.Surface((75, 75))
sprite2.image.fill((0, 255, 0))
sprite2.rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(75, 75)
all_group = pygame.sprite.Group([sprite2, sprite1])
test_group = pygame.sprite.Group(sprite2)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
sprite1.rect.center = pygame.mouse.get_pos()
collide = pygame.sprite.spritecollide(sprite1, test_group, False)
window.fill(0)
all_group.draw(window)
for s in collide:
pygame.draw.rect(window, (255, 255, 255), s.rect, 5, 1)
pygame.display.flip()
pygame.quit()
exit()
有关与面具的碰撞,请参阅如何制作碰撞面具?或Pygame 蒙版碰撞
另见碰撞和相交
pygame.sprite.spritecollide()
/collide_circle
repl.it/@Rabbid76/PyGame-spritecollidecollidecircle
import pygame
pygame.init()
window = pygame.display.set_mode((250, 250))
sprite1 = pygame.sprite.Sprite()
sprite1.image = pygame.Surface((80, 80), pygame.SRCALPHA)
pygame.draw.circle(sprite1.image, (255, 0, 0), (40, 40), 40)
sprite1.rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(40, 40)
sprite2 = pygame.sprite.Sprite()
sprite2.image = pygame.Surface((80, 89), pygame.SRCALPHA)
pygame.draw.circle(sprite2.image, (0, 255, 0), (40, 40), 40)
sprite2.rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(80, 80)
all_group = pygame.sprite.Group([sprite2, sprite1])
test_group = pygame.sprite.Group(sprite2)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
sprite1.rect.center = pygame.mouse.get_pos()
collide = pygame.sprite.spritecollide(sprite1, test_group, False, pygame.sprite.collide_circle)
window.fill(0)
all_group.draw(window)
for s in collide:
pygame.draw.circle(window, (255, 255, 255), s.rect.center, s.rect.width // 2, 5)
pygame.display.flip()
pygame.quit()
exit()
这对您的代码意味着什么?
pygame.Surface.get_rect.get_rect()
返回一个具有Surface对象大小的矩形,该矩形始终从 (0, 0) 开始,因为Surface对象没有位置。矩形的位置可以由关键字参数指定。例如,可以使用关键字参数指定矩形的中心center
。pygame.Rect
这些关键字参数在返回之前应用于 的属性(请参阅pygame.Rect
关键字参数的完整列表)。
请参阅 *为什么我的碰撞测试总是返回“真”,为什么图像矩形的位置总是错误 (0, 0)?
你根本不需要and的x
andy
属性。改用属性的位置:Sprite
Bullet
rect
#Define the sprite class
class Sprite:
def __init__(self, x, y, name):
self.image = pygame.image.load(name)
self.rect = self.image.get_rect(topleft = (x, y))
def render(self):
window.blit(self.image, self.rect)
# Define the bullet class to create bullets
class Bullet:
def __init__(self, x, y):
self.bullet = pygame.image.load("user_bullet.BMP")
self.rect = self.bullet.get_rect(topleft = (x + 23, y))
def render(self):
window.blit(self.bullet, self.rect)
用于检测和pygame.Rect.colliderect()
的实例之间的冲突。
请参阅如何在 pygame 中检测两个矩形对象或图像之间的碰撞:Sprite
Bullet
my_sprite = Sprite(sx, sy, name)
my_bullet = Bullet(by, by)
while True:
# [...]
if my_sprite.rect.colliderect(my_bullet.rect):
printe("hit")