85 lines
2.1 KiB
PHP
85 lines
2.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Game\Entities;
|
|
|
|
use App\Game\EntityList;
|
|
use App\Game\Player;
|
|
use App\Game\Room;
|
|
|
|
final class Boss extends Zombie
|
|
{
|
|
private float $spawnInterval;
|
|
|
|
private int $spawnCount;
|
|
|
|
private float $spawnTimer;
|
|
|
|
/** @var null|callable(float,float,EntityList,Room,?Player):void */
|
|
private $spawnZombie;
|
|
|
|
public function __construct(
|
|
float $x,
|
|
float $y,
|
|
EntityList $container,
|
|
Room $room,
|
|
?Player $initialTarget,
|
|
array $config = [],
|
|
?callable $onDeath = null,
|
|
) {
|
|
parent::__construct($x, $y, $container, $room, $config, $onDeath);
|
|
if ($initialTarget !== null) {
|
|
$this->target = $initialTarget;
|
|
}
|
|
$this->spawnInterval = $config['spawnInterval'] ?? 5.0;
|
|
$this->spawnCount = $config['spawnCount'] ?? 1;
|
|
$this->spawnTimer = 3.0;
|
|
$this->spawnZombie = $config['spawnZombie'] ?? null;
|
|
}
|
|
|
|
public function kind(): string
|
|
{
|
|
return 'boss';
|
|
}
|
|
|
|
public function update(float $dt): void
|
|
{
|
|
parent::update($dt);
|
|
|
|
$this->spawnTimer -= $dt;
|
|
if ($this->spawnTimer > 0.0 || $this->spawnZombie === null) {
|
|
return;
|
|
}
|
|
$this->spawnTimer = $this->spawnInterval;
|
|
|
|
$minions = 0;
|
|
foreach ($this->container as $obj) {
|
|
if ($obj instanceof Zombie && ! ($obj instanceof self)) {
|
|
$minions++;
|
|
}
|
|
}
|
|
if ($minions >= 15) {
|
|
return;
|
|
}
|
|
for ($i = 0; $i < $this->spawnCount; $i++) {
|
|
$angle = ($i / $this->spawnCount) * M_PI * 2.0 + $this->rand01() * 0.6;
|
|
($this->spawnZombie)(
|
|
$this->pos->x + cos($angle) * 70.0,
|
|
$this->pos->y + sin($angle) * 70.0,
|
|
$this->container,
|
|
$this->room,
|
|
$this->target,
|
|
);
|
|
}
|
|
}
|
|
|
|
public function toSnapshot(): array
|
|
{
|
|
$data = parent::toSnapshot();
|
|
$data['type'] = 'boss';
|
|
|
|
return $data;
|
|
}
|
|
}
|