Pygameでスプライト同士の衝突判定と跳ね返りを実装する方法をソースコード付きで詳しく解説します。
スプライト同士の衝突判定と跳ね返り
Pygameでは、self.rect.colliderect を使ってスプライト同士の衝突判定と跳ね返りを実装できます。self.rect.colliderect(other_rect) は、2つの矩形(Rect オブジェクト)が衝突しているかどうかを判定するメソッドです。
衝突している場合は True を返し、そうでない場合は False を返します。
動画解説版
サンプルコード
5つの画像オブジェクトが衝突したら跳ね返るサンプルコードです。
コード解説
上記コードの各部分について解説します。
1. インポートと初期設定
import sys
import pygame
from pygame.locals import *
sysモジュールは、システム固有のパラメータや関数にアクセスするために使用します。pygameは、ゲーム開発のためのライブラリです。pygame.localsから*をインポートすることで、Pygame の定数を直接使用できます。
2. 画面サイズの設定
SCREEN = Rect(0, 0, 600, 400) # 画面サイズ
SCREENは、ゲームウィンドウのサイズを設定するためのRectオブジェクトです。
3. 画像ファイルパスの設定
GIRL1_IMG_PATH = "/Users/github/sample/python/pygame/sprite/girl1.png"
GIRL2_IMG_PATH = "/Users/github/sample/python/pygame/sprite/girl2.png"
GIRL3_IMG_PATH = "/Users/github/sample/python/pygame/sprite/girl3.png"
GIRL4_IMG_PATH = "/Users/github/sample/python/pygame/sprite/girl4.png"
GIRL5_IMG_PATH = "/Users/github/sample/python/pygame/sprite/girl5.png"
- 各スプライトの画像ファイルのパスを設定します。
4. スプライトのクラス定義
class Girl(pygame.sprite.Sprite):
def __init__(self, filepath, pos, vxy, angle=0):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = pygame.image.load(filepath).convert_alpha()
if angle != 0:
self.image = pygame.transform.rotate(self.image, angle)
x, y = pos
vx, vy = vxy
w = self.image.get_width()
h = self.image.get_height()
self.rect = Rect(x, y, w, h)
self.vx = vx
self.vy = vy
self.angle = angle
Girlクラスは、pygame.sprite.Spriteを継承しています。__init__メソッドでは、画像の読み込み、位置と速度の設定、回転角度の適用を行います。
5. スプライトの更新メソッド
def update(self):
self.rect.move_ip(self.vx, self.vy)
if self.rect.left < 0 or self.rect.right > SCREEN.width:
self.vx = -self.vx
if self.rect.top < 0 or self.rect.bottom > SCREEN.height:
self.vy = -self.vy
self.rect = self.rect.clamp(SCREEN)
for sprite in self.containers:
if sprite != self and self.rect.colliderect(sprite.rect):
self.vx = -self.vx
self.vy = -self.vy
updateメソッドでは、スプライトの位置を更新し、画面の端に達した場合や他のスプライトと衝突した場合に速度を反転させます。つまり、スプライトは画面の端や他のスプライトに衝突すると跳ね返る動きをします。self.rect.move_ip(self.vx, self.vy):スプライトの位置を現在の速度(vx,vy)に基づいて更新します。if self.rect.left < 0 or self.rect.right > SCREEN.width:- スプライトが画面の左端または右端に達した場合、
vxの符号を反転させて反射させます。
- スプライトが画面の左端または右端に達した場合、
if self.rect.top < 0 or self.rect.bottom > SCREEN.height:- スプライトが画面の上端または下端に達した場合、
vyの符号を反転させて反射させます。
- スプライトが画面の上端または下端に達した場合、
self.rect = self.rect.clamp(SCREEN):- スプライトの位置を画面内に制限します。
- 他のスプライトとの衝突処理:
for sprite in self.containers:で同じコンテナ内の他のスプライトをループします。つまり、self.containers内の他のスプライトをループし、自分自身以外のスプライトと衝突しているかをself.rect.colliderect(sprite.rect)で判定します。if sprite != self and self.rect.colliderect(sprite.rect):自分自身以外のスプライトと衝突した場合、vxとvyの符号を反転させて反射させます。


コメント