Sie haben eigentlich zwei verschiedene Probleme hier.
Das erste sind die Probleme mit Timern. Sie haben hier viele Möglichkeiten:
- Starten Sie einen Thread, der zwischen Aktionen schläft, etwas wie
(future (loop [] (do-something) (Thread/sleep 20) (when (game-still-running) (recur))))
- Verwenden Sie eine Java TimerTask - einfach von Clojure aus aufzurufen
- Verwenden Sie eine Bibliothek wie mein kleines Dienstprogramm Task, das eine DSL für sich wiederholende Aufgaben beinhaltet
- Verwenden Sie die Timer-Funktionalität von dem Spiele-Engine, den Sie verwenden - die meisten von ihnen bieten einige Werkzeuge zur Einrichtung einer Spielschleife
Ich würde wahrscheinlich einfach die einfache Thread-Option verwenden - es ist ziemlich einfach einzurichten und einfach mehr Funktionen später hinzuzufügen, wenn Sie es müssen.
Das zweite Problem ist das Behandeln des Spielzustands. Dies ist eigentlich das kniffligere Problem und Sie müssen es um den speziellen Typ des Spiels herum entwerfen, also gebe ich nur ein paar Ratschläge:
- Wenn Ihr Spielzustand unveränderlich ist, erhalten Sie viele Vorteile: Ihr Rendercode kann den aktuellen Spielzustand unabhängig zeichnen, während das Spielupdate den nächsten Spielzustand berechnet. Unveränderlichkeit hat einige Leistungskosten, aber die Vorteile der Nebenläufigkeit sind enorm, wenn Sie es zum Laufen bringen können. Beide meine Mini-Clojure-Spiele (Ironclad und Alchemy) nutzen diesen Ansatz
- Sie sollten wahrscheinlich versuchen, Ihren Spielzustand in einer einzigen top-Level-Var zu speichern. Ich finde, dass dies besser funktioniert als das Aufteilen von verschiedenen Teilen des Spielzustands über verschiedene Vars. Es bedeutet auch, dass Sie im Grunde keine Ref-basierten Transaktionen benötigen: ein Atom oder Agent wird normalerweise ausreichen.
- Sie möchten möglicherweise eine Warteschlange von Ereignissen implementieren, die sequenziell vom Spielzustands-Update-Funktion verarbeitet werden müssen. Dies ist besonders wichtig, wenn Sie mehrere gleichzeitige Ereignisquellen haben (z.B. Spieleraktionen, Timer-Ticks, Netzwerkevents usw.)