Entrar
PT
games/open-lemmings / src / View / DemoRunner.php · commit 04e2e2a
<?phpnamespace App\View;use App\Service\Art;use App\Sim\Autoplay;use App\Sim\LevelBuilder;use App\Sim\Levels;use App\Sim\Lumi;use App\Sim\World;use JumPHP\Kernel\Engine;use JumPHP\Renderer\Renderer;/** Levels that play themselves, one after the other, without sound: the living background of the menus. */final class DemoRunner{    private World $world;    private ?WorldView $view = null;    private Autoplay $auto;    private float $acc = 0;    private float $camX = 0;    private float $end = 0;    public function __construct(private Engine $engine, private Art $art, private int $level = 0)    {        $this->start($level);    }    private function start(int $level): void    {        $this->level = $level % Levels::count();        $def = Levels::get($this->level);        $this->world = LevelBuilder::build($def);        $this->view?->release();        $this->view = new WorldView($this->engine, $this->art, $this->world, $def['theme']);        $this->auto = new Autoplay($this->world, $def['solution']);        $this->camX = max(0, $this->world->hatch[0] - 240);        $this->acc = 0;        $this->end = 0;    }    public function update(float $dt): void    {        $this->acc = min(0.3, $this->acc + $dt * 1.5);        while ($this->acc >= 1 / World::TICKS_PER_SECOND) {            $this->acc -= 1 / World::TICKS_PER_SECOND;            if (!$this->world->isOver()) {                $this->world->step();                $this->auto->step();            }        }        $this->view->consume(false);        $this->view->update($dt);        $lead = null;        foreach ($this->world->lumis as $l) {            if ($l->alive && !$l->is(Lumi::STOP) && ($lead === null || $l->x > $lead->x)) {                $lead = $l;            }        }        $target = max(0, min($this->world->terrain->width - WorldView::VIEW_W, ($lead->x ?? $this->world->hatch[0]) - 240));        $this->camX += ($target - $this->camX) * min(1, $dt * 2);        if ($this->world->isOver() && ($this->end += $dt) > 1.5) {            $this->start($this->level + 1);        }    }    public function render(Renderer $r): void    {        $this->view->render($r, $this->camX);    }    public function release(): void    {        $this->view?->release();        $this->view = null;    }}