Connexion
FR
games/open-lemmings / tests / PlayTest.php · commit 04e2e2a
<?phpnamespace Tests;use App\Scene\LevelScene;use App\Scene\PauseScene;use App\Scene\PlayScene;use App\Scene\ResultScene;use App\Scene\TitleScene;use App\Sim\Lumi;use JumPHP\Testing\GameTestCase;/** The game played like a player does: with clicks on the bar and on the Lumikins. */final class PlayTest extends GameTestCase{    private function click(float $x, float $y, int $frames = 2): void    {        $mouse = $this->game->engine->input->getMouse();        $mouse->move($x, $y);        $mouse->down(1);        $this->game->run(1);        $mouse->up(1);        $this->game->run($frames);    }    private function play(int $level): PlayScene    {        $scene = $this->game->start(PlayScene::class, ['level' => $level]);        self::assertInstanceOf(PlayScene::class, $scene);        return $scene;    }    public function testTheTitleShowsALevelPlayingItself(): void    {        $this->game->start(TitleScene::class);        $this->game->run(240);        self::assertInstanceOf(TitleScene::class, $this->game->scene());    }    public function testClickingPlayOpensTheLevelMapAndTheFirstLevel(): void    {        $this->game->start(TitleScene::class);        $this->click(240, 160, 40);        self::assertInstanceOf(LevelScene::class, $this->game->scene());        $this->click(40, 60, 40);        self::assertInstanceOf(PlayScene::class, $this->game->scene());    }    public function testClickingALumikinWithTheShovelMakesItDig(): void    {        $scene = $this->play(0);        $this->game->run(150);        $world = $scene->world();        $lumi = $world->lumis[0];        self::assertSame(Lumi::WALK, $lumi->state);        [$bx, $by] = PlayScene::buttons()['dig'];        $this->click($bx + 10, $by + 10);        $this->click($lumi->x - $scene->camX(), $lumi->y - 6);        self::assertSame(Lumi::DIG, $lumi->state);        self::assertSame(2, $world->skills['dig']);        $this->game->run(60);        self::assertGreaterThan(120, $lumi->y);    }    public function testDiggingThroughTheLedgeBringsEveryoneHome(): void    {        $scene = $this->play(0);        $this->game->press('fast');        $this->game->run(60);        $lumi = $scene->world()->lumis[0];        while ($lumi->x < 110) {            $this->game->run(1);        }        $this->click($lumi->x - $scene->camX(), $lumi->y - 6);        $this->game->run(900);        self::assertInstanceOf(ResultScene::class, $this->game->scene());        self::assertTrue($this->game->peek('result')['won']);        self::assertSame(10, $scene->world()->saved);    }    public function testDraggingTheLevelScrollsIt(): void    {        $scene = $this->play(1);        $mouse = $this->game->engine->input->getMouse();        $before = $scene->camX();        $mouse->move(400, 40);        $mouse->down(1);        $this->game->run(1);        $mouse->move(250, 40);        $this->game->run(2);        $mouse->up(1);        $this->game->run(1);        self::assertEqualsWithDelta($before + 150, $scene->camX(), 1);    }    public function testThePauseButtonFreezesTheLevel(): void    {        $scene = $this->play(0);        $this->game->run(100);        [$bx, $by] = PlayScene::buttons()['pause'];        $this->click($bx + 10, $by + 10);        self::assertInstanceOf(PauseScene::class, $this->game->scene());        $tick = $scene->world()->tick;        $this->game->run(60);        self::assertSame($tick, $scene->world()->tick);        $this->game->press('pause', 3);        self::assertInstanceOf(PlayScene::class, $this->game->scene());    }    public function testPressingTheBurstButtonTwiceEndsTheLevelLost(): void    {        $scene = $this->play(0);        $this->game->run(120);        [$bx, $by] = PlayScene::buttons()['nuke'];        $this->click($bx + 10, $by + 10);        self::assertFalse($scene->world()->nuked);        $this->click($bx + 10, $by + 10);        self::assertTrue($scene->world()->nuked);        $this->game->run(400);        self::assertInstanceOf(ResultScene::class, $this->game->scene());        self::assertFalse($this->game->peek('result')['won']);    }    public function testZoomingInKeepsTheClicksOnTheLumikins(): void    {        $scene = $this->play(0);        $this->game->run(150);        $lumi = $scene->world()->lumis[0];        $scene->zoomAt(2.0, $lumi->x - $scene->camX(), $lumi->y - 6);        self::assertEqualsWithDelta(2.0, $scene->zoom(), 0.01);        $this->game->run(2);        $this->click(($lumi->x - $scene->camX()) * 2, ($lumi->y - 6 - $scene->camY()) * 2);        self::assertSame(Lumi::DIG, $lumi->state);        $scene->zoomAt(0.2, 240, 100);        self::assertSame(1.0, $scene->zoom());        self::assertSame(0.0, $scene->camY());    }    private function finger(string $type, int $id, float $x, float $y): void    {        $f = new \stdClass();        $f->fingerId = $id;        $f->x = $x;        $f->y = $y;        $e = new \stdClass();        $e->type = $type === 'down' ? \SDL_FINGERDOWN : ($type === 'up' ? \SDL_FINGERUP : \SDL_FINGERMOTION);        $e->tfinger = $f;        $this->game->scene()->pinch()->handle($e, $this->game->engine->sdl->getRenderer());    }    public function testPinchingZoomsAndLiftingOneFingerDoesNotMoveTheCamera(): void    {        $scene = $this->play(1);        $this->game->run(5);        $mouse = $this->game->engine->input->getMouse();        $mouse->move(200, 100);        $mouse->down(1);                                   // the first finger is also the mouse (SDL)        $this->finger('down', 1, 0.40, 0.40);        $this->game->run(1);        $this->finger('down', 2, 0.45, 0.40);        for ($i = 1; $i <= 10; $i++) {                     // the fingers move apart            $this->finger('move', 1, 0.40 - $i * 0.01, 0.40);            $this->finger('move', 2, 0.45 + $i * 0.01, 0.40);            $this->game->run(1);        }        self::assertGreaterThan(1.5, $scene->zoom());        $cam = [$scene->camX(), $scene->camY()];        $this->finger('up', 2, 0.55, 0.40);                // one finger lifts, the other one slides        $mouse->move(120, 60);        $this->game->run(3);        self::assertSame($cam, [$scene->camX(), $scene->camY()]);        $mouse->up(1);        $this->finger('up', 1, 0.30, 0.40);        $this->game->run(2);        self::assertFalse($scene->pinch()->active());    }    public function testALostFingerUpDoesNotLeaveAPinchOn(): void    {        $scene = $this->play(1);        $this->finger('down', 1, 0.4, 0.4);        $this->finger('down', 2, 0.5, 0.4);        self::assertTrue($scene->pinch()->active());        $this->game->run(15);                              // no finger-up ever came, the mouse is not held        self::assertFalse($scene->pinch()->active());    }    public function testEveryLanguageDrawsItsTexts(): void    {        $lang = $this->game->engine->lang;        foreach ($lang->available() as $code) {            $lang->setLang($code);            $this->game->start(LevelScene::class);            $this->game->run(2);            $this->play(0);            $this->game->run(3);        }        $lang->setLang('en');        self::assertGreaterThanOrEqual(14, count($lang->available()));    }}