initial commit
This commit is contained in:
commit
e8c3f9862a
193 files changed
+29795
No files matched your search
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Game;
|
||||
|
||||
final class Room
|
||||
{
|
||||
public const STATE_LOBBY = 'lobby';
|
||||
|
||||
public const STATE_PLAYING = 'playing';
|
||||
|
||||
public const STATE_OVER = 'over';
|
||||
|
||||
public float $width = 1920.0;
|
||||
|
||||
public float $height = 1080.0;
|
||||
|
||||
public EntityList $entities;
|
||||
|
||||
/** @var array<string, Player> playerId => Player */
|
||||
public array $players = [];
|
||||
|
||||
public string $state = self::STATE_LOBBY;
|
||||
|
||||
/** Player id of the room's host (the first player to join). */
|
||||
public string $hostId = '';
|
||||
|
||||
public float $elapsed = 0.0;
|
||||
|
||||
public float $nextBossScore = 50.0;
|
||||
|
||||
public int $bossCount = 0;
|
||||
|
||||
public float $bossCooldown = 0.0;
|
||||
|
||||
public float $spawnTimer = 0.0;
|
||||
|
||||
public float $pickupTimer = 8.0;
|
||||
|
||||
/** @var array<int, array<string, mixed>> Queue of one-shot event descriptors for clients. */
|
||||
public array $events = [];
|
||||
|
||||
public int $seq = 0;
|
||||
|
||||
public function __construct(
|
||||
public readonly string $id,
|
||||
public readonly int $maxPlayers = 8,
|
||||
) {
|
||||
$this->entities = new EntityList;
|
||||
}
|
||||
|
||||
public function addPlayer(Player $player): void
|
||||
{
|
||||
$this->players[$player->id] = $player;
|
||||
$this->entities->append($player);
|
||||
}
|
||||
|
||||
public function removePlayer(Player $player): void
|
||||
{
|
||||
unset($this->players[$player->id]);
|
||||
$this->entities->remove($player);
|
||||
}
|
||||
|
||||
/** Reset round state so the room can be played again (host-initiated). */
|
||||
public function reset(): void
|
||||
{
|
||||
$this->state = self::STATE_LOBBY;
|
||||
$this->elapsed = 0.0;
|
||||
$this->nextBossScore = 50.0;
|
||||
$this->bossCount = 0;
|
||||
$this->bossCooldown = 0.0;
|
||||
$this->spawnTimer = 0.0;
|
||||
$this->pickupTimer = 8.0;
|
||||
$this->events = [];
|
||||
$this->seq++;
|
||||
|
||||
foreach ($this->entities->copy() as $entity) {
|
||||
if ($entity instanceof Player) {
|
||||
continue;
|
||||
}
|
||||
$this->entities->remove($entity);
|
||||
}
|
||||
|
||||
foreach ($this->players as $player) {
|
||||
$player->resetForRound();
|
||||
}
|
||||
}
|
||||
|
||||
/** @return array<int, Player> */
|
||||
public function alivePlayers(): array
|
||||
{
|
||||
$alive = [];
|
||||
foreach ($this->players as $player) {
|
||||
if (! $player->dead) {
|
||||
$alive[] = $player;
|
||||
}
|
||||
}
|
||||
|
||||
return $alive;
|
||||
}
|
||||
|
||||
public function highestScore(): int
|
||||
{
|
||||
$best = 0;
|
||||
foreach ($this->players as $player) {
|
||||
$best = max($best, $player->score);
|
||||
}
|
||||
|
||||
return $best;
|
||||
}
|
||||
|
||||
public function hasBoss(): bool
|
||||
{
|
||||
foreach ($this->entities as $entity) {
|
||||
if ($entity instanceof Entities\Boss) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function pushEvent(string $kind, array $data = []): void
|
||||
{
|
||||
$this->events[] = ['k' => $kind, 'x' => $data['x'] ?? 0.0, 'y' => $data['y'] ?? 0.0, 'd' => $data];
|
||||
}
|
||||
|
||||
public function flushEvents(): array
|
||||
{
|
||||
$events = $this->events;
|
||||
$this->events = [];
|
||||
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user