スプライトグループを利用して、当たり判定を実装します!
敵クラスの作成
まずは敵のクラスを作成します。
import pygame
from pygame.locals import *
# mathモジュールをインポート
import math
import tools
class Enemy(pygame.sprite.Sprite):
speed = 5
def __init__(self, pos):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = tools.load_image("data", "haraheris.png", -1)
self.rect = self.image.get_rect()
self.rect.center = pos
self.angle = 90
def update(self):
# 円を描きながら移動する
self.vx = int(3 * math.cos(math.radians(self.angle)))
self.vy = int(3 * math.sin(math.radians(self.angle)))
self.rect.move_ip(self.vx, self.vy)
self.angle += self.speed
def draw(self, screen):
screen.blit(self.image, self.rect)
初登場の可愛さ担当キャラクター、「ハラヘリス」ちゃんを敵にします。見るからにハラペコそうで愛くるしいですね。
Playerクラスを参考にしていますが、円を描くように移動するようupdate()内の処理を書き換えています。
円形移動の計算のために標準のmathモジュールを使用するので、忘れずにインポートしておきましょう。
敵クラスファイルを作成したら、Mainクラスでインポートし、インスタンス化します。
ef __init__(self):
pygame.init()
pygame.display.set_caption("sample")
screen = pygame.display.set_mode(SCR_RECT.size)
# 描画用グループを作成する
self.all = pygame.sprite.RenderUpdates()
# 当たり判定用グループを作成する
self.enemies = pygame.sprite.Group()
# デフォルトグループに設定する
player.Player.containers = self.all
enemy.Enemy.containers = self.all, self.enemies
# 敵をインスタンス化
self.enemy_1 = enemy.Enemy((150, 80))
self.enemy_2 = enemy.Enemy((330, 400))
# プレイヤーをインスタンス化
self.player = player.Player((288, 200))
self.bg = tools.load_image("data", "bg.png")
clock = pygame.time.Clock()
while True:
clock.tick(30)
self.update()
self.draw(screen)
pygame.display.update()
self.key_handler()
今回は、描画用のグループと当たり判定用のグループを作成します。
RenderUpdates()はGroupの派生クラスで、draw()命令が拡張されているようです(よく分かっていません)。
とりあえず描画用にこちらのクラスを使います。
プレイヤーは一人だけなので、当たり判定用のグループは作成せず、描画用グループのみに所属させます。
これでself.allに対して更新・描画を行えば、プレイヤーと敵すべてが更新・描画されるようになりました。
当たり判定の作成
続いて、当たり判定を作成します。
collision_detection()という関数を新たに定義し、update()内で呼び出すようにします。
def update(self):
self.all.update()
self.collision_detection()
def collision_detection(self):
enemy_collided = pygame.sprite.spritecollide(self.player, self.enemies, False)
if enemy_collided:
print("敵と当たっています")
pygame.sprite.spritecollide()は、指定したスプライト(self.player)と接触しているグループ(self.enemies)内のスプライトの一覧を戻り値として返す関数です。
第三引数には、接触したスプライトを削除するかどうかを設定できます。
Trueを設定すると、self.playerと接触した敵のスプライトは削除されます。攻撃のショットなどで設定すれば、貫通弾が作れますね。
enemy_collidedにはself.playerと接触している敵スプライトの一覧が格納されます。
これが空っぽでない=接触しているものがあると判断し、処理を行います。
他にも、グループ同士で接触しているものを探すgroupcollide()や、spritecollide()よりも処理が単純で早いspritecollideany()などがあるので、状況に応じて使い分けることができます。