1. ホーム
  2. スクリプト・コラム
  3. パイソン

Pygameのスプライトと衝突検出の使い方

2022-01-28 13:37:47

始める前に、スプライトと衝突検出の意味を学ぶことが重要です。

スプライトとは、基本的にゲームプログラムにおける小道具、キャラクター、シーン装飾などの小さな絵のことです。小さなquot;スプライト"画像と見なすことができます。また、キャラクターの動きは、以下のようにスプライトの連続(フレームの連続)として見ることができます。


図1:アクションのフレームごとの内訳

フレームごとに分解した後のアクションを、ある一定の頻度で再生すると、アニメーションスプライトが作成され、鷲が高く飛び、人が馬を疾走させ、アスリートが激しくジャンプする様子を見ることができるのです。

スプライトの特徴として、スプライト同士の相互作用(コリジョンとも言う)、2つのスプライトの間で衝突が起きたかどうかを検出する「コリジョンディテクション」ができることが挙げられます。例えば、ヘビゲームでヘビの頭が餌にぶつかったかどうか、飛行機バトルゲームで弾丸がエイリアンにぶつかったかどうか、などです。弾丸がエイリアンに当たると、エイリアンが消えてプレイヤーのスコアが上がり、ゲーム画面には別のエイリアンが現れるといった具合だ。

Pygameにはスプライトを扱うための専用モジュール、スプライト(pygame.sprite)モジュールがあります。通常、このモジュールの基底クラスであるspriteを使用して、以下のようにスプライトを操作するための通常のプロパティとメソッドを提供する、スプライトを扱うためのサブクラスを作成します。

<テーブル プロパティとメソッド 説明 self.image 表示するスプライト画像を読み込み、画像サイズと塗りつぶしの色を制御します。 self.rect スプライト画像を表示する場所 Sprite.update()を実行します。 スプライトマップを更新し、対応する効果が有効になるようにします。 スプライト.add() スプライトグループにスプライトマップを追加する(グループ) スプライト.remove() 選択されたスプライトマップをスプライトグループから削除します。 スプライト.kill() スプライトグループからすべてのスプライトを削除する Sprite.active() スプライトがスプライトグループに属しているかどうかを判定する

なお、ゲーム内に多数のスプライトが存在する場合、その操作が複雑になるため、スプライトグループとも呼ばれるスプライトコンテナ(グループクラス)を構築して管理します。これは次のように行います。

# Create a sprite group
group = pygame.sprite.Group()
# Add a sprite to the group
group.add(sprite_one)


同時に、pygame.spriteモジュールは、以下のようにスプライトの衝突を検出する様々なメソッドも提供しています。

<テーブル メソッド 説明 pygame.sprite.collide_rect()を使用します。  2つのスプライト間の矩形検出、すなわち矩形領域が交差しているかどうかを調べ、ブール値を返します。 pygame.sprite.collide_circle()を使用します。 2つのスプライトの間に円があるかどうか、つまり円形の領域が交差しているかどうかを検出し、ブール値を返します。 pygame.sprite.collide_mask()を使用します。  2つのスプライトの間のピクセルマスクをより正確に検出する方法です。 pygame.sprite.spritecollide()を使用します。  スプライトとスプライトグループの間の矩形衝突検出。グループ内のすべてのスプライトは、別の単一のスプライトに対して1つずつ衝突し、戻り値は衝突したすべてのスプライトのリストです。 pygame.sprite.spritecollideany() スプライトとスプライトグループの間の矩形衝突検出。上記の関数の変形で、衝突が発生した場合はグループ内のスプライトを返し、衝突が発生しない場合は None を返します。 pygame.sprite.groupcollide() 2つのグループ間で衝突するスプライトをすべて検出し,第1グループで衝突したスプライトをキー,第2グループで衝突したスプライトを値とする辞書を返します.

以下に示すコードで、簡単な例をご覧ください。

import pygame
class Snake(pygame.sprite:)
    #define constructor
    def __init__(self,filename,location):
        # Call the parent class to initialize the subclass
        pygame.sprite.Sprite.__init__(self)
        # Load the image
        self.image = pygame.image.load(filename)
        # Get the rect area of the image
        self.rect = self.image.get_rect()
        # Set the position
        self.rect.topleft=location
# Initialize pygame
pygame.init()
screen = pygame.display.set_mode((500,400))
pygame.display.set_caption('C language Chinese web')
# Fill the screen with white
screen.fill((255,255,255))
filename ="C:/Users/Administrator/Desktop/snake.png"
location =(100,150)
snake1 = Snake(filename,location)
# collision detection, there must be two sprites, so create another sprite, and use location to control the location of the second sprite
location_2 = (100,80)
snake2 = Snake('C:/Users/Administrator/Desktop/logo.png',location_2)
# call collide_rect() for rectangular area detection, return a boolean, collision return True, otherwise return False
crash_result = pygame.sprite.collide_rect(snake1,snake2)
if crash_result:
    print("The sprites collided! ")
    pass
else:
    print('Genie did not crash')
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
    # Draw the sprite to the screen
    screen.blit(snake1.image,snake1.rect)
    screen.blit(snake2.image,snake2.rect)
    # Refresh the display screen
    pygame.display.update()

スプライトが衝突しない場合、プログラムは次のように実行されます。


図2:実行結果

次に、snake2 の location_2 パラメータを (100,140) に変更して再度プログラムを実行すると、この時点で 2 つのスプライトが衝突し、次のような結果が得られます。


図3:実行結果

上記以外にも、Pygameにはmixer(サウンド)、movie(ビデオ再生)、music(オーディオ再生)、sndarray(サウンドデータの操作)など多くのモジュールがありますが、これらのモジュールは比較的簡単に使えるため、ここでは一つ一つ紹介せず、興味のある方はPygame公式ドキュメント-The official Pygame documentation is available hereを読んでみてください。 クリックで移動 !

Pygameでスプライトと衝突判定を使う方法についての記事は以上です。Pygameのスプライトと衝突判定については、Script Houseの過去の記事を検索するか、以下の記事を引き続きご覧ください。