import * as Phaser from 'phaser';
import { BossBullet } from './BossBullet';
import {Player} from './Player';
export class Boss2 extends Phaser.Physics.Arcade.Sprite {
private maxHp: number = 5;
private currentHp: number = 5;
private respawnTimer?: Phaser.Time.TimerEvent;
private isDead: boolean = false;
private fireTimer!: Phaser.Time.TimerEvent;
private bulletGroup!: Phaser.Physics.Arcade.Group;
private player!: Player;
constructor(scene: Phaser.Scene, x: number, y: number) {
super(scene, x, y, 'boss');
scene.add.existing(this);
scene.physics.add.existing(this);
this.setCollideWorldBounds(true).setDepth(3);
if (this.body) {
this.body!.immovable = true;
}
this.currentHp = this.maxHp;
this.angle += 90;
this.bulletGroup = scene.physics.add.group({
classType: BossBullet,
runChildUpdate: true
});
// 2秒ごとにプレイヤーを狙って発射するタイマー
this.startAttackRoutine();
}
private startAttackRoutine() {
this.fireTimer = this.scene.time.addEvent({
delay: 2500,
callback: this.attackPlayer,
callbackScope: this,
loop: true
});
}
private attackPlayer() {
// シーン内からプレイヤーオブジェクトを探す
const player = (this.scene as any).player as Phaser.Physics.Arcade.Sprite;
if (!player || !player.active) return;
const baseAngle = Phaser.Math.Angle.Between(this.x, this.y, player.x, player.y);
// 扇形のパラメータ設定
const spreadAngle = Phaser.Math.DegToRad(60); // 扇全体の広がり(60度)
const bulletCount = 5; // 弾の数
const startAngle = baseAngle - spreadAngle / 2;
const angleStep = spreadAngle / (bulletCount - 1);
for (let i = 0; i < bulletCount; i++) {
// グループから非アクティブな弾を取得、なければ新規生成
const bullet = this.bulletGroup.get(this.x, this.y) as BossBullet;
if (bullet) {
const targetAngle = startAngle + (angleStep * i);
// プレイヤーの座標と、動いている方向(速度 velocity)を渡して発射
const vx = player.body ? player.body.velocity.x : 0;
const vy = player.body ? player.body.velocity.y : 0;
// bullet.fire(this.x, this.y, targetAngle);
bullet.fire(player.x, player.y, vx, vy, 350, targetAngle);
}
}
}
// 弾が当たった時の処理
public takeDamage(): void {
if (!this.active) return;
this.currentHp--;
// 被弾時のフラッシュ演出(視覚的フィードバック)
this.setTint(0xff0000);
this.scene.time.delayedCall(100, () => this.clearTint());
// HPが0になったら死亡処理
if (this.currentHp <= 0) {
this.die();
}
}
// 死亡処理
private die(): void {// 当たり判定を無効化
this.isDead = true;
this.setActive(false);
this.setVisible(false);
this.body!.enable = false; // 当たり判定を無効化
this.fireTimer.paused = true; // 死亡中は弾を撃たない
// 4秒(4000ミリ秒)後に復活させるタイマーをセット
this.respawnTimer = this.scene.time.delayedCall(4000, () => {
this.respawn();
});
}
// 復活処理
private respawn(): void {
// this.hp = 5;
this.isDead = false;
this.setActive(true);
this.setVisible(true);
this.body!.enable = true;
this.fireTimer.paused = false;
// 画面内のランダムな座標を計算(画面端から50pxの内側)
const gameWidth = this.scene.scale.width;
const gameHeight = this.scene.scale.height;
const randomX = Phaser.Math.Between(50, gameWidth - 50);
const randomY = Phaser.Math.Between(50, gameHeight - 50);
// 位置を設定して再活性化
this.setPosition(randomX, randomY);
this.currentHp = this.maxHp;
}
public getBullets(): Phaser.Physics.Arcade.Group {
return this.bulletGroup;
}
public destroy(fromScene?: boolean) {
if (this.fireTimer) this.fireTimer.remove();
this.bulletGroup.destroy(true);
super.destroy(fromScene);
}
}