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を作る(9. 敵の配置と衝突判定)

Posted at

概要

Mapに敵配置とPlayerとの衝突判定を追加

Enemyクラス

class Enemy(pg.sprite.Sprite):
    def __init__(self, pos, img_path, enemy_sprites):
        super().__init__(enemy_sprites)

        # イメージの読み込み
        self.img_path = img_path
        self.surface = pg.image.load(self.img_path).convert_alpha()
        self.surface = pg.transform.scale(self.surface, (64, 64))
        # 位置
        self.pos = pos
        # rect
        self.rect = self.surface.get_frect(topleft=pos)

Mapクラス

敵は3種類のみ用意

class Map(pg.sprite.Sprite):
    def __init__(self, collision_sprites, enemy_sprites):

        self.block_images = {
            "B" : "../maps/tree.png",
            "E" : ["../img/enemy/e001.png",'../img/enemy/e002.png','../img/enemy/e003.png']
        }
        self.name = 'map_01'
        self.current_map = TILE[self.name]

        self.collision_sprites = collision_sprites
        self.enemy_sprites = enemy_sprites

        self.map_list = []
        self.enemy_list = []
        self.player = None

    def create(self):
        enemy_count = 0
        for i, row in enumerate(self.current_map):
            for j, column in enumerate(row):
                x = j * TILE_SIZE
                y = i * TILE_SIZE

                if column == 'B':
                    self.block = Block((x,y), self.block_images['B'], self.collision_sprites)
                    self.map_list.append(self.block)
                if column == 'P':
                    self.player = Player((x,y), self.collision_sprites, self.enemy_sprites)
                if column == 'E':
                    self.enemy = Enemy((x,y), self.block_images['E'][enemy_count], self.enemy_sprites)
                    enemy_count += 1
                    self.enemy_list.append(self.enemy)

        return self.player, self.map_list, self.enemy_list

Playerクラス

class Player(pg.sprite.Sprite):
    
    def __init__(self, pos, collision_sprites, enemy_sprites):
        super().__init__()

        self.collision_sprites = collision_sprites
        self.enemy_sprites = enemy_sprites
        # イメージの読み込み
        self.surface = pg.image.load(IMAGE_PATH).convert_alpha()

        # 矩形(rect)と位置情報
        self.rect = self.surface.get_frect(topleft=pos)
        self.hit_box_rect = self.rect.inflate(-10,-10)

        # 移動関連
        self.key_speed = 10
        self.direction = pg.Vector2(0, 0)

    def handle_input(self, dt):
        """キーボード入力で移動処理を行う"""
        keys = pg.key.get_pressed()

        # キーが押されたときだけ移動
        self.direction.x = int(keys[pg.K_RIGHT]) - int(keys[pg.K_LEFT])
        self.direction.y = int(keys[pg.K_DOWN]) - int(keys[pg.K_UP])
        
        self.direction = self.direction.normalize() if self.direction else self.direction

    def collision_enemy(self, dt):
       
        # 水平方向、垂直方向の衝突判定を処理
        self.hit_box_rect.x += self.direction.x * self.key_speed * dt
        for enemy in self.enemy_sprites:
            if enemy.rect.colliderect(self.hit_box_rect):
                print('Enemyと衝突しました!')
        self.hit_box_rect.y += self.direction.y * self.key_speed * dt
        for enemy in self.enemy_sprites:
            if enemy.rect.colliderect(self.hit_box_rect):
                print('Enemyと衝突しました!')
        
        # メイン矩形をヒットボックスに同期
        self.rect.center = self.hit_box_rect.center

    def collision_block(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):
                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):
                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
        

    def update(self, dt):
        self.handle_input(dt)
        self.collision_block(dt)
        self.collision_enemy(dt)

メインクラス

class game:
    def __init__(self):
        pg.init()

        # screen
        self.display_surface = pg.display.set_mode((WIDTH, HEIGHT))
        # title
        pg.display.set_caption(TITLE)
        # clock
        self.clock = pg.time.Clock()
        self.running = True

        # 通過不可Sprite
        self.collision_sprites = pg.sprite.Group()
        # Enemy Sprite
        self.enemy_sprites = pg.sprite.Group()

        # Map
        self.player, self.map_list, self.enemy_list = Map(
            self.collision_sprites,
            self.enemy_sprites,
            ).create()

    def run(self):
        """ゲームループ"""
        dt = self.clock.tick(FPS) / 1000

        while self.running:
            # イベント処理
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    self.running = False

            # draw
            self.display_surface.fill(BLUE)

            # 衝突用ブロック
            for map in self.map_list:
                self.display_surface.blit(map.surface, map.rect)

            # Enemyの表示
            for enemy in self.enemy_list:
                self.display_surface.blit(enemy.surface, enemy.rect)

            # playerの表示    
            self.display_surface.blit(self.player.surface,self.player.rect)

            # player Update
            self.player.update(dt)

            pg.display.update()

        pg.quit()

if __name__ == "__main__":
    new_game = game()
    new_game.run()

ゲーム画面

image.png

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?