在 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的xandy属性。改用属性的位置:SpriteBulletrect
#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")