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()

 

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM