0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pygameを使って RPGを作る(8. Map作成 Sprite版)

Last updated at Posted at 2025-01-02

概要

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

まとめ

  1. メインクラスでSpriteグループを作成
  2. メインクラスからSpriteグループをMapクラスに引き渡す
  3. MapクラスからSpriteグループをBlockクラスに引き渡す
  4. メインクラスからSpriteグループをPlayerクラスに引き渡す

結果:
Spriteグループがメインクラス、Mapクラス、Blockクラス、Playerクラスで共有される

※MapクラスでPlayerを配置する予定なので、MapクラスからPlayerクラスにSpriteを引き渡すことになるので、今後メインクラスからPlayerクラスにSpriteを渡す導線がなくなる

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?