pygame中的碰撞检测

 

1.两个精灵之间的矩形检测

import pygame
import random

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
RED   = (255,   0,   0)

class Block(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        super().__init__()

        self.image = pygame.Surface([width, height])
        self.image.fill(color)
        self.rect = self.image.get_rect()

pygame.init()
b=pygame.mouse.set_visible(False)
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
sprite_list = pygame.sprite.Group()
block = Block(BLACK, 50, 50)
block.rect.x = random.randint(50,screen_width-50)
block.rect.y = random.randint(50,screen_height-50)
player = Block(RED, 50, 50)
sprite_list.add(block)
sprite_list.add(player)

done = False
clock = pygame.time.Clock()
i=0

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    screen.fill(WHITE)
    pos = pygame.mouse.get_pos()
    player.rect.x = pos[0]
    player.rect.y = pos[1]

    #b = pygame.sprite.collide_rect(block, player)  #两个精灵之间的矩形碰撞检测
    #如果碰撞返回True

    b = pygame.sprite.collide_rect_ratio(0.9)(block, player)  #两个精灵之间的矩形碰撞检测
    #两个精灵的矩形面积相互重叠达到10%就返回True
    if b:
        print(i,'两个精灵碰撞了')
    else:
        print(i,'两个精灵没有碰撞')

    sprite_list.draw(screen)
    pygame.display.flip()
    i+=1
    clock.tick(2)

pygame.quit()

2.两个精灵之间的圆检测

import pygame
import random

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
RED   = (255,   0,   0)

class Block(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        super().__init__()

        self.image = pygame.Surface([width, height])
        self.image.fill(color)
        self.rect = self.image.get_rect()

pygame.init()
b=pygame.mouse.set_visible(False)
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
sprite_list = pygame.sprite.Group()
block = Block(BLACK, 50, 50)
block.rect.x = random.randint(50,screen_width-50)
block.rect.y = random.randint(50,screen_height-50)
player = Block(RED, 50, 50)
sprite_list.add(block)
sprite_list.add(player)

done = False
clock = pygame.time.Clock()
i=0

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    screen.fill(WHITE)
    pos = pygame.mouse.get_pos()
    player.rect.x = pos[0]
    player.rect.y = pos[1]

    #b = pygame.sprite.collide_circle(block, player)  #两个精灵之间的圆形碰撞检测
    #【以矩形的对角线为直径形成检测圆,相碰就返回真】

    b = pygame.sprite.collide_rect_ratio(0.9)(block, player)  #两个精灵之间的圆形碰撞检测
    # 【以矩形的对角线为直径形成检测圆,相碰就返回真】
    # 两个精灵的圆形面积相互重叠达到10%就返回True
    if b:
        print(i,'两个精灵碰撞了')
    else:
        print(i,'两个精灵没有碰撞')

    sprite_list.draw(screen)
    pygame.display.flip()
    i+=1
    clock.tick(2)

pygame.quit()

3.两个精灵的精准碰撞检测

import pygame,os
pygame.init()

os.environ['SDL_VIDEO_WINDOW_POS']="%d,%d"%(1400,100)  #窗口自定义坐标
screen = pygame.display.set_mode((400,400))
pygame.display.set_caption("碰撞")
clock = pygame.time.Clock()
i=0

class Block(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height]).convert_alpha()
        self.image.set_colorkey((0, 0, 0))  # 设置透明色
        pygame.draw.rect(self.image, color, (10,10,width//2,height//2))
        self.rect = self.image.get_rect()
        self.mask= pygame.mask.from_surface(self.image)  #给精灵添加一个mask属性


zu = pygame.sprite.Group()

b1=Block((0,0,255),50,50)
b1.rect.x=10
b1.rect.y=200
zu.add(b1)

p1=Block((255,0,0),50,50)
p1.rect.x=20
p1.rect.y=50
zu.add(p1)



while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_DOWN:
            p1.rect.y +=10

        if event.key == pygame.K_UP:
            p1.rect.y -= 10

    b = pygame.sprite.collide_mask(p1,b1)  #两个精灵的mask碰撞检测--精准检测
    #参数:两个精灵
    #返回值:碰撞区域的左上角坐标
    #
    print(i,b)
    screen.fill((255,255,255))
    zu.draw(screen)

    i+=1
    clock.tick(4)
    pygame.display.update()

4.精灵和组之间的冲突检测 

import pygame
pygame.init()

screen = pygame.display.set_mode((400,400))
pygame.display.set_caption("碰撞")
clock = pygame.time.Clock()
i=0

class Block(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height]).convert_alpha()
        self.image.set_colorkey((0, 0, 0))  # 设置透明色
        pygame.draw.rect(self.image, color, (0,0,width//2,height//2))
        self.rect = self.image.get_rect()
        self.mask= pygame.mask.from_surface(self.image)  #给精灵添加一个mask属性


zu = pygame.sprite.Group()
zu1=pygame.sprite.Group()

b1=Block((0,0,255),50,50)
b1.rect.x=10
b1.rect.y=10
zu.add(b1)
b2=Block((0,255,0),50,50)
b2.rect.x=200
b2.rect.y=200
zu.add(b2)
b3=Block((255,255,0),50,50)
b3.rect.x=220
b3.rect.y=190
zu.add(b3)


p=Block((255,0,0),50,50)
p.rect.x=200
p.rect.y=200
zu1.add(p)


while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    screen.fill((255,255,255))
    pos = pygame.mouse.get_pos()
    p.rect.x = pos[0]
    p.rect.y = pos[1]

    #b = pygame.sprite.spritecollide(p, zu,False)  #精灵和组之间的矩形碰撞检测
    #参数1就是单个精灵
    #参数2是精灵组
    #第三个参数是一个bool值。当为True的时候,碰撞后会删除组中所有冲突的精灵(把精灵踢出组),False的时候不会删除冲突的精灵
    #返回值:列表  返回组中被碰撞的精灵
    #[<Block sprite(in 1 groups)>, <Block sprite(in 1 groups)>]


    #b = pygame.sprite.spritecollideany(p, zu, False)  #精灵和组之间的矩形碰撞检测
    # 参数1就是单个精灵
    # 参数2是精灵组
    # 参数3是一个bool值。当为True的时候,碰撞后会删除组中所有冲突的精灵(把精灵踢出组),False的时候不会删除冲突的精灵
    # 返回值:布尔值  是否有碰撞

    b = pygame.sprite.spritecollide(p, zu, False,pygame.sprite.collide_mask)  #精灵和组之间精准碰撞检测
    ##参数1就是单个精灵
    #参数2是精灵组
    #参数3:是一个bool值。当为True的时候,碰撞后会删除组中所有冲突的精灵(把精灵踢出组),False的时候不会删除冲突的精灵
    #参数4:用精灵的mask进行碰撞检测(透明区域不在碰撞检测范围内)--必须给精灵添加mask属性
    #返回值:列表  返回组中被碰撞的精灵
    #[<Block sprite(in 1 groups)>, <Block sprite(in 1 groups)>]


    print(i, b)

    if b:
        print(i,'两个精灵碰撞了')
    else:
        print(i,'两个精灵没有碰撞')


    zu.draw(screen)
    zu1.draw(screen)

    i+=1
    clock.tick(2)
    pygame.display.update()

5.精灵组之间的冲突检测 

import pygame
pygame.init()

screen = pygame.display.set_mode((400,400))
pygame.display.set_caption("碰撞")
clock = pygame.time.Clock()
i=0

class Block(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height]).convert_alpha()
        self.image.set_colorkey((0, 0, 0))  # 设置透明色
        pygame.draw.rect(self.image, color, (10,10,width//2,height//2))
        self.rect = self.image.get_rect()
        self.mask= pygame.mask.from_surface(self.image)  #给精灵添加一个mask属性


zu = pygame.sprite.Group()
zu1=pygame.sprite.Group()

b1=Block((0,0,255),50,50)
b1.rect.x=10
b1.rect.y=200
zu.add(b1)
b2=Block((0,255,0),50,50)
b2.rect.x=200
b2.rect.y=200
zu.add(b2)
b3=Block((255,255,0),50,50)
b3.rect.x=220
b3.rect.y=190
zu.add(b3)


p1=Block((255,0,0),50,50)
p1.rect.x=20
p1.rect.y=50
zu1.add(p1)

p2=Block((255,0,0),50,50)
p2.rect.x=210
p2.rect.y=20
zu1.add(p2)


while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_DOWN:
            p1.rect.y +=10
            p2.rect.y += 10
        if event.key == pygame.K_UP:
            p1.rect.y -= 10
            p2.rect.y -= 10

    #b=pygame.sprite.groupcollide(zu1, zu, False, False)   #精灵组之间的矩形冲突检测
    #参数1:组1
    #参数2:组2
    #参数3:发生碰撞时,组1中碰撞的精灵是否踢出组
    #参数4:发生碰撞时,组2中碰撞的精灵是否踢出组
    #返回值-字典:键是组1中碰撞的精灵,值是组1中的碰撞精灵与组2中发生碰撞的精灵列表
    #{<Block sprite(in 1 groups)>: [<Block sprite(in 1 groups)>], <Block sprite(in 1 groups)>: [<Block sprite(in 1 groups)>, <Block sprite(in 1 groups)>]}

    b = pygame.sprite.groupcollide(zu1, zu, False, False,pygame.sprite.collide_mask)  #精灵组之间的精准碰撞检测
    # 参数1:组1
    # 参数2:组2
    # 参数3:发生碰撞时,组1中碰撞的精灵是否踢出组
    # 参数4:发生碰撞时,组2中碰撞的精灵是否踢出组
    #参数5:用精灵的mask进行碰撞检测(透明区域不在碰撞检测范围内)--必须给精灵添加mask属性
    # 返回值-字典:键是组1中碰撞的精灵,值是组1中的碰撞精灵与组2中发生碰撞的精灵列表
    # {<Block sprite(in 1 groups)>: [<Block sprite(in 1 groups)>], <Block sprite(in 1 groups)>: [<Block sprite(in 1 groups)>, <Block sprite(in 1 groups)>]}

    print(i,b)
    screen.fill((255,255,255))
    zu.draw(screen)
    zu1.draw(screen)

    i+=1
    clock.tick(4)
    pygame.display.update()

6.两个图像的精准检测

看:https://www.cnblogs.com/liming19680104/p/13272989.html    实例2

原文地址:https://www.cnblogs.com/liming19680104/p/13266344.html