概要
Spriteの場合、事前にSpriteグループを登録し、クラスのインスタンス作成時に引き渡すことで、プログラムがすっきりする
メインクラス
# グループのインスタンス
self.collision_sprites = pg.sprite.Group()
# Mapクラスに登録する
self.map_list = Map(self.collision_sprites).create()
# Mapクラスで作成したものをそのまま、Playerクラスに引き渡す
# Playerクラスのインスタンス宣言
self.player = Player([250,100],self.collision_sprites)
# 中略
# player Update
self.player.update(dt) #引数で指定していた、Blockクラスのインスタンスを引き渡す必要がなくなる
Playerクラス
class Player(pg.sprite.Sprite):
def __init__(self, pos, collision_sprites):
super().__init__()
# 衝突判定用Spriteを引き受ける
self.collision_sprites = collision_sprites
内部のメンバー変数で処理できてしまうので、隠蔽できる
def collision(self,dt):
"""ブロックとの衝突判定と位置調整を行う"""
# 水平方向の衝突処理
self.hit_box_rect.x += self.direction.x * self.key_speed *dt
for block in self.collision_sprites:
if block.rect.colliderect(self.hit_box_rect):
print(f"Horizontal Collision detected: {self.hit_box_rect}, {block.rect}")
if self.direction.x > 0: # 右に移動中
self.hit_box_rect.right = block.rect.left
elif self.direction.x < 0: # 左に移動中
self.hit_box_rect.left = block.rect.right
# 衝突後、移動量をリセット
self.direction.x = 0
# 垂直方向の衝突処理
self.hit_box_rect.y += self.direction.y * self.key_speed *dt
for block in self.collision_sprites:
if block.rect.colliderect(self.hit_box_rect):
print(f"Vertical Collision detected: {self.hit_box_rect}, {block.rect}")
if self.direction.y > 0: # 下に移動中
self.hit_box_rect.bottom = block.rect.top
elif self.direction.y < 0: # 上に移動中
self.hit_box_rect.top = block.rect.bottom
# 衝突後、移動量をリセット
self.direction.y = 0
# メイン矩形をヒットボックスに同期
self.rect.center = self.hit_box_rect.center
Blockクラス
Playerと同様引数でSpriteを引き受ける
class Block(pg.sprite.Sprite):
def __init__(self, pos, img_path, collision_sprites):
super().__init__(collision_sprites)
# イメージの読み込み
self.img_path = img_path
self.surface = pg.image.load(self.img_path).convert_alpha()
# 位置
self.pos = pos
# rect
self.rect = self.surface.get_frect(topleft=pos)
Mapクラス
Playerと同様引数でSpriteを引き受けて、そのまま、Blockクラスに引き渡す
class Map(pg.sprite.Sprite):
def __init__(self, collision_sprites):
self.block_images = {
"B" : "../maps/tree.png"
}
self.name = 'map_01'
self.current_map = TILE[self.name]
self.collision_sprites = collision_sprites
self.map_list = []
def create(self):
key = 'B'
for i, row in enumerate(self.current_map):
for j, column in enumerate(row):
x = j * TILE_SIZE
y = i * TILE_SIZE
if column == key:
self.block = Block((x,y), self.block_images[key], self.collision_sprites)
self.map_list.append(self.block)
return self.map_list
まとめ
- メインクラスでSpriteグループを作成
- メインクラスからSpriteグループをMapクラスに引き渡す
- MapクラスからSpriteグループをBlockクラスに引き渡す
- メインクラスからSpriteグループをPlayerクラスに引き渡す
結果:
Spriteグループがメインクラス、Mapクラス、Blockクラス、Playerクラスで共有される
※MapクラスでPlayerを配置する予定なので、MapクラスからPlayerクラスにSpriteを引き渡すことになるので、今後メインクラスからPlayerクラスにSpriteを渡す導線がなくなる