104 lines
2.9 KiB
PHP
104 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Game\Entities;
|
|
|
|
use App\Game\EntityList;
|
|
use App\Game\Player;
|
|
use App\Game\Room;
|
|
use App\Game\Vector2;
|
|
|
|
final class Leaper extends Zombie
|
|
{
|
|
private float $dashRange;
|
|
|
|
private float $windupTime;
|
|
|
|
private float $dashTime;
|
|
|
|
private float $dashSpeed;
|
|
|
|
private float $dashCooldown;
|
|
|
|
private float $dashTimer = 0.0;
|
|
|
|
private float $windupTimer = 0.0;
|
|
|
|
private float $dashCooldownTimer = 0.0;
|
|
|
|
private Vector2 $dashDirection;
|
|
|
|
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->dashRange = $config['dashRange'] ?? 300.0;
|
|
$this->windupTime = $config['windupTime'] ?? 0.35;
|
|
$this->dashTime = $config['dashTime'] ?? 0.28;
|
|
$this->dashSpeed = $config['dashSpeed'] ?? 680.0;
|
|
$this->dashCooldown = $config['dashCooldown'] ?? 1.8;
|
|
$this->dashDirection = new Vector2(1.0, 0.0);
|
|
}
|
|
|
|
public function kind(): string
|
|
{
|
|
return 'leaper';
|
|
}
|
|
|
|
public function update(float $dt): void
|
|
{
|
|
$this->time += $dt;
|
|
if ($this->updateEmerge($dt)) {
|
|
return;
|
|
}
|
|
$this->dashCooldownTimer = max(0.0, $this->dashCooldownTimer - $dt);
|
|
|
|
$target = $this->target;
|
|
$delta = $target !== null ? $target->pos->subV($this->pos) : Vector2::zero();
|
|
$distance = $delta->length();
|
|
|
|
$move = Vector2::zero();
|
|
if ($this->windupTimer > 0.0) {
|
|
$this->windupTimer -= $dt;
|
|
if ($this->windupTimer <= 0.0) {
|
|
$this->dashTimer = $this->dashTime;
|
|
$this->dashDirection = $distance > 1.0 ? $delta->divS($distance) : new Vector2(1.0, 0.0);
|
|
}
|
|
} elseif ($this->dashTimer > 0.0) {
|
|
$this->dashTimer -= $dt;
|
|
$move = $this->dashDirection->mulS($this->dashSpeed);
|
|
} elseif ($distance > 1.0) {
|
|
if ($distance < $this->dashRange && $this->dashCooldownTimer <= 0.0) {
|
|
$this->windupTimer = $this->windupTime;
|
|
} else {
|
|
$move = $delta->divS($distance)->mulS($this->speed);
|
|
}
|
|
}
|
|
|
|
$this->velocity = $move->addV($this->hitKnockback);
|
|
$this->move($dt);
|
|
|
|
$this->hitKnockback = $this->hitKnockback->mulS(max(0.0, 1 - $dt * $this->knockbackDamping));
|
|
$this->flash = max(0.0, $this->flash - $dt);
|
|
}
|
|
|
|
public function toSnapshot(): array
|
|
{
|
|
$data = parent::toSnapshot();
|
|
$data['dash'] = $this->dashTimer > 0.0;
|
|
$data['wind'] = $this->windupTimer > 0.0;
|
|
|
|
return $data;
|
|
}
|
|
}
|