Vorlesungsbeispiel: Universum

Zurück zur Übersicht
// Definition der Hauptklasse des Programms mit dem Namen "Sandbox"
public class Sandbox {

    // Hauptmethode, die das Programm startet und die Eingabeparameter erhält
    public static void main(String[] args) {
        // Erstellen einer neuen Instanz des Universums und Übergabe der Eingabeparameter
        Universe u = new Universe(args);

        // Erstellen eines neuen Planeten vom Typ M und Hinzufügen zum Universum
        Planet p = new Planet(Type.M);
        u.addEntity(p);
        
        // Festlegen der Position des Planeten und Bestätigen, dass er Wolken hat
        p.setLocation(-75.7, 341.042);
        p.setHasClouds(true);

        // Erstellen einer neuen Rakete
        Rocket r = new Rocket();
        
        // Festlegen der Position der Rakete relativ zum Planeten
        r.setLocationRelativeTo(p, 12.2, -200.0);
        
        // Hinzufügen der Rakete zum Universum und Starten ihres Countdowns
        u.addEntity(r);
        r.launchIn(5);

        // Starten der Simulation des Universums
        u.simulate();
    }
}
                        class Entity {
                            protected static int LAST_ID = 0;
                            protected final int id;
                            protected double x, y;
                            public Entity() {
                                this.id = ++LAST_ID;
                            }
                            protected String toJson(){ return "{}"; }
                        }

                        class Universe {
                            private static boolean didSimulate = false;                            
                            private java.util.List<Entity> entities = new java.util.LinkedList<>(); 
                            protected static java.util.List<String> commands = new java.util.LinkedList<>();

                            public Universe(String[] args) {
                                commands.add("{\"command\":\"Universe\"}");                                
                             }

                            public void addEntity(Entity entity) {
                                if (entities.contains(entity)) {
                                    System.err.println("Entity was already added!");
                                    return;
                                }
                                entities.add(entity);
                                commands.add("{\"command\":\"addEntity\", \"entity\": " + entity.id + "}");
                            }

                            protected String toJson(){
                                StringBuilder sb = new StringBuilder();
                                sb.append("[");
                                boolean didAdd = false;
                                for (Entity e : entities){
                                    if (didAdd) sb.append(",");
                                    sb.append(e.toJson());
                                    didAdd = true;
                                }
                                sb.append("]");
                                return sb.toString();
                            }

                            public void simulate() { 
                                commands.add("{\"command\":\"simulate\"}");
                                if (!didSimulate) {
                                    didSimulate = true;
                                    //System.out.println(commands.toString());
                                    de.fau.tf.lgdv.CodeBlocks.postResult(commands.toString());
                                } else {
                                    System.err.println("Simulation was already started!");                                
                                }
                            }
                        }

                        class Planet extends Entity{
                            private final int type;
                            private boolean hasClouds;

                            public Planet(int type) {
                                if (type != Type.M){
                                    System.err.println("Invalid planet type!");
                                } else {
                                    Universe.commands.add("{\"command\":\"Planet\", \"type\": " + type + ", \"id\": " + id + "}");
                                }
                                this.type = type;
                            }

                            public void setLocation(double x, double y) {
                                Universe.commands.add("{\"command\":\"setLocation\", \"x\": " + x + ", \"y\": " + y + ", \"id\": " + id + "}");
                                this.x = x;
                                this.y = y;
                            }

                            public void setHasClouds(boolean hasClouds) {
                                Universe.commands.add("{\"command\":\"setHasClouds\", \"hasClouds\": " + hasClouds + ", \"id\": " + id + "}");
                                this.hasClouds = hasClouds;
                            }

                            protected String toJson(){
                                return "{\"class\":\"Planet\", \"type\": " + type + ", \"x\": " + x + ", \"y\": " + y + ", \"hasClouds\": " + hasClouds + ", \"id\": " + id + "}";                                
                            }
                        }

                        class Rocket extends Entity{
                            private Planet planet;
                            private int launchTime;

                            public Rocket() {
                                Universe.commands.add("{\"command\":\"Rocket\", \"id\": " + id + "}");
                             }
                            public void setLocationRelativeTo(Planet planet, double offsetX, double offsetY) {
                                Universe.commands.add("{\"command\":\"setLocationRelativeTo\", \"planet\": " + planet.id + ", \"offsetX\": " + offsetX + ", \"offsetY\": " + offsetY + ", \"id\": " + id + "}");
                                this.planet = planet;
                                this.x = planet.x + offsetX;
                                this.y = planet.y + offsetY;
                            }
                            public void launchIn(int seconds) { 
                                Universe.commands.add("{\"command\":\"launchIn\", \"seconds\": " + seconds + ", \"id\": " + id + "}");
                                this.launchTime = seconds;
                            }

                            protected String toJson(){
                                double x = this.x;
                                double y = this.y;
                                if (planet!=null){
                                    x += planet.x;
                                    y += planet.y;
                                }
                                return "{\"class\":\"Rocket\", \"x\": " + x + ", \"y\": " + y + ", \"launchTime\": " + launchTime + ", \"id\": " + id + "}";                                
                            }
                        }

                        class Type{
                            public static final int M = 0;
                        }
                    

Erklärung

Das Programm erstellt eine Instanz des Universe, fügt einen Planeten und eine Rakete hinzu, setzt verschiedene Eigenschaften und startet schließlich die Simulation. Hier ist eine kurze Erläuterung der Schritte:

  1. Erstellen des Universums und des Planeten:
    Universe u = new Universe(args);
    Planet p = new Planet(Type.M);
    Diese Zeilen erstellen eine neue Instanz des Universe mit den übergebenen Programmargumenten args und einen neuen Planeten des Typs M.
    In Java ist args ein Array von String-Elementen, das im Methodenkopf der main-Methode auftritt. Dieses Array enthält die Kommandozeilenargumente, die einem Programm übergeben werden, wenn es gestartet wird.
  2. Eigenschaften des Planeten setzen und zum Universum hinzufügen:
    u.addEntity(p);
    p.setLocation(-75.7, 341.042);
    p.setHasClouds(true);
    Der Planet wird zunächst dem Universum u hinzugefügt, seine Position wird festgelegt und es wird angegeben, dass er Wolken hat.
  3. Erstellen und Konfigurieren der Rakete:
    Rocket r = new Rocket();
    r.setLocationRelativeTo(p, 12.2, -200.0);
    u.addEntity(r);
    r.launchIn(5);
    Eine Rakete wird erstellt, relativ zu dem Planeten p positioniert, dem Universum u hinzugefügt und dann so eingestellt, dass sie in 5 Zeiteinheiten startet.
  4. Simulation starten:
    u.simulate();
    Diese Zeile startet die Simulation des Universums u mit den hinzugefügten Entitäten und deren Konfigurationen.

Beschreibung

Repräsentiert das Universum, in dem die Simulation stattfindet.

Konstruktor

  • public Universe(String[] args) Erstellt eine neue Instanz des Universums mit den angegebenen Eingabeparametern.

Instanzmethoden

  • public void addEntity(Planet entity) Fügt einen Planeten zum Universum hinzu.
  • public void addEntity(Rocket entity) Fügt eine Rakete zum Universum hinzu.
  • public void simulate() Startet die Simulation des Universums.

Beschreibung

Repräsentiert einen Planeten im Universum.

Konstruktor

  • public Planet(int type) Erstellt einen neuen Planeten mit dem angegebenen Typ (z.B. M).

Instanzmethoden

  • public void setLocation(double x, double y) Setzt die Position des Planeten auf die angegebenen Koordinaten.
  • public void setHasClouds(boolean hasClouds) Legt fest, ob der Planet Wolken hat.

Beschreibung

Repräsentiert eine Rakete im Universum.

Konstruktor

  • public Rocket() Erstellt eine neue Instanz einer Rakete.

Instanzmethoden

  • public void setLocationRelativeTo(Planet planet, double offsetX, double offsetY) Setzt die Position der Rakete relativ zu einem Planeten.
  • public void launchIn(int seconds) Startet die Rakete nachdem die angegebenen Anzahl von Sekunden vergangen ist.

Beschreibung

Eine Klasse, die verschiedene Konstanten für Planetentypen repräsentiert (z.B. M, N, etc.)

Klassenkonstanten

  • M Ein Bewohnbarer Planet.

Experimente

Was ändert sich, wenn Sie die Position der Rakete auf (0,0) festlegen?
Versuchen Sie eine zweite Rakete einzufügen (Position: (142, -180) • Start: 2s)?
Fügen Sie den Code aus Punkt 3 ein zweites mal ein. Vergessen Sie nicht die Bezeichnung von r sowie die zugehörigen Werte anzupassen.
Bevor die Simulation mit u.simulate(); gestartet wird, können Sie folgendes einfügen:
Rocket r2 = new Rocket();
r2.setLocationRelativeTo(p, 142, -180);
u.addEntity(r2);
r2.launchIn(2);