DE

SONIC PHP

von davidnurdin · Jump 'n' Run
5,0 (1)
▶ Spielen 💬 Feedback Quellcode 🕘 Versionen Bearbeiten GitHub
. / src / Entities / Objects / Monitor.php · commit a20d00e
<?phpnamespace App\Entities\Objects;use App\Entities\GameObject;use App\Level\Level;use App\Gfx\Gfx;class Monitor extends GameObject{    private const STATIC_SCREEN = [461, 8, 22, 24];    private const ITEMS = [        0x01 => ['ring', [493, 8, 22, 24]],        0x02 => ['speed', [525, 8, 22, 24]],        0x03 => ['life', [557, 8, 22, 24]],        0x04 => ['shield', [461, 40, 22, 24]],        0x05 => ['invincibility', [493, 40, 22, 24]],        0x51 => ['checkpoint', [525, 40, 22, 24]],        0x52 => ['continue', [557, 40, 22, 24]],    ];    private string $itemType;    private int $tileX;    private int $tileY;    public function __construct(Gfx $sdl, int $objectType, string $typeName, int $tileX, int $tileY)    {        parent::__construct($sdl, $objectType, $typeName, 0, 0, 22, 24);        [$this->itemType, $icon] = self::ITEMS[$objectType] ?? self::ITEMS[0x01];        // The screen shows the item, with a short burst of static now and then.        $frames = array_merge(array_fill(0, 7, $icon), [self::STATIC_SCREEN]);        $this->animations = ['idle' => ['flags' => [], 'coords' => self::frames($frames)]];        $this->frameDuration = 0.08;        $this->setAnimation('idle');        $this->placeOnSpawn($tileX, $tileY, 16);        $this->tileX = $tileX;        $this->tileY = $tileY;    }    /**     * _5da8: in Green Hill (solidity 0) a monitor spawned on block $AB (palm tree top) is moved $16-4 px right     * and $12 px down, into the leaves that are drawn in front of it.     */    public function setLevel(Level $level): void    {        parent::setLevel($level);        if ($level->getMeta('SP') === 0 && $level->getTile($this->tileX, $this->tileY) === 0xAB) {            $this->x += 0x16 - 4;            $this->y += 0x12;        }    }    public static function supports(int $type): bool    {        return isset(self::ITEMS[$type]);    }    public function getItemType(): string    {        return $this->itemType;    }    // _5deb: hit from below by Sonic rolling upwards, the monitor jumps (Y speed -$180/256 px/frame) instead of    // breaking; from then on it falls ($40/256 px/frame²) onto the floor (_32e2)    private bool $bumped = false;    private float $bumpVy = 0;    public function bump(): void    {        $this->bumped = true;        $this->bumpVy = -0x180 / 256 * 60;    }    public function update(float $deltaTime): void    {        parent::update($deltaTime);        if (!$this->bumped || !$this->active) return;        $this->bumpVy += 0x40 / 256 * 3600 * $deltaTime;        $this->y += $this->bumpVy * $deltaTime;        if ($this->bumpVy >= 0 && $this->level) {            $floor = $this->level->findSurfaceY((int)($this->x + $this->width / 2), (int)($this->y + $this->height - 8), 16);            if ($floor !== null && $this->y + $this->height >= $floor) {                $this->y = $floor - $this->height;                $this->bumpVy = 0;            }        }    }    public function breakMonitor(): string    {        $this->active = false;        $this->visible = false;        return $this->itemType;    }}