Keller-Dev Docs · Java & Hytale

Java Advanced

ECS Datenfluss

1. Systemübersicht & Sequenzieller Datenfluss Die Verarbeitung im Game Loop erfolgt strikt sequenziell in jedem Frame: InbutSystem -> MovementSystem -> CameraSystem -> RenderSystem - InputSystem Prüft Tastatureingaben (über KeyHandler) und setzt die Richtungsvektoren dx und dy in der VelocityComponent der Entität. - MovementSystem Liest VelocityComponent, normalisiert diagonale Bewegungen und aktualisiert die Welt-Koordinaten (worldX, worldY) in der PositionComponent unter Berücksichtigung von speed und deltaTime. - CameraSystem Liest die PositionComponent des Fokus-Objekts (Spieler). Berechnet die Soll-Position der oberen linken Kamera-Ecke in der Welt (cameraWorldX, cameraWorldY). Wichtig: Erreichen diese Werte die Map-Ränder, greift das Clamping und friert die Koordinaten auf die Grenzen ein (0 bis \text{maxWorld} - \text{screenSize}). - RenderSystem Liest die PositionComponent aller zu zeichnenden Entitäten sowie die geklemmte CameraComponent. Transformiert die Welt-Koordinaten in Bildschirm-Koordinaten (\text{screenX} = \text{worldX} - \text{cameraWorldX}) und rendert Map-Tiles und Entitäten auf das JPanel. 2. Mathematisches Modell (Kamera & Clamping) Allgemeine Formeln - Soll-Kameraposition (Top-Left-Origin): cameraWorldX = playerWorldX - (screenWidth/2) + (tileSize/2) cameraWorldY = playerWorldY - (screenHeight/2) + (tileSize/2) - geklemmte Kameraposition (Clamping): cameraWorldX = Math.max(0, Math.min(cameraWorldX, worldWidth-screenWidth)) cameraWorldY = Math.max(0, Math.min(cameraWorldY, worldHeight-screenHeight)) - Transformation in Bildschirmkoordinaten (Screen Space): playerScreenX = playerWorldX - cameraWorldX playerScreenY = playerWorldY - cameraWorldY

Referenz: Datei Lumina: Fate of the Fallen
Beispielszenarien

- Rahmenbedingungen:
    - Map-Größe: 2000 x 1000 px
    - Bildschirm-Größe: 800 x 600 px

Szenario A: Spieler in der Map-Mitte

- Spieler-Position: (1000, 500) px
- Kamera-Soll: 
    cameraWorldX = 1000 - 400 = 600 px
    cameraWorldY = 500 - 300 = 200 px
- Clamping: Werte liegen innerhalb der Grenzen [0, 1200] bzw. [0, 400] -> keine Korrektur.
- Screen-Position: 
    playerScreenX = 1000 - 600 = 400 px
    playerScreenY = 500 - 200 = 300 px
- Ergebnis: Spieler ist exakt in der Bildschirmmitte.


Szenario B: Bewegung in der Map-Mitte

- Spieler-Position verändert sich auf: (500, 500) px
- Kamera-Soll:
    cameraWorldX = 500 - 400 = 100 px
    cameraWorldY} = 500 - 300 = 200 px
- Clamping: Keine Korrektur nötig.
- Screen-Position: 
    playerScreenX = 500 - 100 = 400 px
    playerScreenY} = 500 - 200 = 300 px
- Ergebnis: Welt bewegt sich unter dem Spieler durch, Spieler bleibt visuell zentriert.


Szenario C: Erreichen des linken oberen Randes (Clamping aktiv)

- Spieler-Position verändert sich auf: (50, 100) px
Kamera-Soll: 
    cameraWorldX = 50 - 400 = -350 px
    cameraWorldY} = 100 - 300 = -200 px
- Clamping greift ein: Da Werte < 0 sind, wird die Kamera bei 
    cameraWorldX_clamped = 0 und 
    cameraWorldY_clamped = 0 fixiert.
- Screen-Position: 
    playerScreenX = 50 - 0 = 50 px
    playerScreenY = 100 - 0 = 100 px
- Ergebnis: Die Kamera hält am Rand der Welt an. Der Spieler löst sich visuell aus der Bildschirmmitte und wandert an den linken oberen Rand des Fensters.
#ecs #gaming #RPG #architecture #design-pattern #game-loop #camera-system #clamping #coordinate-transformation #math #rendering #swing #2d-rendering
Bearbeiten