Variable für Array wird nicht korrekt übergeben

NeoLexx

Mitglied
Hallo zusammen,
registriert bin ich seit gestern und heute schon meine ersten Fragen an euch :eek:. Bitte vergebt mir meine amateurhafte Weise mich auszudrücken, ich versuche, so gut es mir möglich ist, das Fachvokabular der Java-Programmierung zu verwenden.

Vielleicht fange ich mit der Fehlermeldung an:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 0
at Game.CreateUniverse.setuniverse(CreateUniverse.java:28)
at Game.LostinAndromeda.main(LostinAndromeda.java:7)

Soweit habe ich die Fehlermeldung auch Verstanden, glaube ich jedenfalls. Problem ist, dass die Variable length, welche die Kantenlänge meiner Arrays repräsentiert, nicht ordnungsgemäß an das Array "universum" übergeben wird. Anschließend, wenn jedem Feld im Array der Wert 0 initialisiert werden soll, wird wohl ein Array-Feld aufgerufen, welches jenseits der definierten Kantenlänge liegt.

Bei meiner bisherigen Fehleranalyse fand ich heraus, dass, sofern ich die Variable "length" innerhalb der Klasse CreateUniverse deklariere und direkt mit einem Wert initialisiere, dieser Wert ordnungsgemäß an das Array übergeben wird. Und der gesamte Code keine Fehlermeldung mehr ausgibt. Daher liegt wohl das Problem in der Übergabe der Variablen length.

Es liegt folgender Code vor:

Beinhaltet die MainMethode:
Java:
package Game;
import javax.swing.JOptionPane;
public class LostinAndromeda {
    public static void main (String [] args) {
        CreateUniverse universe1 = new CreateUniverse(5);
        universe1.setuniverse();
        JOptionPane.showMessageDialog(null, "Damit ist das Universum " +universe1.universum.length +" Felder groß.");
       
        int wert =universe1.readuniverse(Integer.parseInt (JOptionPane.showInputDialog("Gebe die xxx Koordinate ein:")),
                Integer.parseInt (JOptionPane.showInputDialog("Gebe die yyy Koordinate ein:")),
                Integer.parseInt (JOptionPane.showInputDialog("Gebe die xx Koordinate ein:")),
                Integer.parseInt (JOptionPane.showInputDialog("Gebe die yy Koordinate ein:")),
                Integer.parseInt (JOptionPane.showInputDialog("Gebe die x Koordinate ein:")),
                Integer.parseInt (JOptionPane.showInputDialog("Gebe die y Koordinate ein:")));
        JOptionPane.showMessageDialog(null, wert);
    }

}

Wird innerhalb der MainMethode aufgerufen:
Java:
package Game;

public class CreateUniverse {
    static int length;
    public CreateUniverse (int a) {
        length=a;
    }
    int [] [] [] [] [] [] universum = new int [length] [length] [length] [length] [length] [length];
    public void setuniverse () {  
        int x;
        int y;
        int xx;
        int yy;
        int xxx;
        int yyy;
        for(int iyyy=1; iyyy<length; iyyy++) {
            yyy=iyyy;
            for(int ixxx=1; ixxx<length;ixxx++) {
                xxx=ixxx;
                for (int iyy=1; iyy<length; iyy++) {
                    yy=iyy;
                    for (int ixx=1; ixx<length; ixx++) {
                        xx=ixx;
                        for (int iy=1;iy< length;iy++) {
                                    y=iy;
                                    for (int ix=1;ix< length;ix++) {
                                        x=ix;
                                        universum [yyy][xxx][yy][xx][y][x] = 0;
                                    }
                        }
                    }
                }
            }
        }
        }
   
    public int readuniverse (int xxx, int yyy, int xx, int yy, int x, int y) {
        return universum [yyy][xxx][yy][xx][y][x];
       
    }
   

}
 

mihe7

Top Contributor
Vielleicht fange ich mit der Fehlermeldung an:
Die Fehlermeldung besagt, dass Du versuchst, auf Index 1 eines Arrays zuzugreifen, das eine Größe von 0 besitzt.

Das Problem ist, dass Du scheinbar glaubst, die Reihenfolge von Methoden und Deklarationen in einer Java-Datei hätte eine Auswirkung auf die Ausführungsreihenfolge. Dem ist nicht so.

Du hast eine Klassenvariable length, die wird automatisch mit 0 initialisiert. Mal abgesehen davon, dass das eine Instanzvariable sein sollte, wird beim Erzeugen eines CreateUniverse-Objekts erstmal das universum-Array erzeugt - zu diesem Zeitpunkt ist length 0. Anschließend wird der Konstruktor ausgeführt, d. h. length auf den übergebenen Wert gesetzt.

Ändere den Anfang der Klasse so ab:
Java:
public class CreateUniverse {
    private int length;
    int[][][][][][] universum;

    public CreateUniverse (int a) {
        length = a;
        universum = new int[length][length][length][length][length][length];
    }

Dann wird ein Schuh draus.
 
K

kneitzel

Gast
Hallo und erst einmal herzlich willkommen. An Deinem Code fallen mehrere Dinge auf:

Als erstes kommen wir zu dem Fehler
========================

Du versuchst auf ein Element 1 eines Array zuzugreifen, obwohl das Array nur 0 Elemente hat.

Erläuterung, wie es dazu kommt:
Du hast zwei Member-Variablen in Deiner Klasse: length und universum. Wenn Du eine Initialisierung hast, dann wird zuerst die Initialisierung durch direkte Zuweisung gemacht. Und dann kommt erst der Konstruktor.

Also erst werden sozusagen die Variablen erzeugt und initialisiert:
a) length - hier hast Du keine Zuweisung, daher wird die Variable 0.
b) universum - hier wird ein neues mehrdimensionales Array erzeugt - mit der Größe length. Length ist aber 0.
c) Dann kommt der Konstruktor und length wird gesetzt. Aber das ändert natürlich nichts an Universum.

Lösungsidee:
Die Zuweisung von Universum machst Du einfach in dem Konstruktor. Also in den Konstruktor kommt noch rein:
universum = new int [length] [length] [length] [length] [length] [length];
(Und diese Zuweisung brauchst Du bei der Deklaration der Variable dann nicht mehr!)


setUniverse() Anmerkungen
==================

Du hast eine Menge Lokaler Variablen, die Du aber nur nutzt um eine andere Variable zu nutzen.

Also aus einem:

Code:
int name;
for (int iName=.......) {
  name = iName;
  ...
}
Kannst Du einfach machen:
Code:
for (int name=.......) {
  ...
}

Denn so ich nichts übersehen habe, hast Du keinerlei andere Nutzung außer es dann am Ende als index im Array zu nutzen.

Neues Array aus int Werten
==================
Ein neues Array aus primitiven Datentypen wird bereits auf 0 initialisiert. Daher ist eine explizite Initialisierung nach der Erzeugung nicht notwendig.
Ein neues Array wird sozusagen immer mit "0"en gefüllt (Bildlich gesprochen). Bei Referenz-Typen ist das halt "null", bei int/long 0, bei float/double 0.0, boolean false, ....
 

NeoLexx

Mitglied
Wow, danke für eure schnelle Antwort.
@mihe7
Das Problem ist, dass Du scheinbar glaubst, die Reihenfolge von Methoden und Deklarationen in einer Java-Datei hätte eine Auswirkung auf die Ausführungsreihenfolge. Dem ist nicht so.

Okay, ja das hatte ich tatsächlich gedacht. Kannst du mir erklären wieso es sinnvoll ist, dass der Konstruktor zum Schluss abgehandelt wird? Immerhin kann man durch ihn eine Variable mit Wert an die Klasse übergeben, die dann wiederum in diversen Methoden eben dieser Klasse verwendet werden kann. Gibt es eine bessere Variante eine Variable und ihren Wert von außerhalb an eine Klasse zu übergeben?

@JustNobody
Erläuterung, wie es dazu kommt:
Du hast zwei Member-Variablen in Deiner Klasse: length und universum. Wenn Du eine Initialisierung hast, dann wird zuerst die Initialisierung durch direkte Zuweisung gemacht. Und dann kommt erst der Konstruktor.

Okay, soweit auch verstanden. Member-Variablen = Instance Variablen sind Variablen, die außerhalb von Mehtoden deklariert werden. Für mich ist hier auch nicht Plausibel warum der Konstruktor zum Schluss abgehandelt wird, liegt wohl daran, dass ich mir über die Funktion des Konstrukors noch nicht ganz im Klaren bin.

setUniverse() Anmerkungen
==================

Du hast eine Menge Lokaler Variablen, die Du aber nur nutzt um eine andere Variable zu nutzen.

Ja, da hast du recht. Danke für den Tipp.

Neues Array aus int Werten
==================
Ein neues Array aus primitiven Datentypen wird bereits auf 0 initialisiert. Daher ist eine explizite Initialisierung nach der Erzeugung nicht notwendig.
Ein neues Array wird sozusagen immer mit "0"en gefüllt (Bildlich gesprochen). Bei Referenz-Typen ist das halt "null", bei int/long 0, bei float/double 0.0, boolean false, ....

Das Arrey soll später das Spielfeld eines Spieles repräsentieren und den Wert 0 vergebe ich hier nur zu Testzwecken. Wird wohl besser sein wenn ich hier vorerst den Wert 1 setze, so dass ich sehen kann, dass das Setzen funktioniert hat. Später werden hier anhand einer Wahrscheinlichkeitsverteilung Verschiedene Werte gesetzt, wobei z.b. dann 1 für leeren Raum steht, 2 für Asteroid, 3 für Anomalie,... etc.

@mihe7 und @JustNobody

Ihr beide schlägt vor die Zuweisung von "universum" in den Konstruktor zu setzen. Das habe ich getan, es führt jedoch dazu, dass ich die Meldung erhalte, dass "universum" nirgendswo verwendet werde und außerdem, da wo ich es in den Methoden aufrufe, wird es als nicht deklarierte Variable bemängelt.
 

temi

Top Contributor
Kannst du mir erklären wieso es sinnvoll ist, dass der Konstruktor zum Schluss abgehandelt wird?
Was meinst du damit?

Meinst du damit die Anordnung innerhalb der Klasse:
Java:
public class CreateUniverse {
    private int length;
    int[][][][][][] universum;

    public CreateUniverse (int a) {
        length = a;
        universum = new int[length][length][length][length][length][length];
    }
Die Anordnung ist völlig egal. Üblicherweise werden die Instanzvariablen am Anfang deklariert, danach der oder die Konstruktoren und danach die öffentlichen Methoden und danach die privaten Methoden. Aber das kann im Prinzip jeder halten wie er es mag. Auf die Ausführung hat das keinen Einfluss.
 

temi

Top Contributor
Immerhin kann man durch ihn eine Variable mit Wert an die Klasse übergeben, die dann wiederum in diversen Methoden eben dieser Klasse verwendet werden kann. Gibt es eine bessere Variante eine Variable und ihren Wert von außerhalb an eine Klasse zu übergeben?
Das hast du schon richtig erkannt. Der Konstruktor ist eine sehr gute Möglichkeit, die Daten, die von der Klasse benötigt werden an die Instanz der Klasse zu übergeben. Das ist gut und richtig so. Daneben gibt es auch die Möglichkeit von Setter-Methoden, aber generell sollte eine Klasse so erzeugt werden, dass sie anschließend funktionstüchtig ist und das geht mittels des Konstruktors. Setter sind z.B. für optionale Parameter sinnvoll.
 

temi

Top Contributor
Ihr beide schlägt vor die Zuweisung von "universum" in den Konstruktor zu setzen.

Du darfst nur die Initialisierung in den Konstruktor setzen, nicht die Deklaration!

Java:
class Foo {
    int wert; // dies ist eine Deklaration: Typ und Name der Variablen
    
    public Foo() {
        int wert = 42; // FALSCH: Das ist auch eine Deklaration, die Instanzvariable wert wird jetzt von der lokalen Variable wert verdeckt.
        
        wert = 42; // RICHTIG: Der Instanzvariablen wert wird etwas zugewiesen.
    }
}
 

NeoLexx

Mitglied
Was meinst du damit?

Meinst du damit die Anordnung innerhalb der Klasse:
Java:
public class CreateUniverse {
    private int length;
    int[][][][][][] universum;

    public CreateUniverse (int a) {
        length = a;
        universum = new int[length][length][length][length][length][length];
    }
Die Anordnung ist völlig egal. Üblicherweise werden die Instanzvariablen am Anfang deklariert, danach der oder die Konstruktoren und danach die öffentlichen Methoden und danach die privaten Methoden. Aber das kann im Prinzip jeder halten wie er es mag. Auf die Ausführung hat das keinen Einfluss.

Nein, dass die Reinfolge im Code nicht ausschlaggebend für die Reinfolge der Abhandlung des Codes ist, hat mir @JustNobody in seiner Antwort erklärt. Soweit ist das klar.

Ich frage mich jetzt einfach nur welchen Grund es wohl gibt, dass der Konstruktor zum Schluss abgehandelt wird, obwohl er womöglich eine Variable liefert die in einer der Methoden zum Einsatz kommen soll.

Du darfst nur die Initialisierung in den Konstruktor setzen, nicht die Deklaration!

Java:
class Foo {
    int wert; // dies ist eine Deklaration: Typ und Name der Variablen
   
    public Foo() {
        int wert = 42; // FALSCH: Das ist auch eine Deklaration, die Instanzvariable wert wird jetzt von der lokalen Variable wert verdeckt.
       
        wert = 42; // RICHTIG: Der Instanzvariablen wert wird etwas zugewiesen.
    }
}

Perfekt, ja das war der Fehler.

@mihe7 @JustNobody Damit erübrigt sich meine letzte Frage an euch.
 

NeoLexx

Mitglied
Der Konstruktor liefert keine Variable. Was meinst Du damit?

In meinem Fall übergebe ich eine Variable durch den Konstruktor an die Klasse "CreateUniverse" die Variable für die Länge des Arrays (length). Das meine ich mit "er (der Konstruktor) womöglich eine Variable liefert".

Vielleicht erkläre ich einmal was ich überhaupt vor habe mit dieser besagten Klasse:

Folgendes möchte ich in der Klasse CreateUniverse machen:

1. Sie soll ein Spielfeld mit einer noch nicht fest definierten Größe erstellen.

2. Die Größe wird ihr aus der MainMethode übermittelt, oder später aus eine anderen Klasse, die aber zu jetzigem Zeitpunkt noch nicht existiert.

3. Die Klasse soll diverse Anfragen bezüglich des Spielfeldes verarbeiten können. Wie z.b. "readUniverse"

4. Das Spielfeld soll dynamisch sein und von außerhalb der Klasse soll das Spielfeld manipuliert werden können.
 

NeoLexx

Mitglied
Warum hat das Spielfeld soviele Dimensionen?

Das wird nicht leicht sein, damit umzugehen. Evtl. gibt es eine bessere Lösung.

Ich möchte das Spielfeld auf die Art darstellen können wie auf dem Bild zu sehen:

screen.jpg

Es ergeben sich außerdem nachvollziehbare Koordinaten wie z.b. 32 4 . 22 11 . 5 6 diese.

Wobei ich mir schon überlege das Ganze auf 4 Dimensionen zu reduzieren. da 32^6 doch etwas viele Felder sind.

Bin gerne bereit mir deine Version anzuhören..
 

temi

Top Contributor
Kann man sich das so ähnlich hineinzoomen vorstellen? Also jedes einzelne der 32x32 Felder ist noch zweimal in weitere 32x32 Felder eingeteilt?

Vielleicht wäre es einfacher nur die vorhandenen Objekte mit ihrer Koordinate in einer Liste zu speichern?
 

NeoLexx

Mitglied
Kann man sich das so ähnlich hineinzoomen vorstellen? Also jedes einzelne der 32x32 Felder ist noch zweimal in weitere 32x32 Felder eingeteilt?

Vielleicht wäre es einfacher nur die vorhandenen Objekte mit ihrer Koordinate in einer Liste zu speichern?
Ja genau. Leider sind die Ebenen auf dem Bild falsch beziffert. Eigentlich sind es die Ebenen 1, 2 und 3. Wobei die 3te den voll eingezoomten Zustand darstellt. Stell dir jetzt vor, auf der Ebene 2 ist auf Feld (2,2) eine Sonne, dann muss die Folge-Ebene (Ebene 3) von Feld (2,2) auf jeden Fall auch eine Sonne beherbergen und mit hocher Wahrscheinlichkeit auch Planeten.

Jedem Feld einer jeden Ebene wird ein Integer Wert zugeordnet. Auf Ebene 3. kommen z.b. folgende Werte vor:
1=Planet, 2=Asteroid, 3=Komet, ... usw.
Feldern der Ebene 2 können z.b. folgende Werte und ihre Entsprechungen zugrunde liegen:
1=Sonne Typ 1a, 2=Binärsystem, 3= Neutronenstern, 0=Leerer Raum, usw...
Auf diese Weise habe ich vor eine Spielwelt zu generieren, auf der sich dann auch unatürliche Objekte befinden können, wie z.b. auch das Spieler Schiff.

Ich bin von meinem Vorhaben noch weit weg, aber vielleicht gibt dir das Stück Code, dass ich seit heute morgen dazu programmiert habe, noch einen besseren Einblick als meine Erklärungsversuche es in der Lage sind:
Java:
package Game;
import java.util.Random;

public class CreateUniverse {
    int length;
    int [] [] [] [] [] [] universum;
    int objekts=15;
    String [] typobjuni = new String [objekts];
    int [] typobjunipos = new int [objekts];
    Random randomgen = new Random();
    
    public void settypobjuni () {
        typobjuni [0]= "Leerer Raum";//80%
        typobjuni [1]= "Planet";//1%
        typobjuni [2]= "Mond";//2%
        typobjuni [3]= "Asteroid";//5%
        typobjuni [4]= "Nebel";//4%
        typobjuni [5]= "Pulsar";//0,1%
        typobjuni [6]= "Neutronenstern";//0,1%
        typobjuni [7]= "roter Rieße";//0,1%
        typobjuni [8]= "schwazes Loch";//0,1%
        typobjuni [9]= "Anomalie Typ A";//4%
        typobjuni [10]= "Planet Typ B";//4%
    }
    public void settypobjunipos () {
        typobjunipos [0] =80;
        typobjunipos [1] =1;
        typobjunipos [2] =2;
        typobjunipos [3] =5;
        typobjunipos [4] =4;
        typobjunipos [5] =0;
        typobjunipos [6] =0;
        typobjunipos [7] =0;
        typobjunipos [8] =0;
        typobjunipos [9] =4;
        typobjunipos [10] =4;
    }
    public CreateUniverse (int a) {
        length= a;
        universum = new int [length] [length] [length] [length] [length] [length];
    }

    public void setuniverse () {   
        int x;
        int y;
        int xx;
        int yy;
        int xxx;
        int yyy;
        for(int iyyy=1; iyyy<length; iyyy++) {
            yyy=iyyy;
            for(int ixxx=1; ixxx<length;ixxx++) {
                xxx=ixxx;
                for (int iyy=1; iyy<length; iyy++) {
                    yy=iyy;
                    for (int ixx=1; ixx<length; ixx++) {
                        xx=ixx;
                        for (int iy=1;iy< length;iy++) {
                                    y=iy;
                                    for (int ix=1;ix< length;ix++) {
                                        x=ix;
                                        int random = randomgen.nextInt(100);
                                        if (random<typobjunipos[0]) {
                                        universum [yyy][xxx][yy][xx][y][x] = 0;
                                        } else if (random<typobjunipos[1]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 1;
                                        }else if (random<typobjunipos[2]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 2;
                                        }else if (random<typobjunipos[3]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 3;
                                        }else if (random<typobjunipos[4]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 4;
                                        }else if (random<typobjunipos[5]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 5;
                                        }else if (random<typobjunipos[6]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 6;
                                        }else if (random<typobjunipos[7]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 7;
                                        }else if (random<typobjunipos[8]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 8;
                                        }else if (random<typobjunipos[9]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 9;
                                        }else if (random<typobjunipos[10]) {
                                            universum [yyy][xxx][yy][xx][y][x] = 10;
                                        }
                                    }
                        }
                    }
                }
            }
        }
        }
    public int readuniverse (int xxx, int yyy, int xx, int yy, int x, int y) {
        return universum [yyy][xxx][yy][xx][y][x];
        
    }
    

}

Das ganze hat übrigens die Motivation mir das Java-Programmieren beizubringen, wenn dabei noch ein nettes Spiel rauskommt ist das ein nice to have.
 

mihe7

Top Contributor
Dein Modell ist, sagen wir mal, nicht sonderlich effizient.

Du hast in der ersten Ebene 2^10 Felder, die zweite Ebene teilt jedes dieser 2^10 Felder wiederum in 2^10 Felder ein, so dass dort 2^20 Felder entstehen. Für vier Ebenen werden also 2^10 + 2^20 + 2^30 + 2^40 = 1.100.586.419.200 Felder beschrieben, die jeweils einen Wert von 32 Bit aufnehmen würden, das wären also knapp 4,4 TB an Hauptspeicher.

Tatsächlich wirst Du aber keine 4,4 Billionen Informationen benötigen sondern nur einen Bruchteil davon. Insofern ist es sinnvoll, nur die benötigten Informationen inkl. ihrer Koordinaten zu speichern.
 
K

kneitzel

Gast
Also das wird so nicht funktionieren mit den Zufallswerten.

Du berechnet einen Zufallswert bis 100 und schaust dann: ist er kleiner als 80? Ok, kann man so sehen, aber alle dann folgenden Checks sind alle nie wahr. Wenn die Zufallszahl nicht kleiner 80 war, dann wird sie auch nicht kleiner als 5 oder so sein.

Also wenn, dann musst du alle möglichen Zahlen / Zahlenbereiche abdecken ... also 0-80, 81-85, ... dann wird ein Schuh draus.

Und wenn du die Prozente als int nimmst, dann hast du 0% Wahrscheinlichkeit für manche Dinge? Wenn es die nicht geben kann, dann kannst du es auch aus dem Code heraus nehmen ....
 

temi

Top Contributor
Mal ein Vorschlag, wie ich das gemeint habe.

Der Vorteil ist, dass der "Leerraum" keinen Platz benötigt, weil in der Liste nur tatsächliche interstellare Objekte aufgeführt sind.

Java:
// interface für alle interstellaren Objekte
public interface InterstellarObj {
    Position getPosition(); // wie Position funktioniert kannst du bestimmen, entweder ein Kubus mit x,y,z oder vielleicht das galaktische Koordinatensystem?
}

// Beispielobjekt Stern
public class Star implements InterstellarObj {
    private Position position;
    private String name;

    public Star(Position position, String name) {
        this.position = position;
        this.name = name;
    }

    @Override
    public Position getPosition() {
        return position;
    }

    @Override
    public String toString() {
        return name;
    }
}

// oder Planet (nur umrissen)
public class Planet implements InterstellarObj {
    // siehe Klasse Star
}

// Das Universum
public class Universe {
    private List<InterstellarObj> interstellarObjects = new ArrayList<>(); // oder eine Map<Position, InterstellarObj> damit man besseren Zugriff über die Position hat.

    public void add(InterstellarObj object) {
        this.interstellarObjects.add(object);
    }
}

// Hauptprogramm

Universe universe = new Universe();

InterstellarObj sun = new Star(new Position(x,y,z), "Sonne"); // x,y,z sind nur Platzhalter

universe.add(sun); // jetzt hat das Universum eine Sonne :)

https://de.wikipedia.org/wiki/Galaktisches_Koordinatensystem
 
Zuletzt bearbeitet:

NeoLexx

Mitglied
Meine Güte so viel zu beantworten, wann soll ich dann noch Coden :D. Nein nur Spaß, danke für euren Input, für diese tolle konstruktive Kritik.

Dein Modell ist, sagen wir mal, nicht sonderlich effizient.

Du hast in der ersten Ebene 2^10 Felder, die zweite Ebene teilt jedes dieser 2^10 Felder wiederum in 2^10 Felder ein, so dass dort 2^20 Felder entstehen. Für vier Ebenen werden also 2^10 + 2^20 + 2^30 + 2^40 = 1.100.586.419.200 Felder beschrieben, die jeweils einen Wert von 32 Bit aufnehmen würden, das wären also knapp 4,4 TB an Hauptspeicher.

Tatsächlich wirst Du aber keine 4,4 Billionen Informationen benötigen sondern nur einen Bruchteil davon. Insofern ist es sinnvoll, nur die benötigten Informationen inkl. ihrer Koordinaten zu speichern.
Ja, das war mir auch schon aufgefallen, dass es so viel Speicher in Anspruch nimmt. Aber ich komme bei drei Ebenen auf 32x32 pro Ebene (also 2^10) und das ganze in dreifacher Ausführung also, 32^6=1.073.741.824 Felder. Oder habe ich jetzt ein Denkfehler? Wobei das auch schon zu viel ist.
Ich stimme vollkommen überein mit der Tatsache, dass ich hier effizienter werden muss.

Meine bisherige Überlegung ist die, dass ich hier auf die dritte Ebene verzichte und somit nur noch zwei Ebenen verwende. Das wird schon mal einiges an Platz sparen.
Außerdem hatte ich gerade eine Idee:
Sehe ich das richtig, dass ich mir eine eigene Zahlenmenge basteln kann, die dann z.b. so aussieht M={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} Und ich somit viel weniger Speicherplatz reserviere? Falls das möglich ist könnte ich das "universe" Array vom Typ diesere Zahlenmenge schaffen. Ließe dann pro Feld nur eine von 15 Zahlen zu?

Also das wird so nicht funktionieren mit den Zufallswerten.

Du berechnet einen Zufallswert bis 100 und schaust dann: ist er kleiner als 80? Ok, kann man so sehen, aber alle dann folgenden Checks sind alle nie wahr. Wenn die Zufallszahl nicht kleiner 80 war, dann wird sie auch nicht kleiner als 5 oder so sein.

Also wenn, dann musst du alle möglichen Zahlen / Zahlenbereiche abdecken ... also 0-80, 81-85, ... dann wird ein Schuh draus.

Und wenn du die Prozente als int nimmst, dann hast du 0% Wahrscheinlichkeit für manche Dinge? Wenn es die nicht geben kann, dann kannst du es auch aus dem Code heraus nehmen ....
Ja, das ist mir auch schon aufgefallen, deswegen hatte ich da schon etwas nachgebessert. Bisher sieht der Code in dem Bereich wie folgt aus und wird sich da sicherlich von Tag zu Tag noch stark ändern.

Edit: Mir ist klar, dass es so auch nicht funktionieren wird. Zurzeit habe ich aber viel mehr mit der Syntax von Java zu kämpfen als mit solchen logischen Überlegungen. Was mich fast den ganzen Tag beschäftige hat, ist die Tatsache, dass ich die Initialisierung der Variablen "typobjunipos" innerhalb der Methode "setuniverse" codieren musste.
Java:
public void setuniverse () {
        typobjunipos [0] =80;
        typobjunipos [1] =15;
        typobjunipos [2] =5;
        typobjunipos [3] =8;
        typobjunipos [4] =9;
        typobjunipos [5] =0;
        typobjunipos [6] =0;
        typobjunipos [7] =0;
        typobjunipos [8] =0;
        typobjunipos [9] =8;
        typobjunipos [10] =8;
        for(int iyyy=0; iyyy<length; iyyy++) {
       
            for(int ixxx=0; ixxx<length;ixxx++) {
           
                for (int iyy=0; iyy<length; iyy++) {
               
                    for (int ixx=0; ixx<length; ixx++) {
                   
                        for (int iy=0;iy< length;iy++) {
                               
                                    for (int ix=0;ix<length;ix++) {
                                   
                                        int random = randomgen.nextInt(100);
                                        System.out.println(typobjunipos[1]); //DEBUG
                                        if (random<typobjunipos[0]) {
                                        universum [iyyy][ixxx][iyy][ixx][iy][ix] = 0;
                                        }
                                        if (random<typobjunipos[1]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 1;
                                            }
                                        if (random<typobjunipos[2]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 2;
                                            }
                                        if (random<typobjunipos[3]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 3;
                                            }
                                        if (random<typobjunipos[4]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 4;
                                            }
                                        if (random<typobjunipos[5]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 5;
                                            }
                                        if (random<typobjunipos[6]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 6;
                                            }
                                        if (random<typobjunipos[7]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 7;
                                            }
                                        if (random<typobjunipos[8]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 8;
                                            }
                                        if (random<typobjunipos[9]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 9;
                                            }
                                        if (random<typobjunipos[10]) {
                                            universum [iyyy][ixxx][iyy][ixx][iy][ix] = 0;
                                            }
                                    }
                        }
                    }
                }
            }
        }
        }

Mir ist klar, dass alles was mit 0 angegeben ist ein Wahrscheinlichkeit von 0% darstellt. Ursprünglich hatte ich für 5,6,7 und 8 Wahrscheinlichkeiten von kleiner als 1% vorgesehen, als Integer nicht darstellbar, falls man dern Wert von 1 =1% zuordnet, daher habe ich sie Übergangsweise auf 0 gestellt.

Mal ein Vorschlag, wie ich das gemeint habe.

Der Vorteil ist, dass der "Leerraum" keinen Platz benötigt, weil in der Liste nur tatsächliche interstellare Objekte aufgeführt sind.

Java:
// interface für alle interstellaren Objekte
public interface InterstellarObj {
    Position getPosition(); // wie Position funktioniert kannst du bestimmen, entweder ein Kubus mit x,y,z oder vielleicht das galaktische Koordinatensystem?
}

// Beispielobjekt Stern
public class Star implements InterstellarObj {
    private Position position;
    private String name;

    public Star(Position position, String name) {
        this.position = position;
        this.name = name;
    }

    @Override
    public Position getPosition() {
        return position;
    }

    @Override
    public String toString() {
        return name;
    }
}

// oder Planet (nur umrissen)
public class Planet implements InterstellarObj {
    // siehe Klasse Star
}

// Das Universum
public class Universe {
    private List<InterstellarObj> interstellarObjects = new ArrayList<>(); // oder eine Map<Position, InterstellarObj> damit man besseren Zugriff über die Position hat.

    public void add(InterstellarObj object) {
        this.interstellarObjects.add(object);
    }
}

// Hauptprogramm

Universe universe = new Universe();

InterstellarObj sun = new Star(new Position(x,y,z), "Sonne"); // x,y,z sind nur Platzhalter

universe.add(sun); // jetzt hat das Universum eine Sonne :)

https://de.wikipedia.org/wiki/Galaktisches_Koordinatensystem
Deine Idee "Der Vorteil ist, dass der "Leerraum" keinen Platz benötigt, weil in der Liste nur tatsächliche interstellare Objekte aufgeführt sind." finde ich jedoch echt gut und ich werde darüber nachdenken ob und wie ich es einbauen kann den Code. Deinen Code schau ich mir aber erstmal nicht an, da ich gerne versuchen möchte selber drauf zu kommen. Erst wenn ich merke, dass ich gar nicht weiter komme, möchte ich auf diese Art von Hilfe zurückgreifen.
 
Zuletzt bearbeitet:

temi

Top Contributor
Deinen Code schau ich mir erstmal nicht an, da ich gerne versuchen möchte selber drauf zu kommen.

Das ist ein guter Vorsatz, aber im Ernst jetzt: Es ist absolut angebracht sich den Code von anderen anzuschauen. Natürlich sieht man auch viel Mist, aber man kann nur daraus lernen. Falls du unbedingt "allein" drauf kommen willst, dann schau dir mal Java List<> und Map<> an (so der Wissenstand bereits ausreichend ist, ich weiß nicht wo du "stehst").
Edit: Du kannst natürlich auch beim Array bleiben und etwas wie InterstellarObj[] objects machen. Das ist dann ein Array von Objekten, inkl. ihrer Position.

Meine empfohlene Vorgehensweise ist:
  1. Grundlagen von Java lernen (da gehören GUI noch nicht dazu!)
  2. Wenigstens die SOLID-Prinzipien UND Entwurfsmuster anschauen (Buchtip: Entwurfsmuster von Kopf bis Fuß)
  3. Immer auch mal den Code von anderen anschauen. Es gibt so viele gute Programmierer. Da darf man sich durchaus was abschauen.
 
Zuletzt bearbeitet:

mihe7

Top Contributor
Aber ich komme bei drei Ebenen auf 32x32 pro Ebene (also 2^10) und das ganze in dreifacher Ausführung also, 32^6=1.073.741.824 Felder. Oder habe ich jetzt ein Denkfehler? Wobei das auch schon zu viel ist.
Wir haben einfach unterschiedliche Annahmen:
1. Du rechnest mit drei, ich mit vier Ebenen: 32^6 = 2^30
2. Wenn Du in jede Ebene Inhalte separat speichern willst, addieren sich die Zahlen.

Sehe ich das richtig, dass ich mir eine eigene Zahlenmenge basteln kann, die dann z.b. so aussieht M={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} Und ich somit viel weniger Speicherplatz reserviere? Falls das möglich ist könnte ich das "universe" Array vom Typ diesere Zahlenmenge schaffen. Ließe dann pro Feld nur eine von 15 Zahlen zu?
?!?

Der Weg ist normalerweise der, wie ich oben geschrieben bzw. @temi gezeigt hat: man speichert nur die Objekte, die man wirklich braucht, inkl. ihrer Koordinaten.

Die Darstellung ist davon unabhängig.
 
K

kneitzel

Gast
Und auch wenn man entsprechend viele Daten hat: Da hält man nur die Bereiche im Speicher, die man braucht. Wenn Du eine große Map hast mit so vielen Feldern. Selbst wenn Du nur speicherst, wo etwas ist, wäre bei einer Wahrscheinlichkeit von 80% Leere immer noch 1/5 des Speicherplatzes benötigt.

Und der Zugriff über den Index geht nicht mehr, d.h. wir müssen die Koordinate noch speichern, so dass wir dann nur eine Einsparung von ca. 50% haben würden.

Wenn die 4,4 TB aus #17 annehmen, dann wären das also immer noch 2TB. Die im Speicher zu halten ist irgendwie utopisch.

Also muss die Map unterteilt werden um dann nur noch Bereiche im Speicher zu halten. Da bieten sich dann auch schnell Datenbanken an. Oder wenn Du eh alles per Zufall generieren willst, dann kannst Du das Generieren evtl. erst bei Bedarf machen. Wobei Du dann ggf. eine Datenbank bemühen musst um den Zustand zu speichern, so Du diesen noch haben willst, wenn Du z.B. zurück kehrst....
 

NeoLexx

Mitglied
Als erstes muss ich feststellen, dass es schon sehr spät ist und meine Fähigkeit, verständlich zu schreiben, nachlässt. Verzeiht mir also, falls ich mich etwas unklar ausdrücke.

Das ist ein guter Vorsatz, aber im Ernst jetzt: Es ist absolut angebracht sich den Code von anderen anzuschauen. Natürlich sieht man auch viel Mist, aber man kann nur daraus lernen. Falls du unbedingt "allein" drauf kommen willst, dann schau dir mal Java List<> und Map<> an (so der Wissenstand bereits ausreichend ist, ich weiß nicht wo du "stehst").
Edit: Du kannst natürlich auch beim Array bleiben und etwas wie InterstellarObj[] objects machen. Das ist dann ein Array von Objekten, inkl. ihrer Position.

Meine empfohlene Vorgehensweise ist:
  1. Grundlagen von Java lernen (da gehören GUI noch nicht dazu!)
  2. Wenigstens die SOLID-Prinzipien UND Entwurfsmuster anschauen (Buchtip: Entwurfsmuster von Kopf bis Fuß)
  3. Immer auch mal den Code von anderen anschauen. Es gibt so viele gute Programmierer. Da darf man sich durchaus was abschauen.

Wollte da gar nicht blöd rüber kommen. Ich wollte mir deinen Code nur deswegen nicht direkt ansehen, damit ich erstmal selber darüber nachdenken kann. Und dann im Anschluss werde ich mir den Code auf jeden Fall genau ansehen. Habe mich da wohl etwas unglücklich ausgedrückt.
Danke für deine invitierte Zeit, sie ist auf jeden Fall nicht umsonst gewesen.

Wir haben einfach unterschiedliche Annahmen:
1. Du rechnest mit drei, ich mit vier Ebenen: 32^6 = 2^30
2. Wenn Du in jede Ebene Inhalte separat speichern willst, addieren sich die Zahlen.


?!?

Der Weg ist normalerweise der, wie ich oben geschrieben bzw. @temi gezeigt hat: man speichert nur die Objekte, die man wirklich braucht, inkl. ihrer Koordinaten.

Die Darstellung ist davon unabhängig.
Alles klar, eure Idee, nur dort Speicher zu benutzen wo sich auf dem Spielfeld auch was befindet, ist super. Und am ende werde ich wahrscheinlich auch so umsetzen.

Wollte noch eben auf meine Erklärung eingehen da du sie wohl nicht verstanden hast:
Es geht ja um diese Aussage:
"Außerdem hatte ich gerade eine Idee:
Sehe ich das richtig, dass ich mir eine eigene Zahlenmenge basteln kann, die dann z.b. so aussieht M={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} Und ich somit viel weniger Speicherplatz reserviere? Falls das möglich ist könnte ich das "universe" Array vom Typ diesere Zahlenmenge schaffen. Ließe dann pro Feld nur eine von 15 Zahlen zu? "

In Java sind verschiedene Datentypen vordefiniert wie Int , long, und so weiter. Bei der Deklaration einer Int Variablen werden ja jeweils 4 byte Speicher reserviert. Mit diesen 4byte Speicher lassen sich Dezimalzahlen zwischen -2^31 und 2^31-1 codieren. Was für meine Bedürfnisse ja viel zu viel ist. Ich werde etwas zwischen 15 und 25 verschiedene Typen von Objekten auf dem Spielfeld platzieren. Also brauche ich einen Daten-Typ, ich nenne ihn jetzt mal TypUniversum der nur folgende Zahlen Codieren kann: 0,1,2,3,4,5,6,7,8,9,10,11,12,...,25 Jedes mal also, wenn ich eine Variable diesen Typs deklariere, dann wird sie deutlich weniger Speicher reservieren müssen wie z.b der Datentyp short oder byte, vorausgesetzt das ist überhaupt möglich mit Java. Und das würde ja das Problem mit dem Speicher aus einer anderen Richtung angehen. Und warum das Ganze Speicher-Optimierungsproblem nicht aus zwei Richtung angehen?

Und auch wenn man entsprechend viele Daten hat: Da hält man nur die Bereiche im Speicher, die man braucht. Wenn Du eine große Map hast mit so vielen Feldern. Selbst wenn Du nur speicherst, wo etwas ist, wäre bei einer Wahrscheinlichkeit von 80% Leere immer noch 1/5 des Speicherplatzes benötigt.

Und der Zugriff über den Index geht nicht mehr, d.h. wir müssen die Koordinate noch speichern, so dass wir dann nur eine Einsparung von ca. 50% haben würden.

Wenn die 4,4 TB aus #17 annehmen, dann wären das also immer noch 2TB. Die im Speicher zu halten ist irgendwie utopisch.

Also muss die Map unterteilt werden um dann nur noch Bereiche im Speicher zu halten. Da bieten sich dann auch schnell Datenbanken an. Oder wenn Du eh alles per Zufall generieren willst, dann kannst Du das Generieren evtl. erst bei Bedarf machen. Wobei Du dann ggf. eine Datenbank bemühen musst um den Zustand zu speichern, so Du diesen noch haben willst, wenn Du z.B. zurück kehrst....

Daran eine externe Speicherquelle zu verwenden habe ich auch schon nachgedacht. Nur das Umfeld um den Spieler herum zu generieren und das Ganze, sobald der Spieler den Ort des Geschehens verlässt, zu speichern, würde ich, aus folgendem Grunde, nur sehr ungern tun. Ich möchte versuchen ein stark vereinfachtes Model einer Galaxie zu simulieren, es sollen sich Ereignisse abspielen, auch wenn das Spieler Raumschiff nicht anwesend ist. Bedenkt bitte, dass dieses Spiel, im Moment, nur als Konzept, in dem Kopf eines Menschen existiert, der sich mit Programmierung nicht auskennt. Zwangsläufig werde ich so mit der einen oder anderen Idee anecken.

Ihr seid aber echt Klasse, kann mich hier nur nochmal bei euch bedanken für die Zeit die ihr investiert.
 

mihe7

Top Contributor
Also brauche ich einen Daten-Typ, ich nenne ihn jetzt mal TypUniversum der nur folgende Zahlen Codieren kann
Du kannst in Java keinen Datentypen definieren, der Bruchteile eines Bytes belegt. Im Gegenteil: jeder selbst definierte Datentyp ist ein Referenztyp, d. h. statt nur für den Wert würde in jedem Fall zusätzlich noch Platz für die Referenz benötigt.

Wenn, dann müssest Du einen Datentypen definieren, der nach außen z. B. das komplette "Array" darstellt, intern aber die Daten gepackt ablegt (bit packing). Allerdings sparst Du damit gerade mal ca. die Hälfte an Speicher.

Ich möchte versuchen ein stark vereinfachtes Model einer Galaxie zu simulieren, es sollen sich Ereignisse abspielen, auch wenn das Spieler Raumschiff nicht anwesend ist.
Dagegen spricht die Verwendung externen Speichers nicht.

Bedenkt bitte, dass dieses Spiel, im Moment, nur als Konzept, in dem Kopf eines Menschen existiert, der sich mit Programmierung nicht auskennt. Zwangsläufig werde ich so mit der einen oder anderen Idee anecken.
Keine Angst, Du eckst damit nicht an. Es geht darum, ob und wie sich Anforderungen umsetzen lassen.
 

temi

Top Contributor
Wollte da gar nicht blöd rüber kommen. Ich wollte mir deinen Code nur deswegen nicht direkt ansehen, damit ich erstmal selber darüber nachdenken kann. Und dann im Anschluss werde ich mir den Code auf jeden Fall genau ansehen. Habe mich da wohl etwas unglücklich ausgedrückt.
Keine Sorge!

Worauf ich hinaus wollte ist, dass man beim Anschauen von fremden Code öfter mal: "Ach, so geht das auch!" Momente haben wird. So ging es mir zumindest. Und ich lese auch hier im Forum oft einfach nur mit.

Ansonsten: Ein interessantes und ambitioniertes Projekt hast du dir da vorgenommen. Möglicherweise überforderst du dich noch etwas damit, aber das wird schon mit der Zeit. Fang erst mal klein an und erweitere deine Möglichkeiten.

Wie hier schon angesprochen wurde, werden externe Datenstrukturen irgendwann wichtig werden und vermutlich auch andere Techniken. Arbeite dich in die objektorientierte Programmierung ein und deren Umsetzung mittels SOLID und Mustern. Das wird dir ganz neue Horizonte eröffnen.
 

NeoLexx

Mitglied
Kleines Update:
Zusehen ist ein Ausschnitt aus einem neu erschaffenen Universum.
eine bewohnte Welt.JPG

Darf ich vorstellen? Die markierte Drei ist ein bewohnter Planet, ich nenne ihn Java. Es gibt also kein Zweifel mehr, es gibt Leben, neben dem unseren, im Javaversum!!

Der Code soweit:
Java:
package Game;
import java.util.Random;

public class CreateUniverse {
    int length;
    //short [] [] [] [] [] [] universum;
    short [] [] universum;
    int objekts=9;
    String [] typobjuni = new String [objekts];
    short [] typobjunipos = new short [objekts];
    Random randomgen = new Random();
   
    /*public void settypobjuni () {  //Baustelle
        typobjuni [0]= "Leerer Raum";//80%
        typobjuni [1]= "Planet";//1%
        typobjuni [2]= "Mond";//2%
        typobjuni [3]= "Asteroid";//5%
        typobjuni [4]= "Nebel";//4%
        typobjuni [5]= "Pulsar";//0,1%
        typobjuni [6]= "Neutronenstern";//0,1%
       
    }*/
    /*public void settypobjunipos () { //Baustelle
        typobjunipos [0] =800;
        typobjunipos [1] =1000;
        typobjunipos [2] =20;
        typobjunipos [3] =50;
        typobjunipos [4] =40;
        typobjunipos [5] =1;
        typobjunipos [6] =1;*/
    }
    public CreateUniverse (int a) { //Wahrscheinlichkeiten für Objekte/Übergabe von Array Größe, Array deklaration
        length= a;
        universum = new short [length] [length];
        typobjunipos [0] =0; //null
        typobjunipos [1] =960; //Leerer Raum
        typobjunipos [2] =970; //Planet unbewohnt
        typobjunipos [3] =972; //Planet bewohnt
        typobjunipos [4] =980; //Asteroid leer
        typobjunipos [5] =985; //Asteroid Metale
        typobjunipos [6] =995; //Mond
        typobjunipos [7] =1000; //Anomalie
       
    }

    public void setuniverse () {   //hier wird das Universum erstellt
       
        for (int ix=0;ix< length;ix++) {
            for (int iy=0;iy<length;iy++) {
                int random = randomgen.nextInt(1000);
                for (short ipos=1;ipos<typobjunipos.length;ipos++) {
                if (random<=typobjunipos[ipos] && random>=typobjunipos[ipos-1]) {
                universum [iy][ix] = ipos;}}}}

        }
    public void visualizeUniverse () { //Ausgabe einer Karte
        for (int iy=0; iy<length; iy++) {
            System.out.println();
            for (int ix=0; ix<length; ix++) {
                System.out.print(universum [ix] [iy]+" ");
            }
        }
       
    }
    /*public int readuniverse (int xxx, int yyy, int xx, int yy, int x, int y) {
        return universum [y][x];
       
    }*/
   

}

Du kannst in Java keinen Datentypen definieren, der Bruchteile eines Bytes belegt. Im Gegenteil: jeder selbst definierte Datentyp ist ein Referenztyp, d. h. statt nur für den Wert würde in jedem Fall zusätzlich noch Platz für die Referenz benötigt.
Okay, schade.
Wenn, dann müssest Du einen Datentypen definieren, der nach außen z. B. das komplette "Array" darstellt, intern aber die Daten gepackt ablegt (bit packing). Allerdings sparst Du damit gerade mal ca. die Hälfte an Speicher.
Das ist mir doch gerade noch etwas zu viel.

Ansonsten: Ein interessantes und ambitioniertes Projekt hast du dir da vorgenommen. Möglicherweise überforderst du dich noch etwas damit, aber das wird schon mit der Zeit. Fang erst mal klein an und erweitere deine Möglichkeiten.
Habe die Erfahrung gemacht, dass ich am besten lerne, wenn die Umstände herausfordernd sind. Mal gucken, wie weit mich das Projekt in die tiefen Javas bringt.

Wie hier schon angesprochen wurde, werden externe Datenstrukturen irgendwann wichtig werden und vermutlich auch andere Techniken. Arbeite dich in die objektorientierte Programmierung ein und deren Umsetzung mittels SOLID und Mustern. Das wird dir ganz neue Horizonte eröffnen.
Werde ich mir demnächst mal ansehen.

Danke für die tollen Tipps!
 

temi

Top Contributor
Habe die Erfahrung gemacht, dass ich am besten lerne, wenn die Umstände herausfordernd sind. Mal gucken, wie weit mich das Projekt in die tiefen Javas bringt.

Ich denke du wirst feststellen, dass sich dein Projekt im Laufe der Zeit anders entwickeln wird. So kannst du davon ausgehen, dass du von Arrays irgendwann zu Kollektionen wechseln wirst. Und diese Kollektionen irgendwann aus einer DB lesen wirst. Du wirst also dein Programm mit steigendem Wissenstand immer wieder neu organisieren. Das wird ganz sicher eine spannende Reise für dich werden.
 

temi

Top Contributor
Noch kurz ein paar Anmerkungen zu deinem bisherigen Programm.

Klassennamen sind in der Regel Substantive, z.B. Tier, Haus, Universum. Methodennamen dagegen meist Verben, z.B. createUniverse(), getUniverse(), setUniverse(). Eine kleine Abweichung gibt es bei Methoden, die als Rückgabewert ein boolean haben, die werden häufig isEmpty(), hasStars() benannt.

Eine Besonderheit sind noch die Getter- und Settermethoden (getXXX(), setXXX()), die für den Zugriff auf Instanzvariablen verwendet werden. Wobei der direkte Zugriff auf Instanzvariablen soweit wie möglich beschränkt werden sollte. Ein Setter hat damit auch normalerweise einen Parameter (der Wert, der gesetzt werden soll).

In dieser Hinsicht solltest du dir deine Benennungen noch einmal durch den Kopf gehen lassen und auch über die Sichtbarkeit von Methoden nachdenken, z.B.
Java:
public class Universe {
    
    private int length;
    private short[][] universe;
    
    public Universe(int lenght) {
        
    }

    // anstelle von setUniverse(), weil das kein typischer Setter ist
    // kann evt. private sein und im Konstruktor aufgerufen werden.
    public void createRandomUniverse() {

    }
}

Das sind nur Kleinigkeiten, aber es ist gut sich solche Regeln gleich von Anfang an anzugewöhnen.

Außerdem solltest du dir überlegen, die Visualisierung aus der Klasse herauszuhalten. Normalerweise trennt man die UI von der Logik. Verwende stattdessen einen Getter, der dir den Zugriff auf die Objekte im Universum erlaubt und greif über diesen in einer separaten Ausgabe darauf zu. Das macht es dir später mal einfacher, wenn du von der Konsole auf eine grafische Oberfläche wechseln möchtest (was du jetzt unbedingt noch nicht machen sollst!!!!)
 

NeoLexx

Mitglied
Ich denke du wirst feststellen, dass sich dein Projekt im Laufe der Zeit anders entwickeln wird. So kannst du davon ausgehen, dass du von Arrays irgendwann zu Kollektionen wechseln wirst. Und diese Kollektionen irgendwann aus einer DB lesen wirst. Du wirst also dein Programm mit steigendem Wissenstand immer wieder neu organisieren. Das wird ganz sicher eine spannende Reise für dich werden.
So eine Entwicklung wäre natürlich optimal.

Noch kurz ein paar Anmerkungen zu deinem bisherigen Programm.

Klassennamen sind in der Regel Substantive, z.B. Tier, Haus, Universum. Methodennamen dagegen meist Verben, z.B. createUniverse(), getUniverse(), setUniverse(). Eine kleine Abweichung gibt es bei Methoden, die als Rückgabewert ein boolean haben, die werden häufig isEmpty(), hasStars() benannt.
Dass es die eine oder andere Konvention gibt, war mir klar und du wirst es nicht glauben, aber heute morgen habe ich bereits angefangen das eine oder andere entsprechende umzubenennen.

Eine Besonderheit sind noch die Getter- und Settermethoden (getXXX(), setXXX()), die für den Zugriff auf Instanzvariablen verwendet werden. Wobei der direkte Zugriff auf Instanzvariablen soweit wie möglich beschränkt werden sollte. Ein Setter hat damit auch normalerweise einen Parameter (der Wert, der gesetzt werden soll).
Ja, ich denke das wird eins meiner nächsten Lernfelder sein.
Außerdem solltest du dir überlegen, die Visualisierung aus der Klasse herauszuhalten. Normalerweise trennt man die UI von der Logik. Verwende stattdessen einen Getter, der dir den Zugriff auf die Objekte im Universum erlaubt und greif über diesen in einer separaten Ausgabe darauf zu. Das macht es dir später mal einfacher, wenn du von der Konsole auf eine grafische Oberfläche wechseln möchtest (was du jetzt unbedingt noch nicht machen sollst!!!!)
Okay, hört sich sinnvoll an. Dadurch erhalte ich mir eine gute Flexibilität im Programm.

Übrigens habe ich nochmals das Konzept für die Generierung der SolarKarten überdacht. Ich denke, dass ich für jedes SolarKarte eine größe von 51x51 festlege und die Karte von Feld (26,26) aus, wo sich dann jeweils die Sonne befindet, Spiralförmig gegen den Uhrzeigersinn Generierenen lasse. Planeten entstehen dann im Radius um die Sonne herum, genau so wie Monde im Radius um Planeten gesetzt werden, und später ließe sich sogar eine Rotation der Stellarobjekte um die Sonne herum realisieren und die Rotation der Monde um die Planeten natürlich auch. So stelle ich mir das ganze vor:

überschreiben bilddatei.JPG

Da es hier schon lange nicht mehr darum geht: "Variable für Array wird nicht korrekt übergeben" Die Bitte an jemanden, der hier verantwortlich ist, diesen Post 1. nach "Spiele- und Multimedia-Programmierung" zu verschieben und 2. den Titel des Post in "Spiel Entwicklung - Lost in Andromeda" zu ändern. Denn ich würde gerne die Entwicklung des Spiels und die damit auftreffenden Probleme, gebündelt in diesem Post, abhandeln. Natürlich nur falls das okay ist.
 

temi

Top Contributor
Überlege dir mal, ob du nicht bereits an dieser Stelle den Hinweis umsetzt, nur vorhandene Objekte zu speichern. Das kannst du auch zunächst mit einem Array realisieren.

Du benötigst dazu nur eine Klasse, die die gespeicherten Objekte repräsentiert und wenigstens eine Positionsangabe und die Art des Objekts enthält (inkl. Getter für die Koordinaten und den Typ).

Damit kannst du deine Karte virtuell mit den gewünschten Abmessungen aufspannen und darin die gewünschte Anzahl von Objekten plazieren: InterstellarObj[] objects = new InterstellarObj[objectsCount];

Tatsächlich habe ich mir auch mal ein paar Gedanken gemacht, wie man z.B. die Rotation von Planeten realisieren könnte. Ich bin zum Schluss gekommen, dass ich den Stellaren Objekten zur Position noch eine Rotationsgeschwindigkeit und einen Zeitpunkt, für den diese Position gilt mitgeben würde. Sobald man die Karte anzeigen möchte, muss dann zuerst aus diesen Angaben die aktuelle Position berechnet werden (evtl. mit Zeitraffer). Das würde ich etwas vereinfachen, weil eine korrekte astronomische Umsetzung der elliptischen Bahnen meine mathematischen Fähigkeiten überschreitet. ;)

Edit:

Mir fällt gerade auf, und ich denke hier mal laut vor mich hin, dass deine Planeten auch noch Monde haben und ggf. Raumschiffe, die um den Mond kreisen. Wenn man sich das so betrachtet, dann erkennt man:
  1. Monde, um die Raumschiffe kreisen
  2. Planeten, um die Monde kreisen
  3. Sonnen, um die Planeten kreisen
  4. Galaxien, um die Sonnen kreisen
Da ist ein erkennbares Muster: Ein Objekt kreist um ein anderes Objekt, aber generell verhalten sich alle Objekte identisch. Damit könnte man es einem InterstellarObj ermöglichen, wiederum InterstellarObjs zu enthalten und das hierarchisch aufzubauen, z.B.:
Java:
InterstellarObj ship = new InterstellarObj(...); // Parameter lass ich mal weg...
InterstellarObj moon = new InterstellarObj(...);
InterstellarObj earth = new InterstellarObj(...);
InterstellarObj sun = new InterstellarObj(...);

sun.add(earth); // earth kreist um sun
earth.add(moon); // moon kreist um earth
moon.add(ship); // ship kreist um moon
Noch nicht ausgereift, aber den Gedanken solltest du für die Zukunft im Hinterkopf behalten. Damit kann sich "sun" um die Berechnung ihrer Position kümmern und jeweils relativ dazu alle untergeordneten Objekte ihre eigenen Positionen berechnen.
 
Zuletzt bearbeitet:

NeoLexx

Mitglied
Überlege dir mal, ob du nicht bereits an dieser Stelle den Hinweis umsetzt, nur vorhandene Objekte zu speichern. Das kannst du auch zunächst mit einem Array realisieren.
Soweit ich dich da richtig verstanden hatte, habe ich heute morgen schon damit angefangen, siehe folgenden Code. Habe es wohl etwas anderes Umgesetzt, aber ich glaube von der Funktion ist es sehr ähnlich.

Tatsächlich habe ich mir auch mal ein paar Gedanken gemacht, wie man z.B. die Rotation von Planeten realisieren könnte. Ich bin zum Schluss gekommen, dass ich den Stellaren Objekten zur Position noch eine Rotationsgeschwindigkeit und einen Zeitpunkt, für den diese Position gilt mitgeben würde. Sobald man die Karte anzeigen möchte, muss dann zuerst aus diesen Angaben die aktuelle Position berechnet werden (evtl. mit Zeitraffer). Das würde ich etwas vereinfachen, weil eine korrekte astronomische Umsetzung der elliptischen Bahnen meine mathematischen Fähigkeiten überschreitet. ;)
An sowas hatte ich auch schon gedacht, sollte sich später relativ leicht upgraden lassen.

Mir fällt gerade auf, und ich denke hier mal laut vor mich hin, dass deine Planeten auch noch Monde haben und ggf. Raumschiffe, die um den Mond kreisen. Wenn man sich das so betrachtet, dann erkennt man:
  1. Monde, um die Raumschiffe kreisen
  2. Planeten, um die Monde kreisen
  3. Sonnen, um die Planeten kreisen
  4. Galaxien, um die Sonnen kreisen
Da ist ein erkennbares Muster: Ein Objekt kreist um ein anderes Objekt, aber generell verhalten sich alle Objekte identisch. Damit könnte man es einem InterstellarObj ermöglichen, wiederum InterstellarObjs zu enthalten und das hierarchisch aufzubauen, z.B.:
Ja, klar. Da lässt sich sicherlich eine Methode schreiben, die dann auf alle beliebigen Objekte anwendbar ist. Gehen wir von der Sonne aus die auf (26,26) sitzt, dann gehen folgende Wert in die Methode rein: Koordinaten der Sonne x y, Geschwindigkeit des Objekts, Koordinaten des Objekts. Raus kommen die neuen Koordinaten des Objekts... (Das ganze Game wird wohl Runden-basierend sein, wobei eine Runde etwa 1/4 eines Tages entsprechen werden). Daraus lässt sich eine Rotation pro Runden ableiten. Jedoch macht das nur Sinn, falls die Rotation der Objekte auch sinvoll ins Gameplay integriert werden, da muss ich mir noch Gedanken zu machen.

Möchte folgende Schritte als nächstes gehen:
1. Die Erschaffung der Galaxie (des Spielfeldes) ist fertig Programmiert.
2. Implementierung des Spieler-Schiffes (mit Attributen, verschiedenen Systemen, usw.) Es dient als Basis aller Schiffe in der Galaxie.. (wird also im Programm eine Klasse darstellen)
3. Schaffung eines ersten UserInterface.


Ich habe die Generierung des Spielfeldes noch mal von neuem angefangen. Soweit bin ich heute Abend gekommen, morgen geht es erstmal weiter:
(Einige Stellen wie die Objekt-Wahrscheinlichkeiten sind noch auf 0 gesetzt, dass ist klar dass sich da noch was ändern wird.. )
("placeObjektinOrbit" konnte ich noch nicht testen. Allerdings sollte es so funktionieren. Mit dieser Methode lassen sich Objekte in einem Orbit von der Weite "radius" zu einem Mittelpunkt (x,y) platzieren. Also z.b. auch ein Mond in einem Radius zu einem vorhanden Planeten usw...)
Java:
package Game;
import java.util.Random;

public class Solarsystem {
    final short size =51; //Feste größe für ein Solarsystem
    final short typamount=4; //Anzahl Sternen Sorten
    final short amountObjekts=9;
    short x; //Positon x auf der Galaxie Karte
    short y; //Postion y auf der Galaxie Karte
    short typ; //Solarsystem Typ
    short solarsystem [] []= new short [size] [size]; //hier wird das Solarsystem gespeichert
    short solarobjekts []= new short [amountObjekts];
    Random randomgen = new Random();
    int random = randomgen.nextInt(1000);
    //======================================================Anzahl diverse Objekte
    int amountplanet;
    int amountastorid;
    int amountastoridressource;
    int amountmoon;
    int amountanomaly;
    //======================================================
    public void getSolarTyp(short solartyp) {
        this.typ=solartyp;
    }
    public void setPositon (short x, short y) {
    this.x=x;
    this.y=y;
    }
 
    public void randomAmountObjekts() { // Bestimmung der Anzahl verschiedener stellarer Objekte per Zufall
        while (this.amountplanet<=2) {
            this.amountplanet=randomgen.nextInt(10); //min 2 max 10
        }
        while (this.amountmoon<=amountplanet) {
            this.amountmoon=randomgen.nextInt(amountplanet*2); //min AnzahlPlaneten max 2*AnzahlPlaneten
        }
        while (this.amountastorid<40) {
            this.amountastorid=randomgen.nextInt(80); //min 40 max 80
        }
        while (this.amountastoridressource<40) {
            this.amountastoridressource=randomgen.nextInt(80); //min 40 max 80
        }
        this.amountanomaly=randomgen.nextInt(5); //Anomalie max 5
     
    }
    public void defSolarObjektPoss () { //Wahrscheinlichkeiten für einzelene Objekte 1000 = 100%
        this.solarobjekts[0]=0;
        this.solarobjekts[1]=450; //Planet Stein
        this.solarobjekts[2]=980; //Planet Gas
        this.solarobjekts[3]=1000; //Planet Bewohnt
        this.solarobjekts[4]=0; //Stern
        this.solarobjekts[5]=0;    //Asteroid
        this.solarobjekts[6]=0; //Anomalie
        this.solarobjekts[8]=0;     //Mond
        this.solarobjekts[8]=0; //Asteroid Rohstoffe
    }
    public void placeObjektinOrbit (int x, int y,int radius, int typ) {  //Platizierung des Objekts vom Typ "typ" ausgehend von (x,y) mit "radius" Entferung vom Orbit per Zufall
        int xa= x+radius-1; //startkoordinate x vom Orbit
        int xa= x+radius-1; //startkoordinate x vom Orbit
        int ya= y+radius-1; //startkoordinate y vom Orbit
        //int orbit =radius;  // Orbit
        int orbitpart =(radius-1)*2;
        int scopeorbit= 4*orbitpart;  //Durchmesser Orbit (Anzahl Felder eines Orbits)
        int placerandom=randomgen.nextInt(scopeorbit-1); //Zufallsgenerator Orbit
        int newx;
        int newy;
        if (placerandom<=orbitpart) { //Quadrant rechts
            newx = xa;
            newy = ya-placerandom-0*orbitpart;
        }
        if (placerandom<=2*orbitpart && placerandom>orbitpart) { //Quadrant oben
            newx = xa-placerandom+1*orbitpart;
            newy = ya-orbitpart;
        }
        if (placerandom<=3*orbitpart && placerandom>orbitpart*2) { //Quadrant links
            newx=xa-orbitpart;
            newy=ya-orbitpart+placerandom-2*orbitpart;
        }
        if (placerandom<=4*orbitpart && placerandom>orbitpart*3) { //Quadrant unten
            newx=xa-orbitpart+placerandom-3*orbitpart;
            newy=ya;
        }
         
        this.solarsystem [newx] [newy] = typ;
        }
 
 
    public void buildSolarSystem () {
        for (int i=1;i<amountplanet;i++) {
            int randomplanet=randomgen.nextInt(1000);
            int typplanet;
            int radius=0;
            while (0==radius) {radius=randomgen.nextInt(26);}
            for (int j=0;j<3;j++) {
            if (randomplanet<=solarobjekts[j]&&randomplanet>solarobjekts[j-1]) {
                typplanet=j;
            }
            placeObjektinOrbit (26,26,radius,typplanet);
            }
        }
        for (int i=1;i<amountmoon;i++) {
            //hier geht es morgen weiter :D
        }
 
    }
}
 
Zuletzt bearbeitet:

temi

Top Contributor
Soweit ich dich da richtig verstanden hatte, habe ich heute morgen schon damit angefangen, siehe folgenden Code. Habe es wohl etwas anderes Umgesetzt, aber ich glaube von der Funktion ist es sehr ähnlich.
Nicht so ganz. Ich hab mir jetzt nicht alles angeschaut, aber soweit ich sehe, ist das die Stelle, an der ein Objekt ins Solarsystem gesetzt wird: this.solarsystem [newx] [newy] = typ;.

Das Problem ist, dass du ein Array mit einer Größe von 51x51 erstellt hast und die Werte für die Koordinaten (da sie ja gleichzeitig dem Arrayindex entsprechen) damit auch zwischen 0 und 50 liegen müssen.

Das Ziel wäre es von diesem Index unabhängig zu werden und die Position innerhalb des Objekts zu speichern, welches wiederum im Array gespeichert ist. Im einfachsten Fall ist das eine Klasse mit drei öffentlichen Instanzvariablen:
Java:
// kein richtig "gutes" Objekt, aber es funktioniert...
public class SolarObject {
    public int x;
    public int y;
    public int typ;
  
    public SolarObject(int x, int x, int typ) {
        this.x = x;
        this.y = y;
        thix.typ = typ;
    }
}

Und in der Klasse Solarsystem dann SolarObject[] solarsystem = new SolarObject[size]. In diesem Array kannst du dann "size" Objekte an beliebigen Koordinaten platzieren (Wertebereich von int).

Und noch ein paar Anmerkungen:

Es ist eine sehr gute Idee Vorgabewerte als Konstanten zu definieren. Es ist gängige Praxis, das Konstanten in Java komplett groß geschrieben werden und neben "final" auch noch "static" deklariert werden.
Java:
final static short SIZE = 51; //Feste Größe für ein Solarsystem
final static short TYP_AMOUNT = 4; //Anzahl Sternen Sorten
final static short AMOUNT_OBJECTS = 9;

Normale Variablen sollten im "lowerCamelCase" deklariert werden, also anstatt int placerandom besser int placeRandom. Das lässt sich leichter lesen.

Darf ich fragen, nach welcher Vorlage (Buch, Tutorial, ??) du Java lernst? Nur aus Neugierde.
 
Zuletzt bearbeitet:

temi

Top Contributor
Ja, klar. Da lässt sich sicherlich eine Methode schreiben, die dann auf alle beliebigen Objekte anwendbar ist. Gehen wir von der Sonne aus die auf (26,26) sitzt, dann gehen folgende Wert in die Methode rein: Koordinaten der Sonne x y, Geschwindigkeit des Objekts, Koordinaten des Objekts. Raus kommen die neuen Koordinaten des Objekts
Ich hatte das etwas anders gemeint, aber das ist wohl etwas vorgegriffen. Du denkst noch zuwenig objektorientiert (was normal ist, wenn man gerade damit begonnen hat). Das Objekt selbst (z.B. die Sonne) hat eine Methode, die ihre Position neu berechnet. Diese Methode braucht auch nicht die Position und die Geschwindigkeit als Parameter, denn als "Sonne" (das Objekt) weiß sie das schon alles.

Zusätzlich kommt dazu das Zusammenspiel zwischen verschiedenen Objekten. Wenn du sowas hast:
Java:
InterstellarObj ship = new InterstellarObj(...); // Parameter lass ich mal weg...
InterstellarObj moon = new InterstellarObj(...);
InterstellarObj earth = new InterstellarObj(...);
InterstellarObj sun = new InterstellarObj(...);

sun.add(earth); // earth kreist um sun
earth.add(moon); // moon kreist um earth
moon.add(ship); // ship kreist um moon

Dann würde es ausreichen für das übergeordnete Objekt, in diesem Fall "sun" die Berechnung auszulösen sun.calcPosition(currentTime);. Für alle untergeordneten Objekte (earth, moon, ship) wird die Berechnung dann intern ausgelöst. Da die Objekte alle vom selben Typ sind (Klasse InterstellarObj) wird auch dieselbe Methode verwendet.

Aber nimm das jetzt erst mal als mögliches Wissen für die Zukunft mit und mach in deinem Tempo weiter.
 

NeoLexx

Mitglied
Das Problem ist, dass du ein Array mit einer Größe von 51x51 erstellt hast und die Werte für die Koordinaten (da sie ja gleichzeitig dem Arrayindex entsprechen) damit auch zwischen 0 und 50 liegen müssen.
Das wäre ja nicht schlimm, da ich doch sowieso eine feste Größe für ein jedes Solarsystem festgelegt habe, es sollen jeweils 51 Felder sein. Also von 0-50. Dennoch ich würde es gerne so probieren wie von dir vorgeschlagen.

Das Ziel wäre es von diesem Index unabhängig zu werden und die Position innerhalb des Objekts zu speichern, welches wiederum im Array gespeichert ist. Im einfachsten Fall ist das eine Klasse mit drei öffentlichen Instanzvariablen:
Das verstehe ich nicht ganz.
Ich erstelle also eine neue Klasse:
Java:
package Game;

public class SolarObjekt {
    public int x;
    public int y;
    public int typ;
    
    public void SolarObject (int x, int y, int typ) {
    this.x=x;
    this.y=y;
    this.typ=typ;
    }
}
Die ich dann in der Klasse SolarSystem aufrufe, und somit dort ein Objekt der Klasse SolarObjekt erstelle. Wie kommt jetzt noch das Array ins spiel?
Und in der Klasse Solarsystem dann SolarObject[] solarsystem = new SolarObject[size]. In diesem Array kannst du dann "size" Objekte an beliebigen Koordinaten platzieren (Wertebereich von int).

Ich hätte jetzt gedacht, dass ich für jedes Objekt( Planet 1, Planet 2, Mond1, usw.), welches ich erstelle, ein neues Objekt der Klasse SolarObjekt erschaffe muss. Oder mach ich das dann mit dem Array? Ach so, ja okay. Beim danach Fragen habe ich es verstanden.

Also sind die Objekte im Solarsystem folgende: solarsystem [1], solarsystem [2], usw. Und jedes dieser Objekte ist vom Typ SolarObjekt, dass wiederum 3 Werte speichert. Später ließe sich relativ einfach eine weitere Eigenschaft hinzufügen, wie Masse oder Geschwindigkeit.

Ja, das ist eine gute Methode das ganze zu programmieren, danke für der Tipp.
s ist eine sehr gute Idee Vorgabewerte als Konstanten zu definieren. Es ist gängige Praxis, das Konstanten in Java komplett groß geschrieben werden und neben "final" auch noch "static" deklariert werden.
Java:
final static short SIZE = 51; //Feste Größe für ein Solarsystem
final static short TYP_AMOUNT = 4; //Anzahl Sternen Sorten
final static short AMOUNT_OBJECTS = 9;
Normale Variablen sollten im "lowerCamelCase" deklariert werden, also anstatt int placerandom besser int placeRandom. Das lässt sich leichter lesen.

Ja, das werde ich abändern.

Darf ich fragen, nach welcher Vorlage (Buch, Tutorial, ??) du Java lernst? Nur aus Neugierde.

Von Überall ein bisschen. Wenn ich, während der Programmierung des Spiels, merke, dass ich mit meinem jetzigen Wissensstand nicht weiter komme, konsultiere ich das Internet. Ob es dann ein YouTube Video ist, eine Verlinkung auf "Java ist auch eine Insel" oder irgend ein Tutorial von jemanden oder eventuell ein Forumbeitrag, macht für mich dabei kein Unterschied. Letztendlich dient das Ganze, als Vorbereitung auf ein Informatik Studium, wo dann "Objektorientierte Programmierung", in Form von Java, im ersten Semester, thematisiert wird.

Ich hatte das etwas anders gemeint, aber das ist wohl etwas vorgegriffen. Du denkst noch zuwenig objektorientiert (was normal ist, wenn man gerade damit begonnen hat). Das Objekt selbst (z.B. die Sonne) hat eine Methode, die ihre Position neu berechnet. Diese Methode braucht auch nicht die Position und die Geschwindigkeit als Parameter, denn als "Sonne" (das Objekt) weiß sie das schon alles.

Okay, habe ich verstanden. Kommt dann als Methode in die Klasse SolarObjekt.
 

temi

Top Contributor
Also sind die Objekte im Solarsystem folgende: solarsystem [1], solarsystem [2], usw. Und jedes dieser Objekte ist vom Typ SolarObjekt, dass wiederum 3 Werte speichert. Später ließe sich relativ einfach eine weitere Eigenschaft hinzufügen, wie Masse oder Geschwindigkeit.

Genau! Mit SolarObject[] objects = new SolarObject[100]; erstellst du ein Array, welches 100 Solarobjekte aufnehmen kann. Achtung, es enthält damit noch keine Objekte, nach dem Erzeugen des Arrays sind alle Stellen null.

Die Objekte musst du selbst hinzufügen, z.B. objects[0] = new SolarObject(0, 0, 5);

Von Überall ein bisschen.

Das ist möglicherweise nicht so ideal, weil es so keinen roten Faden gibt, der eine sinnvolle Entwicklung der Fähigkeiten und Kenntnisse verfolgt. YouTube gibt es auch viel Mist, leider kann das ein Anfänger erst beurteilen, wenn er kein Anfänger mehr ist. Kann sein, dass man dadurch viel Müll lernt und sich mühevoll wieder abgewöhnen muss. Die Insel ist ein tolles Nachschlagewerk, aber kein ideales Buch für den Einstieg. Das Problem ist, dass du so entweder auf Anfängerniveau weiterprogrammierst, oder von fortgeschrittenen Techniken erschlagen wirst ohne sie zu verstehen.

Nehmen wir mal ein Array, wie du es verwendest. Eine sinnvolle Entwicklung der Programmierfähigkeiten beginnt bei einem Array für primitive Typen, danach ein Array von Objekten, danach wird man sich eine eigene Klasse für ein dynamisches Array (das seine Größe anpassen kann) schreiben und schließlich bei den bei Java mitgelieferten Kollektionen wie List<>, Set<> oder Map<> landen. Die sind dann auch das Mittel der Wahl.

Darum gilt immer noch
Meine empfohlene Vorgehensweise ist:
  1. Grundlagen von Java lernen (da gehören GUI noch nicht dazu!)
  2. Wenigstens die SOLID-Prinzipien UND Entwurfsmuster anschauen (Buchtip: Entwurfsmuster von Kopf bis Fuß)
  3. Immer auch mal den Code von anderen anschauen. Es gibt so viele gute Programmierer. Da darf man sich durchaus was abschauen.

Solange du Punkt 1 nicht sinnvoll (d.h. ein gutes Lehrbuch oder ein gutes Tutorial) abgeschlossen hast, würde ich an diesem Projekt nicht mehr weitermachen.

Ich würde dir an dieser Stelle trotzdem empfehlen wenigstens das Buch "Entwurfsmuster von Kopf bis Fuß" zunächst zu bearbeiten. Der Code darin ist recht einfach und du scheinst ja damit zurechtzukommen, dir notfalls die nötigen Informationen zu beschaffen, wenn du was nicht verstehst. Andererseits halte ich es für so ein Projekt schon für relevant, sich mit diesem Thema gut auseinandergesetzt zu haben, weil man so das Zusammenwirken von Objekten besser versteht und das fehlt dir offensichtlich noch fast komplett.
 
Zuletzt bearbeitet:

NeoLexx

Mitglied
Das ist möglicherweise nicht so ideal, weil es so keinen roten Faden gibt, der eine sinnvolle Entwicklung der Fähigkeiten und Kenntnisse verfolgt. YouTube gibt es auch viel Mist, leider kann das ein Anfänger erst beurteilen, wenn er kein Anfänger mehr ist. Kann sein, dass man dadurch viel Müll lernt und sich mühevoll wieder abgewöhnen muss.

Das sehe ich anders, das Potential, durch YouTube dinge zu Lernen, wird offenbar immer noch stark unterschätzt. Und dass dort auch Material zu finden ist, dass ehr Kontraproduktiv ist, ja dieses Argument gilt für jedes Buch auch.

Man muss sich ja nur etwas in den Naturzustand der Menschen versetzen und wird einsehen müssen, dass gerade das Lernen, dass durch die Sinne, Sehen und Hören, vermittelt wird, sich am besten bei uns Menschen einprägen.

Es sei noch so viel gesagt, ich habe meine Methode zu lernen, bewusst und mit bedacht, gewählt und das steht hier nicht zur Diskussion.

Die Insel ist ein tolles Nachschlagewerk, aber kein ideales Buch für den Einstieg. Das Problem ist, dass du so entweder auf Anfängerniveau weiterprogrammierst, oder von fortgeschrittenen Techniken erschlagen wirst ohne sie zu verstehen.

Sehe hier das Problem nicht, wenn ich merke, dass eine Technik unverständlich ist, weil sie auf anderen Lerninhalten aufbaut, die man vorher verstanden haben muss, ja dann suche ich einen anderen Weg oder aber ich bringe mir diese fehlenden Lerninhalte bei. Und dass ich auf Anfängerniveau weiterprogrammiere, ja das ist doch klar, ich bin so lange Anfänger bis ich experte werde und sowas dauert nun mal.

Ich würde dir an dieser Stelle trotzdem empfehlen wenigstens das Buch "Entwurfsmuster von Kopf bis Fuß" zunächst zu bearbeiten.
Auf einen kurzen Blick scheint das Buch ganz witzig zu sein, werde es mir eventuell ansehen.

Solange du Punkt 1 nicht sinnvoll (d.h. ein gutes Lehrbuch oder ein gutes Tutorial) abgeschlossen hast, würde ich an diesem Projekt nicht mehr weitermachen.
Ja, schade. Aber ich werde an dem Projekt weiter machen.

By the way, zwei Solarsystem mit der neuen Klasse erstellt:
überschreiben bilddatei.JPG
Der eine oder andere Mond ist noch zu weit von seiner Welt entfernt, aber den Fehler finde ich noch..
 
X

Xyz1

Gast
Das sehe ich anders, das Potential, durch YouTube dinge zu Lernen, wird offenbar immer noch stark unterschätzt
Das Potenzial, bei YouTube nur Bullshit "zu lernen", wird offenbar immernoch stark unterschätzt.

Man muss sich ja nur etwas in den Naturzustand der Menschen versetzen und wird einsehen müssen, dass gerade das Lernen, dass durch die Sinne, Sehen und Hören, vermittelt wird, sich am besten bei uns Menschen einprägen
Man lernt am besten durch begreifen von Dingen. Kannst Du YouTube anfassen?

Und dass ich auf Anfängerniveau weiterprogrammiere, ja das ist doch klar, ich bin so lange Anfänger bis ich experte werde und sowas dauert nun mal
Kein Experte fällt vom Himmel. (Außer Jesus, aber das ist was anderes...)

Auf einen kurzen Blick scheint das Buch ganz witzig zu sein, werde es mir eventuell ansehen
Es ist nicht nur witzig, sondern ein herausragendes Referenzwerk. Kein x beliebiges Youtube Video von Horst-Otto...
 
Zuletzt bearbeitet von einem Moderator:

httpdigest

Top Contributor
Das sehe ich anders, das Potential, durch YouTube dinge zu Lernen, wird offenbar immer noch stark unterschätzt. Und dass dort auch Material zu finden ist, dass ehr Kontraproduktiv ist, ja dieses Argument gilt für jedes Buch auch.
Das hängt, denke ich, stark von dem Thema ab. Wenn es darum geht, wie man ein Steak richtig zubereitet, dann ja. Hab da gute Erfahrungen gemacht! :) Aber wenn es um geistig anspruchsvolle Dinge wie Softwareentwicklung bzw. Programmieren geht, dann nein. Hier sind Videos meiner Meinung nach die reinste Zeitverschwendung. Programmieren lernt man nicht, indem man sich auf seine Couch setzt und ein Video über Programmieren guckt. So lernen Menschen einfach nicht. Programmieren lernt man durch Ausprobieren und Üben, also Dinge selber tun. Versuche mal, nachdem du ein Video auf YouTube geguckt hast, zusammenzufassen, was genau du danach eigentlich gelernt hast. Und dann versuche mal, das Gelernte gleich anzuwenden.
Ein weiteres Problem bei Videos ist, dass man sie entgegen einem Buch mit Inhaltsverzeichnis, nur linear konsumieren kann. Du musst dir anhören, wie jemand Dinge in einer bestimmten Geschwindigkeit von Anfang bis Ende des Satzes "sagt". Ja, man kann zwar im YT Player die Geschwindigkeit begrenzt erhöhen. Trotzdem bleibt das Konsumieren des Inhaltes aber strikt linear, anders als bei einem Buch, in dem man gut Querlesen kann.
Desweiteren ist das Vermarktungsmodell bei YouTube ein anderes: Dort werden Videoproduzenten besser bezahlt, je länger Zuschauer ihre Videos schauen. Um das zu erreichen, wird alles getan, damit Zuschauern nicht langweilig wird. Das heißt, dass "Entertainment" einen viel höheren Stellenwert hat als das Vermitteln von Wissen.
 
X

Xyz1

Gast
Das heißt, dass "Entertainment" einen viel höheren Stellenwert hat als das Vermitteln von Wissen.
Das kommt noch erschwerend zu möglicherweise qualitativen Mängeln hinzu... Wenn ich unterhalten werden möchte, schaue ich nen Film oder Serie oder gar ein schwachsinniges Lets-Play (von gronkh), wenn auch noch ein paar Gehirnzellen absterben sollen; aber, wenn ich Wissen anhäufen möchte, nicht.
 

temi

Top Contributor
Es sei noch so viel gesagt, ich habe meine Methode zu lernen, bewusst und mit bedacht, gewählt und das steht hier nicht zur Diskussion.
Deine Methode sei dir gegönnt. Es war nur als Hinweis gemeint, dass speziell auf YT sehr (sogar sehr sehr) viel Müll zu finden ist.
Und dass ich auf Anfängerniveau weiterprogrammiere, ja das ist doch klar, ich bin so lange Anfänger bis ich Experte werde und sowas dauert nun mal.
Ich finde es halt schwierig (für uns, wie auch für dich), zu entscheiden, wann es an der Zeit ist, die nächste "Entwicklungsstufe" anzugehen. Dazu noch einmal zurück zum Array. Arrays sind sicher unabdingbar in der Softwareentwicklung, werden aber selten direkt verwendet. Das gilt auch für dein Projekt. Lass den ganzen Array-Quatsch weg und wechsel direkt zu List<>, Set<> oder Map<>. Das ist nur sinnvoll. Problematisch ist, dass dafür einiges vorausgesetzt wird, so solltest du schon wissen was Generics sind. Verstehst du was ich meine?

Also mach ruhig mit deinem Projekt weiter. Das ist interessant, macht Spaß und du wirst dabei lernen. Aber du musst dir trotzdem die Grundlagen anschaffen. Ich würde mir also jetzt, bevor ich damit weiter mache, die "Insel" hernehmen und wenigstens die Kapitel 2 (Imperative Sprachkonzepte) bis 10 (Generics) durcharbeiten. Dann hast du wenigstens eine Basis, auf der du aufbauen kannst. Wie willst du etwas anwenden, wenn du es nicht kennst, weil du bei Arrays aufgehört hast zu lesen?
 

NeoLexx

Mitglied
@httpdigest und @Xyz1 Danke für euren Input zum Themenkomplex Lernmethoden, ich werde über das geschrieben nachdenken.

Weiterhin möchte ich gerne diesen Beitrag nutzen, um Probleme betreffend meines Projektes zu thematisieren. Derzeit konnte ich alles, so wie von mir konzipiert, umsetzen. Danke nochmal an @temi, @JustNobody und @mihe7, die sich die Zeit genommen haben, mir dabei zu helfen. Ich melde mich wieder wenn ich bei dem Projekt nicht weiter komme.
 

NeoLexx

Mitglied
Hallo zusammen. Ich bin bei meinem Projekt an einem Punkt angekommen, an dem ich mich mit Static deklarierten Mehtoden/Variablen und co. versus kreierten Instanzen von Klassen und co., auseinander setzen muss. Ich habe diesbezüglich einiges an Informationen eingeholt, möchte das Thema jedoch besser verstehen. Zunächst lassen sich Variablen als Static deklarieren und können sich dann bei Veränderung auf alle Instanzen, der Mutterklasse, auswirken. Das ist für mich total verständlich.

Doch wie sieht es bei Klassen aus, bei denen ich keine unterschiedlichen Instanzen benötige? Ist es da sinnvoll auf eine Kreierung einer Instanz zu verzichten und dann mit Static Mehtoden bei dieser Klasse zu arbeiten? In meinem Fall geht es um das Userinterface. Bei diesem bekommt der Spieler einerseits Information und kann anderseits Informationen eingeben. Da das Spiel runden basierend ist, wird diese Userinterface-Klasse zu beginn einer jeden Runde gestartet. Ich benötige also gar keine unterschiedlichen Instanzen dieses Interfaces. Gibt es ein Grund, den ich gerade nur nicht sehe, hier doch mit einer Instanz zu arbeiten?
 

temi

Top Contributor
Zunächst lassen sich Variablen als Static deklarieren und können sich dann bei Veränderung auf alle Instanzen, der Mutterklasse, auswirken.

Man kann sich mal grob merken:
Java:
class Foo {

    public static int klassenVariable; // Klassenvariable
    public int instanzVariable; // Instanzvariable
}

Foo.klassenVariable = 42; // Aufruf muss über die Klasse erfolgen, der Wert ist gültig über alle Instanzen dieser Klasse

Foo foo = new Foo;
foo.instanzvariable = 42; // Aufruf muss über die Instanz der Klasse erfolgen, der Wert gilt nur für diese Instanz

Doch wie sieht es bei Klassen aus, bei denen ich keine unterschiedlichen Instanzen benötige?
Das was du vermutlich meinst, nennt sich Singleton-Muster, d.h. von dieser Klasse gibt es nur genau eine Instanz. Das kann sinnvoll sein, hat aber einen schlechten Ruf. Dieser Ruf liegt allerdings in erster Linie an der falschen Verwendung des Singleton. Häufig wird es als "globale Variable" mißbraucht und das ist nicht gut. Korrekt verwendet würde diese Instanz ganz normal z.B. über den Konstruktor in die Klassen injiziert, die es benötigen.

Ob es für deine Anwendung sinnvoll ist, musst du entscheiden. Eine mögliche Umsetzung:
Java:
class Foo {
    private Foo instance = new Foo(); // Instanz über den privaten Konstruktor erzeugen

    private Foo() {} // Konstruktor verbergen, damit keine Instanzen außerhalb erzeugt werden können

    public static Foo getInstance() {
        return instance; // Rückgabe der einzig existierenden Instanz
    }
}
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
P Zähler Variable für mehrere Objekte Java Basics - Anfänger-Themen 6
S Wie erstelle ich eine Vorbedingung für eine Variable einer Methode ? Java Basics - Anfänger-Themen 5
L Variable für JLabel wird nicht erzeugt Java Basics - Anfänger-Themen 6
C Werteraum für Variable bestimmen Java Basics - Anfänger-Themen 5
R Php werte in jquery variable speichern für autocomplete Java Basics - Anfänger-Themen 7
U Java neue Variable für jeden Schleifendurchgang Java Basics - Anfänger-Themen 11
N Variable für alle Klassen Java Basics - Anfänger-Themen 6
F Listener für Variable Java Basics - Anfänger-Themen 29
K Übergabe der Variable für Farbe Java Basics - Anfänger-Themen 6
L Variable Stelle für Stelle auslesen Java Basics - Anfänger-Themen 2
M Länge eines Arrays als Variable speichern möglich? Java Basics - Anfänger-Themen 14
R Liste in Variable speichern Java Basics - Anfänger-Themen 6
J Java long- in int-Variable umwandeln Java Basics - Anfänger-Themen 6
Nitrogames Variablen Variable aus JOptionPane Abfrage in Array einfügen Java Basics - Anfänger-Themen 4
E Variable von 1. Fenster an 2. Fenster übergeben. Java Basics - Anfänger-Themen 7
T Variable in Schleife deklarieren, Speicherplatz, Garbage Collector Java Basics - Anfänger-Themen 10
T Datum als Variable wert Java Basics - Anfänger-Themen 4
G Variable aktualisiert sich nicht in rekursiver Methode Java Basics - Anfänger-Themen 4
R Compiler-Fehler Variable wird nicht gefunden bzw. erkannt? Java Basics - Anfänger-Themen 2
Say super.methode / super.variable und super(variable) Java Basics - Anfänger-Themen 2
M variable in anderer funktion aufrufen Java Basics - Anfänger-Themen 10
N Was Passiert mit dem Namen einer Variable, wenn man diese einer Liste Hinzufügt Java Basics - Anfänger-Themen 16
T Variable von Objekten in einer Methode überprüfen Java Basics - Anfänger-Themen 26
U Wie mache ich die Variable xyz eindeutig/unique? Java Basics - Anfänger-Themen 20
JordenJost char variable funktioniert irgendwie nicht a+b ergibt nicht à Java Basics - Anfänger-Themen 4
M Variable Felderanzahl Java Java Basics - Anfänger-Themen 10
T Variable durch Action Listener ändern Java Basics - Anfänger-Themen 2
stormyark Fehler beim überschreiben einer Variable Java Basics - Anfänger-Themen 1
S Eine Variable in einem Array speichern Java Basics - Anfänger-Themen 5
I Methoden Wieso wird mein Array "a" verändert und meine Variable "a" nicht? Java Basics - Anfänger-Themen 4
M Variable in einer Schleife initialisieren Java Basics - Anfänger-Themen 46
W Schleife und einmal variable++ zu viel Java Basics - Anfänger-Themen 20
M String mit Variable vergleichen Java Basics - Anfänger-Themen 9
M Methoden Wert einer Variable geht verloren? Java Basics - Anfänger-Themen 6
G variable kopieren bzw. woanders benutzen Java Basics - Anfänger-Themen 6
Ameise04 Variablen Inhalt einer Variable im Code verwenden? Java Basics - Anfänger-Themen 9
J Double Variable und Addition Java Basics - Anfänger-Themen 2
I Variable innerhalb Methode: Local variable test defined in an enclosing scope must be final or effectively final Java Basics - Anfänger-Themen 3
KogoroMori21 Variable im Parameter und Ohne Java Basics - Anfänger-Themen 5
Vivien Auf eine Variable von einer anderen Klasse aus zugreifen Java Basics - Anfänger-Themen 3
H Datentypen Wertebereich von <Klassenname> <Variable> Java Basics - Anfänger-Themen 12
M Private Variable Java Basics - Anfänger-Themen 2
idontknow707 Matrix nach z.B. Variable durchsuchen Java Basics - Anfänger-Themen 4
T Variable in for Schleife ansprechen ohne Array ? Java Basics - Anfänger-Themen 25
s.marcii Modulo in der Variable einsetzen - ist das möglich? Java Basics - Anfänger-Themen 2
N Variable aus anderen Variablen in statischer Klasse berechnen/abspeichern? Java Basics - Anfänger-Themen 4
Y Wie kann ich die Variable in der Try Catch returnen? Java Basics - Anfänger-Themen 3
K Übergabe des Wertes einer Variable aus main() in eine Klassenmethode Java Basics - Anfänger-Themen 8
B Inkrement von Variable Java Basics - Anfänger-Themen 8
V Variablen statische Variable einer Objektvariable zuordnen Java Basics - Anfänger-Themen 3
L Variable von einer Methode zu einer anderen Methode inkl. einer "Zwischenmethode" Java Basics - Anfänger-Themen 1
J JTextField Bezeichnung als Variable Java Basics - Anfänger-Themen 3
N Wie kann ich eine meine Variable Final machen? Java Basics - Anfänger-Themen 1
M Enum-Variable HashMap zuweisen Java Basics - Anfänger-Themen 5
H Variable um 1 erhört ausgeben Java Basics - Anfänger-Themen 4
V Erste Schritte Eine Array-Variable mit Benutzereingaben befüllen Java Basics - Anfänger-Themen 3
J Fehlermeldung unklar. non-static variable player0 cannot be referenced from a static context Java Basics - Anfänger-Themen 4
P non-static variable cannot be referenced from a static context Java Basics - Anfänger-Themen 6
A Wie zwei zahlen in einer Variable speichern? Java Basics - Anfänger-Themen 7
W Problem mit dem Wert von boolean-Variable Java Basics - Anfänger-Themen 3
M Input/Output JTextField Eingabe in String Variable speichern Java Basics - Anfänger-Themen 15
A Kann man eine Methode als Variable speichern und danach noch verändern? Java Basics - Anfänger-Themen 6
L cannot find symbol variable Kon Java Basics - Anfänger-Themen 8
C Statischer Typ aber Variable nicht statisch? Java Basics - Anfänger-Themen 5
H Variable.methode aufstellen, verstehen Java Basics - Anfänger-Themen 2
R Warnung, wenn eine Variable eingegeben wird Java Basics - Anfänger-Themen 6
S Variable einscannen Java Basics - Anfänger-Themen 30
N Best Practice Rückgabe eines Terminal Befehls in eine Variable speichern Java Basics - Anfänger-Themen 27
M Erste Schritte Mit Variable verschiedene Texte in Textfeld einfügen Java Basics - Anfänger-Themen 27
J Input-Variable nicht sichtbar Java Basics - Anfänger-Themen 2
L Warum ist Variable null? Java Basics - Anfänger-Themen 3
E Variable (Vektor) in andere Methode übergeben Java Basics - Anfänger-Themen 4
A OOP Variable in anderer Klasse durch Methode aufrufen und einer anderen Variable gleichsetzen Java Basics - Anfänger-Themen 2
S Variable Parameter Java Basics - Anfänger-Themen 5
D Datei auslesen & Werte in Variable speichern Java Basics - Anfänger-Themen 12
P if - Statement erkennt variable nicht. Java Basics - Anfänger-Themen 12
J Ungewollte Wertveränderung einer Variable Java Basics - Anfänger-Themen 9
R Variablen Variable an FXML-Controller übergeben Java Basics - Anfänger-Themen 4
J Zugriff auf Variable in anderem Programm Java Basics - Anfänger-Themen 5
R variable istpositiv might not have been initialized Java Basics - Anfänger-Themen 2
A Methodenname aus variable Java Basics - Anfänger-Themen 2
L Variable aus einer Klasse in einer anderen Klasse nutzen Java Basics - Anfänger-Themen 6
P Methode soll Variable einer anderen Klasse ändern. Wie? Java Basics - Anfänger-Themen 1
Hanschyo Variable nicht initialisiert Java Basics - Anfänger-Themen 6
deatzi Variable aus If Abfrage später nutzen Java Basics - Anfänger-Themen 4
L Variable in If-Statement initialisieren Java Basics - Anfänger-Themen 4
C return kann nicht auf variable zugreifen Java Basics - Anfänger-Themen 26
S Warum kann ich nicht mehr als eine Variable in einer for Schleife deklarieren ? Java Basics - Anfänger-Themen 1
V Warum speichert meine String-Variable nummerische Werte? Java Basics - Anfänger-Themen 3
J Wert eines Arrays einer Variable zuweisen, sobald der Wert eines anderen Arrays eintritt Java Basics - Anfänger-Themen 2
DaCrazyJavaExpert Compiler-Fehler Variable nicht mit null initialisiert, trotzdem: NullPointerException Java Basics - Anfänger-Themen 28
A Erste Schritte Mein Programm erkennt die variable EinAus.readInt nicht Java Basics - Anfänger-Themen 15
Aprendiendo [JAVA-Syntax] (int... variable) bei einem Konstruktor Java Basics - Anfänger-Themen 8
F Variablen If else: Einer Variable einen Wert hinzufügen oder so? Java Basics - Anfänger-Themen 6
Aprendiendo Interpreter-Fehler "non-static variable this cannot be referenced from a static context" Java Basics - Anfänger-Themen 2
D Aufruf einer statischen Variable Java Basics - Anfänger-Themen 1
F [OOP] Auf eine Variable aus meherer Klassen zugreifen Java Basics - Anfänger-Themen 22
D Einer Variable automatisch Zahlen hinzuaadieren Java Basics - Anfänger-Themen 3
BadBat Klassen instanz als variable + methodenaufruf Java Basics - Anfänger-Themen 4
BadBat Variablen Eine Variable mit 2 Typen Java Basics - Anfänger-Themen 38

Ähnliche Java Themen

Neue Themen


Oben