首頁 > 軟體

一文詳解pygame.sprite的精靈碰撞

2023-01-24 14:01:34

前言

pygame中的精靈碰撞是可見遊戲中用的最基礎的東西,這裡結合官方檔案和小甲魚的網站上的內容做個小總結,方便日後使用。

pygame.sprite.Sprite - 可見遊戲物件的簡單基礎類別。

Sprite(*groups) -> Sprite

  • pygame.sprite.Sprite.add - 將精靈新增到組中
  • pygame.sprite.Sprite.remove - 從組中刪除精靈
  • pygame.sprite.Sprite.kill - 從所有組中刪除Sprite
  • pygame.sprite.Sprite.alive - 精靈屬於任何組的檢測
  • pygame.sprite.Sprite.groups - 包含此Sprite的組列表
  • pygame.sprite.Sprite.update - 控制精靈行為的方法

pygame.sprite.Group - 用於儲存和管理多個 Sprite 物件的容器類。

Group(*sprites) -> Group

  • pygame.sprite.Group.sprites - 此組包含的 Sprite 列表
  • pygame.sprite.Group.copy - 複製組
  • pygame.sprite.Group.add - 將 Sprite 新增到此組
  • pygame.sprite.Group.remove - 從組中刪除 Sprite
  • pygame.sprite.Group.has - 測試一個 Group 是否包含 Sprite
  • pygame.sprite.Group.update - 在包含的 Sprite 上呼叫 update 方法
  • pygame.sprite.Group.draw - blit Sprite 的影象
  • pygame.sprite.Group.clear - 在 Sprites 上繪製背景
  • pygame.sprite.Group.empty - 刪除所有 Sprite`

上面兩個基礎類別是pygame中最常用,相當輕量級,只為大多數遊戲常見的程式碼提供了一個起始點。

Sprite 類旨在用作遊戲中不同型別物件的基礎類別,為我們碰撞檢測做準備。還有一個基本的 Group 類,它只儲存 sprite 物件, 這樣方便不同型別的精靈進行碰撞檢測, 通常的操作 in / len / bool / iter 都對這個group使用。

in      test if a Sprite is contained
len     the number of Sprites contained
bool    test if any Sprites are contained
iter    iterate through all the Sprites

pygame.sprite.spritecollide() - 在與另一個精靈相交的組中查詢精靈

spritecollide(sprite, group, dokill, collided = None) -> Sprite_list

  • 返回一個sprite列表,其中包含與另一個 Sprite 相交的 Group 中的所有 Sprite 。 通過比較每個 Sprite 的 Sprite.rect 屬性來確定交集。
  • dokill 引數是一個布林值。如果設定為 True,則將從組中刪除所有碰撞的 Sprite 。
  • collided 碰撞引數是一個回撥函數,用於計算兩個精靈是否發生碰撞。 它應該將兩個精靈作為值,並返回一個 bool 值,指示它們是否發生碰撞。 如果未傳遞碰撞,則所有精靈必須具有 rect 值,該值是 sprite 區域的矩形,將用於計算碰撞。

可用的回撥函數

collide_rect, collide_rect_ratio, collide_circle,
collide_circle_ratio, collide_mask
  • pygame.sprite.collide_rect - 使用 rects 檢測兩個精靈之間的碰撞。
    • Collision detection between two sprites, using rects. 使用函數pygame rect colliderect檢測碰撞並將結果返回給*collide, 精靈必須具有 ‘rect’ 屬性

collide_rect(left, right) -> bool

  • pygame.sprite.collide_rect_ratio - 使用按比例縮放的 rects 檢測兩個精靈之間的碰撞。
    • Collision detection between two sprites, using rects scaled to a ratio. 使用 ratio 建立,然後將範例作為碰撞回撥函數傳遞給 *collide 函數。
      ratio 是浮點數 - 1.0 是相同的大小,2.0 是兩倍大,0.5 是大小的一半。

collide_rect_ratio(ratio) -> collided_callable

  • pygame.sprite.collide_circle - 使用圓圈檢測兩個精靈之間的碰撞。
    • *Collision detection between two sprites, using circles.*測試兩個精靈之間的碰撞,通過測試以檢視精靈中心的兩個圓是否重疊。

如果精靈具有 radius(半徑) 屬性,用於建立圓,否則會建立一個足夠大的圓,以完全包圍由 rect 屬性給出的精靈矩形。作為碰撞回撥函數傳遞給 *collide 函數。精靈必須具有 rect 和可選的 radius 屬性

collide_circle(left, right) -> bool

  • pygame.sprite.collide_circle_ratio - 使用按比例縮放的圓圈檢測兩個精靈之間的碰撞。
    • Collision detection between two sprites, using circles scaled to a ratio. 使用浮點數 ratio 建立,然後將範例作為碰撞回撥函數傳遞給 *collide 函數。ratio 是浮點數 - 1.0 是相同的大小,2.0 是兩倍大,0.5 是大小的一半。

兩個精靈之間的碰撞建立的可呼叫測試,通過測試以檢視以精靈為中心的兩個圓是否重疊,在通過儲存的比例縮放圓半徑之後。如果精靈具有 radius 半徑屬性,用於建立圓,否則會建立一個足夠大的圓,以完全包圍由 rect 屬性給出的精靈矩形。打算作為碰撞回撥函數傳遞給 *collide 函數。

精靈必須具有 rect 和可選的 radius 屬性

collide_circle_ratio(ratio) -> collided_callable

  • pygame.sprite.collide_mask - 使用蒙版在兩個精靈之間進行碰撞檢測。
    • *Collision detection between two sprites, using masks. *返回 masks 碰撞的 mask 上的第一個點,如果沒有碰撞,則返回 None 。

通過測試它們的 bitmasks( pygame.mask.Mask.overlap()) 是否重疊來測試兩個精靈之間的碰撞。 如果精靈具有 mask 屬性,該屬性用作 mask,否則將從精靈影象建立 mask 。 作為碰撞回撥函數傳遞給 *collide 函數。

精靈必須具有 rect 和可選的 mask 屬性

如果要多次檢查碰撞,應該考慮在載入時為精靈建立一個mask。這將提高效能,否則這可能是一個昂貴的功能,因為它會在每次檢查碰撞時建立 mask 。

# Example of mask creation for a sprite.
sprite.mask = pygame.mask.from_surface(sprite.image)

collide_mask(sprite1, sprite2) -> (int, int)

collide_mask(sprite1, sprite2) -> None

pygame.sprite.groupcollide - 查詢在兩個組之間發生碰撞的所有精靈。

  • Find all sprites that collide between two groups.
  • This will find collisions between all the Sprites in two groups. Collision is determined by comparing the Sprite.rect attribute of each Sprite or by using the collided function if it is not None.
    Every Sprite inside group1 is added to the return dictionary. The value for each item is the list of Sprites in group2 that intersect. 像這個格式{group1_sprite: group2_sprite}
  • 如果*collide沒有指定回撥函數,則所有的sprite需要有rect屬性

groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_dict

EG:
class Block(pygame.sprite.Sprite):

    # Constructor. Pass in the color of the block,
    # and its x and y position
    def __init__(self, color, width, height):
       # Call the parent class (Sprite) constructor
       pygame.sprite.Sprite.__init__(self)

       # Create an image of the block, and fill it with a color.
       # This could also be an image loaded from the disk.
       self.image = pygame.Surface([width, height])
       self.image.fill(color)

       # Fetch the rectangle object that has the dimensions of the image
       # Update the position of this object by setting the values of rect.x and rect.y
       # give radius and mask attribute
       self.rect = self.image.get_rect()
       self.radius = self.rect.width / 2
       self.mask = pygame.image.from_surface(self.image)


class File(pygame.sprite.Sprite):

    # Constructor. Pass in the color of the block,
    # and its x and y position
    def __init__(self, color, width, height):
       # Call the parent class (Sprite) constructor
       pygame.sprite.Sprite.__init__(self)

       # Create an image of the block, and fill it with a color.
       # This could also be an image loaded from the disk.
       self.image = pygame.Surface([width, height])
       self.image.fill(color)

       # Fetch the rectangle object that has the dimensions of the image
       # Update the position of this object by setting the values of rect.x and rect.y
       self.rect = self.image.get_rect()
       self.radius = self.rect.width / 2
       self.mask = pygame.image.from_surface(self.image)
    
block_group = pygame.sprite.Group()
for i in range(5):
    block = Block(color, width, height)
    block_group.add(block)
    
    # there is another sprite group called file_group, which have same setting as block_group.
file_group = pygame.sprite.Group()
for i in range(5):
    file = File(color, width, height)
    file_group.add(file)
    
    # the collide check will like:
    hit_list1 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_rect
    hit_list2 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_rect_ratio(.75))
    hit_list3 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_circle
    hit_list4 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_circle_ratio(.25))
    hit_list5 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_mask
    # select the collided function whatever you like
    hit_list6 = pygame.sprite.spritecollide(block_group, file_group, False, False, pygame.sprite.collide_XXX)

總結

到此這篇關於pygame.sprite精靈碰撞的文章就介紹到這了,更多相關pygame.sprite精靈碰撞內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com