Architektur der Engine
Erkunde die Hauptschleife, EngineContext, Objektbesitz und die Beziehungen zwischen den Systemen.
Auf dieser Seite
Von der Eingabe zum Frame
main() erstellt eine Engine und wiederholt drei Operationen, solange das Fenster geöffnet bleibt. Dieser Ausschnitt stammt aus dem Referenzcode:
while (engine.IsRunning()) {
engine.ProcessEvent();
engine.Update();
if (!engine.HasFocus()) {
sf::sleep(sf::milliseconds(10));
continue;
}
engine.Render();
}
Ohne Fokus verarbeitet die Schleife weiterhin Ereignisse und aktualisiert die Uhr; sie überspringt das Rendering und wartet 10 ms. Auch Engine::Update prüft den Fokus, bevor die Szene fortschreitet.
Aufgaben von Engine
Engine besitzt das Fenster, einen EngineContext, das Szenenregister, die Referenz auf die aktive Szene und ein Pausen-Overlay. Ihre Aufgabe ist es, diese Elemente zu koordinieren.
Engine
├── sf::RenderWindow
├── EngineContext
│ ├── renderer · resources · particles
│ ├── input · cursor · gui
│ ├── audio · time · random
│ └── scenes · save · screenshot · clipboard
├── SceneFactory::Scenes
│ └── Name → unique_ptr<Scene>
├── currentScene → aktive Scene
└── Overlay → TGUI-Widgets
Der Kontext wird jeder Szene als Referenz übergeben. So kann ein Spiel auf ctx.renderer, ctx.input oder ctx.resources zugreifen, ohne Dienste doppelt anzulegen.
Ereignisverarbeitung
Zu Beginn von ProcessEvent verarbeitet die Engine den ausstehenden Szenenwechsel. Anschließend entnimmt sie die Ereignisse aus sf::RenderWindow und verteilt sie:
EngineVisitorbehandelt Schließen, Fokus, Größe, Controller und globale Tastenkürzel.GuiManagerübergibt das Ereignis an TGUI.- Die Szene erhält
OnEvent, wenn das Overlay verborgen ist. - Die Engine verarbeitet eine mögliche Overlay-Auswahl und synchronisiert den Pausenzustand.
GUI und Szene nehmen an derselben Verarbeitung teil; ein separater Ereignisbus ist nicht dokumentiert.
Aktualisierung und Zeit
TimeManager berechnet die seit dem vorherigen Frame verstrichene Zeit und begrenzt sie auf gConfig.maximumDeltaTime. Danach wird der Cursor aktualisiert; ist das Overlay verborgen, wird Scene::Update aufgerufen.
Das System implementiert keinen Akkumulator für feste Zeitschritte. Die Spiele entscheiden, wie sie die Delta-Zeit und ihre eigenen Timer verwenden.
In der Referenzrevision implementiert jede Szene ihre Reaktion auf OnPause, einschließlich Audio und Timer. Eine lokale Überarbeitung der Cooldown-Uhr ist als in Entwicklung gekennzeichnet und gehört nicht zu dieser öffentlichen Referenz-API.
Rendering und Ebenen
Die Szene zeichnet auf eine sf::RenderTexture. RenderManager wendet die Effektkette an und gibt die fertige Textur zurück. Engine zeigt sie im Fenster an und zeichnet GUI und Cursor darüber.
Scene::Render
↓
RenderManager / RenderTexture
↓
Bloom → Monitor
↓
Fenster → GUI → Cursor → display
Die Effekte werden nur hinzugefügt, wenn sf::Shader::isAvailable() wahr zurückgibt. GUI und Cursor werden nach der Nachbearbeitung gezeichnet. Unter Rendering findest du die einzelnen Bloom-Durchläufe.
Besitz und Speicher
- Szenen werden in einer
unordered_mapmitunique_ptr<Scene>gespeichert. - Effekte werden in einem Vektor mit
unique_ptr<Effect>gespeichert. - Die aktive Szene ist ein nicht besitzender Zeiger; ihr Objekt gehört weiterhin dem Register.
- Die Manager sind als Werte in
EngineContextenthalten. - ResourceManager speichert Ressourcen als Werte in Maps.
Das Projekt verwendet RAII und Standardcontainer. Es gibt weder eine eigene Speicherverwaltung noch ein generisches ECS. Alle registrierten Szenen werden in CreateScenes erstellt; ein Szenenwechsel erzeugt nicht bei jeder Transition eine neue Instanz.
Aufbau des Codes
| Verzeichnis | Inhalt |
|---|---|
Engine/Include |
Verträge und Typen für Kern, Manager, Szenen, Effekte und Hilfsfunktionen. |
Engine/Source |
Implementierungen und Einstiegspunkt. |
Games/Include |
Spielklassen, Typen und Konfigurationskonstanten. |
Games/Source |
Spiellogik und Rendering. |
Content |
Grafik- und Audioressourcen, Schriften, Shader, Theme und JSON. |