Files
zombie-game/app/Game/Entities/Pickup.php
T
2026-09-07 20:37:40 +02:00

110 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Game\Entities;
use App\Game\EntityList;
use App\Game\GameObject;
use App\Game\Player;
use App\Game\Room;
final class Pickup extends GameObject
{
public const TYPES = [
'rapid' => 'Rapid Fire',
'damage' => 'Damage +1',
'multishot' => 'Multishot',
'speed' => 'Bullet Speed',
];
private EntityList $container;
private Room $room;
public string $type;
public float $life;
private float $time = 0.0;
public float $collectRadius;
public float $size;
/** @var array<float> */
public array $color;
public function __construct(
float $x,
float $y,
string $type,
EntityList $container,
Room $room,
float $life = 10.0,
float $collectRadius = 46.0,
) {
parent::__construct($x, $y);
$this->container = $container;
$this->room = $room;
$this->type = $type;
$this->life = $life;
$this->collectRadius = $collectRadius;
$this->time = 0.0;
$this->size = 16.0;
$this->width = $this->size;
$this->height = $this->size;
$this->color = self::colorFor($type);
}
public function kind(): string
{
return 'pickup';
}
public static function colorFor(string $type): array
{
return match ($type) {
'rapid' => [1.0, 0.8, 0.2, 1.0],
'damage' => [1.0, 0.3, 0.3, 1.0],
'multishot' => [0.2, 0.8, 1.0, 1.0],
'speed' => [0.6, 0.9, 1.0, 1.0],
default => [1.0, 1.0, 1.0, 1.0],
};
}
public function collectableBy(Player $player): bool
{
if ($player instanceof Player && ! $player->dead) {
return $player->maxUpgradeLevel > ($player->upgrades[$this->type] ?? 0);
}
return false;
}
public function update(float $dt): void
{
$this->time += $dt;
if ($this->time >= $this->life) {
$this->container->remove($this);
}
}
public function remaining(): float
{
return max(0.0, $this->life - $this->time);
}
public function toSnapshot(): array
{
return [
'eid' => $this->eid,
'd' => $this->kind(),
'x' => round($this->pos->x, 1),
'y' => round($this->pos->y, 1),
't' => $this->type,
'life' => round($this->remaining(), 2),
];
}
}