• pygame.mask--图形遮罩模块


    用于快速实现完美的碰撞检测,Mask 可以精确到 1 个像素级别的判断

    import pygame
    
    pygame.init()
    screen = pygame.display.set_mode((500, 400))
    pygame.display.set_caption("遮罩")
    
    tu = pygame.image.load('圆红.png').convert()
    tu.set_colorkey((255,255,255))   
    m=pygame.mask.from_surface(tu)  #从指定 Surface 对象中返回一个 Mask
    #返回值:<class 'pygame.mask.Mask'> <Mask(116x113)>
    #透明的部分设置为0,不透明部分设置为 1
    #说明:基于set_colorkey透明的省略参数2
    
    tu1=pygame.image.load('圆蓝.png').convert_alpha()  #基于像素透明
    m1=pygame.mask.from_surface(tu1,127)  #从指定 Surface对象中返回一个 Mask
    #基于像素透明的可以设置参数2(threshold)
    #参数2:检查每个像素的 alpha 值是否大于参数2指定的值。(alpha 通道使用 0 ~ 255 描述像素的透明度)【默认127】
    #【alpha通道小于参数2的为透明,大于参数2的为不透明】
    
    tu2=pygame.image.load('圆红.png').convert_alpha()
    
    x=m.get_size()   #返回Mask 的大小。
    # (116, 113)-> (width,height)
    
    x=m.get_at((50,50))  #返回遮罩中指点坐标的值
    #参数:坐标
    #返回值:0表示透明,1表示不透明
    
    m2=m
    m2.set_at((50,50),0)  #给指定坐标设置值
    #参数1:坐标
    #参数2:值
    
    print(type(x),x)
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
        screen.blit(tu, (0, 0))
        screen.blit(tu1, (300, 0))
        pygame.display.update()
    
    
    import pygame
    pygame.init()
    red = (255,0,0)
    blue = (0,0,255)
    w,h = size = 480,360
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption("遮罩")
    clock = pygame.time.Clock()
    i=0

    # 创建大的圆环
    radius1 = 50
    width1,height1 = 2*radius1,2*radius1
    hollow_circle = pygame.Surface((width1,height1),pygame.SRCALPHA)
    pos = width1//2,height1//2
    rect1 = hollow_circle.get_rect(center=(w//2,h//2))
    pygame.draw.circle(hollow_circle,red,pos,radius1,10)
    mask1 = pygame.mask.from_surface(hollow_circle) #获取圆环的Mask
    # 创建小的实心圆
    radius2 = 10
    width2,height2 = 2 * radius2,2 * radius2
    solid_circle = pygame.Surface((width2,height2),pygame.SRCALPHA)
    pos = width2//2,height2//2
    rect2 = solid_circle.get_rect(center=(w//2,h//2))
    pygame.draw.circle(solid_circle,blue,pos,radius2)
    mask2 = pygame.mask.from_surface(solid_circle)


    while True:
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    exit()
    screen.fill((255,255,255))

    mpos = pygame.mouse.get_pos()
    rect2.center = mpos

    offset = rect2.x - rect1.x, rect2.y - rect1.y
    p = mask1.overlap(mask2, offset) #检测两个Mask有没有碰撞
    #这种检测法图像的透明区域不在碰撞检测范围内
    #没有碰撞返回None,有碰撞返回碰撞的坐标(相对于mask1的坐标)
    #返回值:【mask1中碰撞区域左上角的坐标,而且这个坐标是相对于mask1图像左上角的】
    screen.blit(hollow_circle, rect1)
    screen.blit(solid_circle, rect2)
    print(i,p)
    i+=1
    clock.tick(2)
    pygame.display.update()
     
    import pygame
    pygame.init()
    red = (255,0,0)
    blue = (0,0,255)
    screen = pygame.display.set_mode((480,360))
    pygame.display.set_caption("mask")
    clock = pygame.time.Clock()
    i=0
    
    小红块 = pygame.image.load("小红块.png").convert_alpha()
    小红块rect = 小红块.get_rect()
    测试图 = pygame.image.load("测试图.png").convert_alpha()
    测试图.set_colorkey((0,0,0))
    #设置透明色,透明区域不在mask碰撞检测范围内
    测试图rect = 测试图.get_rect()
    
    测试图rect.x=100
    测试图rect.y=100
    小红块mask = pygame.mask.from_surface(小红块,127)
    测试图mask = pygame.mask.from_surface(测试图,127)
    #透明区域的mask值为0
    
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    小红块rect.x = 小红块rect.x + 10
                if event.key == pygame.K_LEFT:
                    小红块rect.x = 小红块rect.x - 10
                if event.key == pygame.K_UP:
                    小红块rect.top = 小红块rect.top - 10
                if event.key == pygame.K_DOWN:
                    小红块rect.move_ip(0, 10)
        screen.fill((255,255,255))
        offsetX = 小红块rect.x - 测试图rect.x
        offsetY = 小红块rect.y - 测试图rect.y
    
        point = 测试图mask.overlap(小红块mask, (offsetX, offsetY))
        someArea = 测试图mask.overlap_area(小红块mask, (offsetX, offsetY))  #返回两个 Mask 重叠的像素数量
    
        if point:
            px, py = point
            # 借助返回的点,获取返回点的颜色
            pixel1 = 测试图.get_at((px,py))
    
            sx=测试图rect.x+px
            sy = 测试图rect.y + py
            #相对于screen的坐标
    
            cx=sx-小红块rect.x
            cy = sy - 小红块rect.y
    
            pixel2 = 小红块.get_at((cx, cy))
            
    
        else:
            pixel1=1000
            pixel2=2000
    
        print(i,point,someArea,pixel1,pixel2)
        screen.blit(测试图,测试图rect )
        screen.blit(小红块, 小红块rect)
    
        i+=1
        clock.tick(2)
        pygame.display.update()

    测试图:

     小红块:

    mask1.fill()  #将所有的位设置为 1
    mask1.clear()  #将所有的位设置为0
    mask1.invert()  #翻转 Mask 中所有的位(0 变 1,1 变 0)
    mask2=mask1.scale((50,50))   #缩放 Mask 的尺寸
    #Mask 根据指定尺寸缩放后返回一个新的 Mask
    import pygame
    pygame.init()
    
    w,h = size = 480,360
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption("遮罩")
    clock = pygame.time.Clock()
    
    tu1 = pygame.Surface((6,6),pygame.SRCALPHA)
    mask1 = pygame.mask.from_surface(tu1)
    #创建一个全部为0的mask
    
    tu2=pygame.Surface((3,3),pygame.SRCALPHA)
    pygame.draw.rect(tu2, (0,0,255), (0,0,3,3))
    mask2 = pygame.mask.from_surface(tu2)
    
    L1=[]
    for i in range(6):
        for j in range(6):
            p = mask1.get_at((i, j))
            L1.append(p)
    L2=[]
    for i in range(3):
        for j in range(3):
            p = mask2.get_at((i, j))
            L2.append(p)
    mask1.draw(mask2, (2,1))   #将mask2绘制到mask1上边,执行的是按位 or 操作
    #参数2-偏移量:2表示mask2对应于mask1的位置往下走2行(mask1的第3行与mask2的首行对齐)
    #             1表示mask2对应于mask1的位置往右走2列(mask1的第2列与mask2的首列对齐)
    #偏移量的意思:【(mask2的行偏移量,列偏移量)】
    
    L3=[]
    for i in range(6):
        for j in range(6):
            p = mask1.get_at((i, j))
            L3.append(p)
    print('L1')
    print(L1)
    print('L2')
    print(L2)
    print('L3')
    print(L3)
    
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
        screen.fill((255,255,255))
    
        clock.tick(2)
        pygame.display.update()

    意思理解图:

    n=mask1.count()  #返回 Mask 被设置(为 1)的像素的数量
    p=mask1.centroid()  #找到 Mask 的重心点。如果 Mask 是空的,那么返回值是 (0, 0)
    #找到mask中所有设置为1的中心点,如果mask所有值都是0,那就返回(0,0)
    import pygame
    pygame.init()
    
    w,h = size = 200,100
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption("遮罩")
    clock = pygame.time.Clock()
    
    tu1 = pygame.Surface((8,8),pygame.SRCALPHA)
    pygame.draw.rect(tu1, (0,0,255), (1,1,4,4))
    mask1 = pygame.mask.from_surface(tu1)
    
    f=mask1.outline()  #用列表的形式返回组成对象轮廓的点
    #[(1, 1), (2, 1), (3, 1), (4, 1), (4, 2), (4, 3), (4, 4), (3, 4), (2, 4), (1, 4), (1, 3), (1, 2), (1, 1)]
    
    print(f)
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
        screen.fill((255,255,255))
    
        clock.tick(2)
        pygame.display.update()

    理解图:

    import pygame
    pygame.init()
    
    w,h = size = 400,400
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption("遮罩")
    clock = pygame.time.Clock()
    
    tu1 = pygame.Surface((200,200),pygame.SRCALPHA)
    pygame.draw.circle(tu1, (0,0,255), (4,4),3,1)
    pygame.draw.ellipse(tu1, (0,0,255), (20,20,20,10),1)
    mask1 = pygame.mask.from_surface(tu1)
    
    f=mask1.get_bounding_rects()  #返回具有连续1区域矩形列表
    #每个1连续区域形成就形成一个矩形
    #返回值:列表
    #[<rect(1, 1, 7, 6)>, <rect(20, 20, 20, 10)>]
    
    
    print(f)
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
        screen.fill((255,255,255))
    
        clock.tick(2)
        pygame.display.update()

      

  • 相关阅读:
    用循环链表求解约瑟夫问题
    Nim游戏变种——取纽扣游戏
    POJ-2726-Holiday Hotel
    常用排序算法总结(二)
    常用排序算法总结(一)
    找出数组中出现次数最多的那个数——主元素问题
    C99新特性:变长数组(VLA)
    linux tftp配置 (Ubuntu18.04)
    Ubuntu 18.04安装Samba服务器及配置
    记录学习Linux遇到的问题
  • 原文地址:https://www.cnblogs.com/liming19680104/p/13272989.html
Copyright © 2020-2023  润新知