概要
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()