URLhttps://learnscript.net/zh-hant/pygame/sprite/collision/
    複製連結移至說明  範例

    實作精靈碰撞偵測的三種方式,以及如何移除精靈

    閱讀 6:06·字數 1835·發佈 
    Youtube 頻道
    訂閱 375

    前言

    在遊戲開發過程中,碰撞偵測是一個常見且關鍵的技術問題。無論是判斷道具撿取、子彈擊中目標,還是角色與環境互動,都需要可靠的碰撞偵測機製。Python 的 Pygame 通過其sprite模組,為開發者提供了強大的遊戲精靈(Sprite)碰撞偵測功能。

    本文將講解 Pygame 中三種主要的碰撞偵測方式:精靈與精靈之間、精靈與精靈組之間,以及精靈組與精靈組之間的碰撞偵測,並詳細介紹移除精靈的多種方法。

    範例準備

    為了示範各種碰撞偵測技術,我們組建了一個簡單的遊戲案例。在這個案例中,玩家可以通過點選滑鼠右鍵,在滑鼠位置建立鐳射(Laser)物件,並與案例中的糖果(Candy)和門(Door)進行互動。

    # 定義三個精靈類別
    class Candy(pygame.sprite.Sprite):
    	pass # 具體實作省略
    
    class Laser(pygame.sprite.Sprite): pass # 具體實作省略
    class Door(pygame.sprite.Sprite): pass # 具體實作省略
    # 建立對應的精靈組 cs = pygame.sprite.Group() # Candy 精靈組 ls = pygame.sprite.Group() # Laser 精靈組

    Pygame 中的碰撞偵測

    Pygame 中所有Sprite物件都擁有一個rect變數,這個矩形不僅表示精靈的位置和大小,同時也作為預設的碰撞偵測區域。值得註意的是,理想情況下碰撞偵測區域應小於精靈的影像,並位於影像中心,以獲得更真實的碰撞效果。但在本文的範例中,我們直接使用精靈表面物件建立的矩形作為碰撞區域,這可能導致碰撞現象看起來不太「真實」。

    碰撞偵測方式一:精靈與精靈之間

    sprite模組提供的collide_rect函式,可以實作兩個精靈物件之間的碰撞偵測。

    collide_rect(left, right)

    left,right 參數

    參與檢測的兩個精靈物件。

    傳回值

    如果兩個精靈的碰撞偵測區域(rect變數)有重疊部分,則傳回True,否則傳回False

    Group物件的sprites方法傳回一個包含組中所有精靈的串列。

    當檢測到碰撞時,呼叫精靈的kill方法會將該精靈從所有包含他的精靈組中移除。由於範例通過精靈組來更新和繪製所有鐳射,被移除的鐳射會從遊戲視窗中消失,其update方法也不再被呼叫。

    # 周遊所有鐳射精靈
    for l in ls.sprites():
    	# 檢測鐳射與門的碰撞
    	if pygame.sprite.collide_rect(l, door):
    		l.kill() # 從所有包含該精靈的組中移除精靈

    碰撞偵測方式二:精靈與精靈組之間

    sprite模組提供的spritecollide函式,可用於檢測精靈與精靈組中所有精靈的碰撞。

    spritecollide(sprite, group, dokill, collided=None)

    sprite 參數

    參與檢測的精靈物件。

    group 參數

    參與檢測的精靈組。

    dokill 參數

    布林值,決定是否自動移除精靈組中被碰撞的精靈。

    傳回值

    傳回一個串列,包含了精靈組中與指定精靈發生碰撞的所有精靈。

    在這個範例中,我們將dokill設為False,然後手動處理碰撞後的移除操作。Sprite物件的remove方法可以從指定精靈組中移除精靈,Group物件的remove方法可以從精靈組中移除指定的精靈。

    for l in ls.sprites():
    	# 檢測鐳射與糖果組的碰撞,但不自動移除
    	rcs = pygame.sprite.spritecollide(l, cs, False)
    
    if rcs: # 如果發生碰撞 l.remove(ls) # 手動從鐳射組中移除鐳射 cs.remove(rcs) # 從糖果組中移除所有碰撞的糖果

    碰撞偵測方式三:精靈組與精靈組之間

    sprite模組提供的groupcollide函式,可用於檢測兩個精靈組之間的碰撞。

    groupcollide(groupa, groupb, dokilla, dokillb, collided=None)

    groupa,groupb 參數

    參與檢測的兩個精靈組。

    dokilla,dokillb 參數

    布林值,決定是否自動移除各自組中被碰撞的精靈。

    傳回值

    字典,鍵是第一個組中被碰撞的精靈,值是一個串列,包含了第二個組中與該精靈碰撞的所有精靈。

    這種方式比較簡潔,特別適合處理大量需要相互檢測的物件,如子彈與敵人群體之間的碰撞。

    # 檢測鐳射組與糖果組的碰撞,自動移除碰撞的精靈和糖果
    pygame.sprite.groupcollide(ls, cs, True, True)

    精靈移除方法

    SpriteGroup物件提供了多種移除精靈的方式,當然,你也可以通過碰撞偵測函式的相關參數自動移除精靈。

    kill方法,由Sprite物件呼叫,可從所有包含該精靈的組中移除精靈。

    sprite.kill()

    remove方法,由SpriteGroup物件呼叫,可從指定組中移除精靈,或從組中移除指定精靈。

    sprite.remove(*groups)
    group.remove(*sprites)

    groups 參數

    可變參數groups所包含的位置參數,可以是Group精靈組物件,或巢狀包含Group物件的序列物件。

    sprites 參數

    可變參數sprites所包含的位置參數,可以是Sprite精靈物件,或巢狀包含Sprite物件的序列物件。

    結論

    Pygame 的sprite模組提供了全面而靈活的碰撞偵測機製,開發者可以根據具體需求選擇最適合的檢測方式。

    內容分類

    講解影片

    Pygame 實作碰撞偵測(Sprite 精靈、Group 精靈組),以及精靈組移除精靈的方式·YouTube