Whack-a-Mole: Die CSS Edition

Avatar of Will Yu
Will Yu am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Wir haben den Checkbox-Hack gesehen und wie er verwendet werden kann, um eine vollständige Zustandsmaschine in CSS zu erstellen. Heute gehen wir diesen Gedankengang noch einen Schritt weiter und bauen ein einfaches Whack-A-Mole-Spiel, bei dem der Spieler schnell reagieren muss, um zu gewinnen … ganz ohne ein Quäntchen JavaScript.

Das mag in einer Sprache, die keine Ahnung von Timern oder Intervallen hat, etwas albern erscheinen, aber das Geheimnis ist, dass CSS diese Funktionen *hat* – sie sind nur in einem kleinen Feature namens CSS Animations verpackt.

Schauen Sie sich diesen Doppelklick-Handler an. Beachten Sie, dass CSS nicht weiß, was ein Klick ist, geschweige denn ein Doppelklick

Wie funktioniert das? Hier ist eine Aufnahme der wichtigen Elemente, umgefärbt und verlangsamt

Die Idee ist, dass das Bewegen des Doppelklick-Elements an die Cursorposition, wenn Sie zum ersten Mal auf den Button klicken, auch dazu führt, dass sich ein Maskierungselement nach oben bewegt, um es zu verdecken.

  • Wenn der zweite Klick schnell genug nach dem ersten erfolgt (wie auf der linken Seite der Aufnahme), geschieht er auf dem Doppelklick-Element (blau).
  • Andernfalls (wie auf der rechten Seite der Aufnahme) geschieht er auf dem Maskierungselement (gelb), was die Wirkung eines Ein-Klick-Elements hat.

(Für eine eingehende Erklärung lesen Sie meine Ausarbeitung zum reinen CSS-Doppelklick-Handler hier.)

Hier spielen zwei Ideen eine Rolle

  1. Animationen können verwendet werden, um Zustände nach einem festgelegten Muster zu verwalten. (Ich verwende den Begriff „Zustand“ lose.)
  2. Durch Ändern der Position eines Elements können wir ändern, ob ein Benutzer eine Aktion ausführen darf oder nicht.

Das ist alles, was wir brauchen!

Anstatt unser Ziel in Sicht zu bringen, könnten wir jetzt stattdessen animation-timing-function: step-end verwenden, damit es ein- und ausspringt, ähnlich wie ein Maulwurf in einem Loch.

Ich habe ein paar verschiedene Optionen ausprobiert, um den Maulwurf aus dem Weg zu bewegen, und die Änderung seiner absoluten Position – hier left – scheint am besten zu funktionieren. Die Verwendung einer Translation wäre praktisch, hinterlässt aber leider, dass Firefox denkt, der Cursor befände sich über dem falschen Element, da die Änderung von transform in der Gecko-Layout-Engine kein erneutes Layout auslöst. (Normalerweise wäre das aus Leistungsgründen gut, aber nicht so sehr für unsere kleine Demo!)

Mit ein wenig Styling können wir es mehr wie ein Spielelement aussehen lassen

Der „Maulwurf“ ist im Grunde ein umgestaltetes CSS-Label, das den Checkbox-Hack auslöst. Das Loch auch. Wenn die Animation des Maulwurfs ihn über das Loch bringt, löst ein Klick in der Region die Radio-Schaltfläche des Maulwurfs aus; wenn der Maulwurf aus dem Weg ist, löst ein Klick die Radio-Schaltfläche des Lochs aus.

Der nächste Schritt ist, ein paar Löcher nebeneinander zu platzieren und die Maulwürfe dazwischen herumhüpfen zu lassen, jeder mit einer anderen negativen animation-delay. Mit einer Zustandsmaschine, die liest, welche der Maulwürfe getroffen wurden und welche der Löcher kollabiert sind, wird daraus ein ordentliches kleines Spiel.

Ich habe kurze Python-Skripte verwendet, um sowohl die Selektoren für die Zustandsmaschine als auch die Keyframes für den Maulwurf zu generieren. Andernfalls wird es von Hand etwas unübersichtlich. Das liegt hauptsächlich daran, dass CSS auch keine zufälligen Zahlen kennt, was uns keine andere Wahl lässt, als das „zufällige“ Verhalten des Maulwurfs fest zu codieren.

Da haben wir es: ein vollständiges reaktionsbasiertes Spiel, komplett in HTML und CSS.