Pygameのスプライトと衝突検出の使い方
始める前に、スプライトと衝突検出の意味を学ぶことが重要です。
スプライトとは、基本的にゲームプログラムにおける小道具、キャラクター、シーン装飾などの小さな絵のことです。小さな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の過去の記事を検索するか、以下の記事を引き続きご覧ください。
関連
-
Python入門 openを使ったファイルの読み書きの方法
-
[解決済み】Pythonのvirtualenvを離脱/終了/無効化する方法
-
[解決済み】「'float'オブジェクトを暗黙のうちにstrに変換できない」【重複あり
-
[解決済み] Kivy ScrollView内のGridLayoutをスクロールするにはどうすればよいですか?
-
[解決済み] PythonのMaven相当品 [終了しました]。
-
[解決済み] Spyderのオブジェクトインスペクタがない
-
[解決済み] PyMongo 3でServerSelectionTimeoutErrorが発生するのはなぜですか?
-
[解決済み] KeyError / フリーズしたimportlib._bootstrapがspyderの2つ目のライブラリインポートでエラーになる。
-
[解決済み] Gephiで可視化するためにnetworkxのグラフを保存する方法は?
-
python 小白之型エラー: 'str' と 'int' のインスタンスの間で '>=' がサポートされておらず、int ではなく str でなければならない。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】IndexError:サイズ1/ForwardEulerの軸0に対してインデックス1が境界外である
-
[解決済み】Python 2: AttributeError: 'list' オブジェクトに 'strip' 属性がない。
-
[解決済み】TypeError: 'newline' is an invalid keyword argument for this function [重複] この関数のキーワード引数は無効です。]
-
TypeError: flexible type solutionでreduceを実行できない。
-
[解決済み] TypeError: PythonでJSONをパースするとき、文字列のインデックスは整数でなければなりませんか?
-
[解決済み] Python TypeError: フォーマット文字列の引数が足りない
-
[解決済み] DistutilsOptionError: homeかprefix/exec-prefixのどちらかを指定しなければならない -- 両方ではない
-
[解決済み] 2文字列間の削除距離
-
pipのpythonバージョン10.1では、Could not install packages due to anEnvironmentErrorというエラーが発生します。[WinError 5] アクセスが拒否されました。
-
TypeError: 非反復可能な float オブジェクトをアンパックできない (20191105)