Verbesserungsvorschläge zum Quellcode

Darokh

Mitglied
Hi,
derzeitig bringe ich mir ja Java bei und hätte gern etwas Rückmeldung, ob das, wie ich das gerade angehe, ok ist. Möchte gerne dazulernen und bin somit für jede Kritik dankbar.
Die ganze Geschichte ist auf Basis von dem Tutorial für Java Spiele aufgebaut.
Würde man nun auch die anderen Klasse noch anschauen, würde man sehen, dass eigentlich nur die Struktur etwas anders ist - aber ansonsten bisher alles gleich.

Also, worum gehts:
Bei dem Programm handelt es sich um ein "Spiel", welches mehrere Unterspiele beinhalten wird.
Also Spiel_1 kann aus SubSpiel_1 und SubSpiel_2 bestehen,
während Spiel_2 (später) aus SubSpiel_2 , 3 und 4 bestehen kann.

Jedes Spiel überschaut also die SubSpiele,
die SubSpiele wiederum verwalten sich selbst und bekommen bei Zeiten Anweisungen vom (Haupt-) Spiel.

In einem SubSpiel erscheinen beispielsweise Grafiken oder Sounds, auf die der User Einfluss nimmt, reagieren muss oder vergleichbares.
Die Zielsetzung der SubSpiele ist noch unklar, da es hierbei um Spiele für "therapeutische" Zwecke handelt, zu denen ich gerade forsche...oder besser gesagt, forschen werde. Als erstes muss ich nun aber erstmal Java lernen...



Nun habe ich allerdings noch ein paar Fragen zu der Hauptklasse:
1 - Zeile 48: Zum Frame werden die Keylistener hinzugefügt: Wie ist es möglich, das diese Zeile nicht mehr notwendig ist, und das SubGame es selbst verwaltet?

2 - Zeile 71: Initialisieren der Grafiken für das Spiel: Eigentlich sollte jedes Subgame seine eigenen Grafiken verwalten, aber das bekomme ich noch nicht hin

3 - Zeile 65 + 105: Das geht bestimmt noch eleganter

Meine größte Hürde ist im Moment, dass jedes SubSpiel wirklich für sich alleine steht. Alle Tutorials, die ich bisher gefunden habe, machen fast alles in 2 oder 3 Klassen und wenig verschachtelt.
Ich muss das allerdings genauer aufschlüsseln. Ziel ist es - sofern das überhaupt möglich ist - dass ich in einem Spiel ein neues SubSpiel-Objekt erstelle und es von da an komplett alleine arbeitet. Also auch mit KeyListenern, usw. --> Da hakt es bei mir aber derzeitig noch gewaltig.
Den KeyListener bekomme ich z.B. gerade nur an den Frame von HauptSpiel gekoppelt. Ich glaube, da habe ich auch irgendetwas noch überhaupt gar nicht verstanden.

Hier die abstrakte Klasse, wobei die noch erweitert wird.

[Java]
import javax.swing.JPanel;


public abstract class Game extends JPanel implements Runnable {

protected int posX;
protected int posY;

protected long delta;
protected long last;
protected long fps;

public Game()
{
// Alles, was für jedes Spiel vorher initialisiert werden muss
}

// Berechne FPS
protected void computeDelta()
{
delta = System.nanoTime() - last;
last = System.nanoTime();
fps = ((long)1e9) / delta;
}
}
[/Java]

Und das Spiel_1 wird genauer beschrieben:

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;


public class Game_1 extends Game implements Runnable{
	private static final long serialVersionUID = 1L;
	
	SubGame_1 mySubGame_1;
	
	JFrame frame;
	boolean gameStarted = false;
	
	public static void main(String[] args)
	{
		new Game_1();
	}
		
	
	public Game_1()
	{
		super();
		
		// erstelle Spielbildschirm
		this.setPreferredSize(new Dimension(800,600));
		frame = new JFrame ("Spiel 1");
		frame.setLocation(100,200);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(this);
		frame.pack();
		frame.setVisible(true);
		
		// starte alles, was zum Spielbeginn notwendig ist
		doInitializations();
	}
	

	// Startet alles, was für vor der Initialisierung des Games notwendig ist
	private void doInitializations() 
	{
		last = System.nanoTime(); 					// Legt ersten Zeitpunkt der Initialisierung fest, für spätere FPS Berechnung
		mySubGame_1 = new SubGame_1(this);			// das erste SubGame
		
		// ****1: Zum Frame werden die Keylistener hinzugefügt: Wie ist es möglich, das diese Zeile nicht mehr notwendig ist, und das SubGame es selbst verwaltet? 
		frame.addKeyListener(mySubGame_1);			
		
		// starte eigenen Thread (aus Tutorial übernommen - so genau weiß ich auch noch nicht, warum)
		Thread th = new Thread(this);			
		th.start();
		
	}
	
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		g.setColor(Color.red);
		g.drawString("FPS: " + Long.toString(fps), 20 ,10);
		
		
		// ****3: Das geht bestimmt noch eleganter
		if(!gameStarted)
		{
			return;
		}
		
		// ****2: Initialisieren der Grafiken für das Spiel: Eigentlich sollte jedes Subgame seine eigenen Grafiken verwalten, aber das bekomme ich noch nicht hin
		mySubGame_1.allHeliCopters.firstElement().drawObjects(g);
		mySubGame_1.testCircle.drawObjects(g);
	}
	
		
	// startet für jedes Subgame die Anweisung, dass es nun seine Objekte bewegen darf
	private void moveObjecs()
	{
		mySubGame_1.moveObjects(delta);
	}
	
		
	// Check keys für jedes Subgame und für gesamtgame (für pause, start)
	private void checkKeys()
	{
		mySubGame_1.checkKeys();
	}
	
	// startet für jedes SubGame die Funktion, die für die Logik zuständig ist (beispielsweise animationen, Berechnungen etc)
	private void doLogic()
	{
		mySubGame_1.doLogic(delta);		
	}
	
	// Clont die Objekte / Vektoren
	private void cloneObjects()
	{
		mySubGame_1.cloneVectors();		
	}
	
		
	public void run() 
	{
		// ****3: das geht bestimmt noch eleganter
		gameStarted=true;		
		
		while (frame.isVisible())
		{
			computeDelta();
			doLogic();	
			checkKeys();
			moveObjecs();			
			cloneObjects();
			
			repaint();
			
				try
				{
					Thread.sleep(10);
				}
				catch (InterruptedException e)
				{
					
				}	
		}		
	}	
}

[/Java]

Soweit erstmal, wenn dann noch Fragen sind oder weiteres Interesse, kann ich die nächsten Klassen ja mal posten...
Vielen dank auf jeden Fall schonmal...
 

Marco13

Top Contributor
Hoffentlich nimmst du dir mit dem Ziel, die http://www.java-forum.org/codeschnipsel-u-projekte/127705-mini-games-fuer-doktorarbeit.html selbst zu entwickeln, nicht zu viel vor (nicht damit an sich, sondern speziell das "nebenher" neben der Dokterarbeit zu machen).

Bisher sieht man da ja nicht viel, aber das was man sieht, sieht ... verbesserungswürdig aus. Ggf. solltest du die Rolle der SubGames innerhalb eines Games nochmal genauer beschreiben: Wird da immer nur eins gleichzeitig angezeigt? Wird zwischen denen hin- und her geschaltet? Laufen die in einer Sequenz ab, ggf. mit sowas wie einer Auswetung zwischendrin? Ist der Ablauf festgelegt, oder inwieweit wird der vom User gesteuert? Welche "Anweisungen" bekommen die SubGames vom HauptGame?
 

hdi

Top Contributor
Ok, dann will ich dich mal auseinander nehmen :D Ist vielleicht mehr Kritik als du willst, aber ich meine es nicht böse, im Gegenteil. Außerdem sei vorweg gesagt dass ich generell ein Mann der Prinzipien bin, und dir Verbesserungsvorschläge mache die manch einer hier als Overkill bezeichnen würde. Also wenn's dich langweilt, dann ignorier's einfach ;)

Java:
public abstract class Game extends JPanel implements Runnable {

VÖLLIGER MÜLL!! ...Nein, so schlimm bin ich auch nicht :D Aber ich finde du implementierst zuviel in einer einzigen Klasse. Sogenannte "Gott-Klassen", die fast das gesamte Programm beinhalten sind designtechnisch fraglich. Du kannst dein Programm übersichtlicher und flexibler gestalten, wenn du einzelne Teile in eigene Klassen auslagerst.

Mein Vorschlag:
- Klasse Game implements Runnable für die Spielinfos und -logik
- Klasse GamePanel extends JPanel für die Darstellung des Spiels

Java:
protected
Grundsätzlich sollten Instanz-Variablen private sein. Natürlich kann man nicht pauschal sagen dass protected falsch wäre. Aber man sollte dann schon einen guten Grund dafür haben warum sie nicht private sind. Hast du solch einen Grund? Wenn nein, dann mach sie private. (Ein Grund ist übrigens NICHT, dass sie in anderen Klassen verwendet werden müssen. Für sowas gibt es Setter und Getter).
Für die Methoden gilt übrigens das selbe: Ich sehe keinen Grund dafür warum computeDelta() nicht eine private Hilfsmethode für die Klasse sein kann.

Java:
public class Game_1

Game_1 ist ein Name, der gegen die Naming Conventions verstößt. Namen für Datenstrukturen (Klassen, Interfaces, Enums, Annotations) sollte man in CapitalCamelCase schreiben. Keine Unterstriche etc, die Teilworte zusammenziehen und jedes Teilwort mit neuem Buchstaben schreiben. In deinem Fall ist es kein Wort sondern eine Zahl. Also nenn das Ding einfach Game1, oder besser noch: Gib dem Spiel einen aussagekräftigeren Namen. Oder soll das Spiel wirklich Game1 heißen? Dafür findest du keinen Publisher :D

Die selbe Sache, Variablen schreibt man in lowerCaseCamelCase, also mySubGame1, ein Unterstrich gehört da nicht hin.

Java:
public void paintComponent(Graphics g)
Beim Overriding einer Methode sollte man immer eine @Override Annotation dazuschreiben. Ist sicherer:
Java:
@Override // für die run-Methode gilt das selbe
public void paintComponent(Graphics g)
Außerdem auch hier die Frage: gibt es einen Grund warum du den geerbten Access Modifier (protected) auf public erhöhst?


Java:
 frame = new JFrame ("Spiel 1");
        frame.setLocation(100,200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
        frame.pack();
        frame.setVisible(true);
Das hat finde ich nix in dieser Klasse zu suchen. Ein Spiel kann durchaus sowas wie seine bevorzugte Frame-Größe anbieten (über Getter abfragen), aber die Erzeugung des Frames und vorallem die Anzeige sollte von höherer Instanz aus geschehen.

Java:
frame.setVisible(true);
Von wegen GUI: Grundsätzlich solltest du GUI-Code nur auf dem EDT ausführen lassen. Das ist jetzt aber zu kompliziert als dass ich es schnell erklären könnte, und führt uns auch zuweit von deinem Code weg. Aber lies dich mal in das Thema ein, das ist sehr wichtig:
Threads and Swing

1 - Zeile 48: Zum Frame werden die Keylistener hinzugefügt: Wie ist es möglich, das diese Zeile nicht mehr notwendig ist, und das SubGame es selbst verwaltet?
zB indem du in der Klasse Game/SubGame definierst, dass man dem Konstruktor ein JFrame übergeben muss, und das Game registriert sich selber über
Code:
frame.addKeyListener(this);
Aber: Ich würd das nicht machen. Ein Spiel sollte nicht entscheiden müssen wo es seinen KeyListener registriert. Hier ist übrigens auch wieder die Frage ob du den KeyListener nicht in eine eigene Klasse auslagerst.

3 - Zeile 65 + 105: Das geht bestimmt noch eleganter
Nö, eigentlich nicht ;) Du kannst die Logik natürlich umdrehen und sagen if(gameStarted){...}, aber so ein return find ich da durchaus passend.

2 - Zeile 71: Initialisieren der Grafiken für das Spiel: Eigentlich sollte jedes Subgame seine eigenen Grafiken verwalten, aber das bekomme ich noch nicht hin
Hm, das ist auch schon etwas komplizierter. Grundsätzlich musst du kucken dass du abstrakte Schichten im Programm schaffst. Gleiche Dinge in einer einzigen Klasse oder einem Interface bündeln. Es ist jetzt nicht ohne weiteres möglich zu sagen wie du das am besten machen solltest. Dazu müsste man mehr über die einzelnen SubGames wissen.

Insgesamt muss ich mich Marco anschließen: Das Projekt find ich zu schwer, mach erstmal EIN Spiel. Dann merkst du wohl auch eher was du dann in dem Mehrspiel-Projekt als Zusatzarbeiten hast, und merkst dementsprechend dass diese auch nicht Teil der einzelnen Spiele sein sollten.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Das wollte ich gestern abend (nach >30 Stunden ohne Schlaf) nicht mehr so ausführlich schreiben, aber du hast natürlich recht.

Nur in bezug auf den letzten Punkt bin ich mir nicht sicher. Natürlich wäre es für einen Anfänger, der nur Java lernen will, besser, erstmal EIN Spiel zu schreiben. Aber hier stehen schon einige (vermutlich sehr viele sehr konkrete) Anforderungen im Raum. Vermutlich ist es nicht so wichtig, ob das alles "gut" und "schön" (im Sinne pedantischer Java-Freaks und OO-Nazis) ist, sondern eher, dass alles seinen Zweck erfüllt. Aber um das zu erreichen, muss man sich schon ein paar Gedanken machen...

Oder soll das Spiel wirklich Game1 heißen? Dafür findest du keinen Publisher :D

Schlimmer: "game1.org" ist schon registriert ;( :D
 

Darokh

Mitglied
Hi,
vielen Dank erstmal für die Rückmeldung. Und nein, es ist nicht zu viel.

Ich denke, eine große Falle, in die ich tappe, ist, dass ich auf Sachen, die mir Eclipse "anbietet", dann eingehe, anstatt dann einen eigenen, geeigneteren Weg zu gehen und vor allem, dann bei einigen Sachen nicht weiß, wofür sie stehen.

Und ja, derzeitig ist das auch noch etwas viel. Ich arbeite daran.
Ein MiniGame - das sollte man kurz bedenken - besteht am Ende nur aus zwei oder drei Grafiken, die sich bewegen und dann auf Tastendruck die dann beeinflusst werden. Die SubGames sind also nicht wirklich komplex.

Was mir Probleme bereitet, ist, alles noch mehr in einzelne Klassen zu packen, da ich das nicht gerade auf der Pike auf lerne...

Ich mache mir nochmal genauer Gedanken darüber und poste das Ergebnis hier nachher nochmal.

zu dem KeyListener:
Wie würdest du den denn dann als Klasse bauen? Das bereitet mir gerade etwas Kopfzerbrechen.
 

Darokh

Mitglied
OK, banale Frage, weil ich einfach nicht checke, wie die methode paintCompment funktioniert.

Ich habe nun eine Klasse GamPanel erstellt, auf der das Spiel stattfinden soll:

[Java]
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class GamePanel extends JPanel{

private JFrame frame;

public static void main(String[] args)
{
new GamePanel ();
}



public GamePanel()
{
this.setPreferredSize(new Dimension(800,600));

frame = new JFrame ("GameDemo");
frame.setLocation(100,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setVisible(true);
new Game_1(frame);
}


protected void paintComponent(Graphics g)
{
super.paintComponent(g);

g.setColor(Color.red);
g.drawString("FPS: " , 20 ,10);
}
}

[/Java]



Und eine abstrakte Klasse für die Spiele:

[Java]
public abstract class Game implements Runnable {


protected int posX;
protected int posY;

protected long delta;
protected long last;
protected long fps;


public Game()
{
// Alles, was für jedes Spiel vorher initialisiert werden muss
}

// Berechne FPS
protected void computeDelta()
{
delta = System.nanoTime() - last;
last = System.nanoTime();
fps = ((long)1e9) / delta;
}

}
[/code]

Und das Spiel_1 (Namen noch nicht geändert, kommt noch - generell noch relativ unverändert:

[Java]
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;


public class Game_1 extends Game {
private static final long serialVersionUID = 1L;


SubGame_1 mySubGame_1;

JFrame frame;
boolean gameStarted = false;



// Übergebe Frame, in dem Game_1 stattfinden soll
public Game_1(JFrame frame)
{
super();
this.frame = frame;

// starte alles, was zum Spielbeginn notwendig ist
doInitializations();
}


// Startet alles, was für vor der Initialisierung des Games notwendig ist
protected void doInitializations()
{

last = System.nanoTime(); // Legt ersten Zeitpunkt der Initialisierung fest, für spätere FPS Berechnung
mySubGame_1 = new SubGame_1(this,frame); // das erste SubGame


frame.addKeyListener(mySubGame_1);

// starte eigenen Thread (aus Tutorial übernommen - so genau weiß ich auch noch nicht, warum)
Thread th = new Thread(this);
th.start();

}

// Das Folgende war ja mal unkommentiert.

/*public void paintComponent(Graphics g)
{
super.paintComponent(g);

g.setColor(Color.red);
g.drawString("FPS: " + Long.toString(fps), 20 ,10);


// ****3: Das geht bestimmt noch eleganter
if(!gameStarted)
{
return;
}

// ****2: Initialisieren der Grafiken für das Spiel: Eigentlich sollte jedes Subgame seine eigenen Grafiken verwalten, aber das bekomme ich noch nicht hin
mySubGame_1.allHeliCopters.firstElement().drawObjects(g);
mySubGame_1.testCircle.drawObjects(g);




}*/





// startet für jedes Subgame die Anweisung, dass es nun seine Objekte bewegen darf
private void moveObjecs()
{
mySubGame_1.moveObjects(delta);
}


// Check keys für jedes Subgame und für gesamtgame (für pause, start)
private void checkKeys()
{
mySubGame_1.checkKeys();
}

// startet für jedes SubGame die Funktion, die für die Logik zuständig ist (beispielsweise animationen, Berechnungen etc)
private void doLogic()
{
mySubGame_1.doLogic(delta);

}

// Clont die Objekte / Vektoren
private void cloneObjects()
{
mySubGame_1.cloneVectors();

}


public void run()
{

gameStarted=true;


while (frame.isVisible())
{
computeDelta();
doLogic();
checkKeys();
moveObjecs();

cloneObjects();

frame.repaint();

try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{

}
}

}

}[/Java]



So, das Ding läuft nun aber nicht, da ich einfach nicht weiß, wie ich nun die Grafiken bis zum JPanel / GamePanel bekomme.

Und egal wie viel ich google, nirgends verstehe ich, wie paintComponent wirklich funnktioniert und wie ich es nun ansprechen kann, damit ich beispielsweise auch ganz banal aus Game_1 (nicht aus dem SubGame) etwas grafisch darstellen kann.

Da wäre Hilfe ganz nett...

@ Marco13:
Die SubGames sind komplett auf sich alleine gestellt und interagieren nicht miteinander- abgesehen von deren Level.
Also, ist SubGame1 auf LVL 5, wird SubGame2 hinzugeschaltet auf Lvl 1 und SubGame1 springt auf Lvl 3.
Aber das kann ja von Game1 gemanaged werden - dafür ist das Ding ja da.
 

Marco13

Top Contributor
Also, ist SubGame1 auf LVL 5, wird SubGame2 hinzugeschaltet auf Lvl 1 und SubGame1 springt auf Lvl 3.

Nach 5 kommt 3, klar :D

Mal im Ernst: Ein bißchen was, was vielleicht in die Richtung geht, die du vorhast, kannst du dir vielleicht hier klauen: http://www.java-forum.org/entwuerfe/113007-kein-swing-tutorial-2.html#post806478 - aber das ändert nichts daran, dass du dir SEHR genau über die Strukturen und Abläufe Gedanken machen solltest. Beschreib' halt nochmal genauer, wie das am Ende aussehen soll, soweit es eben ohne NDA möglich ist (notfalls auch per PN)
 

Alph0r

Mitglied
Wenn ich mich richtig erinner ist paintComponent eine ziemlich normale Methode, die du halt aufrufen kannst. Super.paint component zeichnet das Fenster und dann kommen die ganzen Sachen rein, die du zeichnen willst.
Du musst die Methode in eine Schleife packen, damit sie immer wieder neu aufgerufen wird und alles immer wieder neu gezeichnet wird.
Es steht auch noch gut erklärt in lexlis spieletutorial imo.
 

Stelufl

Mitglied
Ich glaube nicht, dass es sinnvoll ist hier allzu viel Zeit in Clean Code und möglichst bester OOP zu legen. Er will kein Programmierer werden und den Code wird außer ihm vermutlich kaum jemand zu Gesicht bekommen. Natürlich kann man modular programmieren oder sich gar ein Framework aufbauen, aber das ist ja in diesem besonderen Fall unnötig und auch nutzlos. Das Teil muss laufen, mehr nicht. Man darf nicht vergessen, dass dies nur ein Beiwerk seiner Doktorarbeit wird... Finde da Verbesserungsvorschläge zum Thema Naming Conventions usw. dann eher fehl am Platz.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
@Alph0r: Ja, man kann paintComponent einfach aufrufen. Und das Graphics, das man übergeben muss, kann man sich mit 'panel.getGraphics()' holen.

[wr]War nur ein Witz[/wr]

Sicher kann man unterschiedliche Prioritäten setzen. Solange niemand das genaue Ziel und den genauen Umfang der zu entwickelnden Dinge kennt, müssen die Tipps und Vorschläge sehr allgemein sein, und können sich trotzdem als hinfällig erweisen. Ich hatte gestern angefangen ein paar Klassen zusammenzustümpern, anfangs noch mit Kommentaren, aber als dann der "Dummy"-Teil angefangen hat, wo irgendein "Dummy-Spiel" zum Anklicken rumfliegender Objekte dazukam, wurde klar, dass das ohne genauere Infos keinen Sinn macht. Hab' sie zwar mal angehängt, aber das kann VÖLLIG an dem vorbei sein, was tatsächlich gebraucht wird... :bahnhof:
 
Zuletzt bearbeitet von einem Moderator:

Darokh

Mitglied
Wow...das ist genau das, was ich gebraucht habe. Da brauche ich ja fast nur noch die KeyListener einzubauen und bin fast fertig -_- Das ist gruselig. Von dem Code werde ich sehr viel lernen können und schaue mir den mal sehr genau an.
Vielen Dank!

Edit:
Ich korrigiere, KeyListener sind ja auch schon drin.

Wenn ich die Tage durch den Code komplett durchgestiegen bin, kann ich ja fast schon direkt mit dem Programmieren der SubGames beginnen o_O
 
Zuletzt bearbeitet:

Darokh

Mitglied
Für mein Verständnis, des ganzen Spiels, fasse ich mal alles zusammen...


- Main erstellt ein neues JFrame.
- GameMain erstellt ein Panel mit dem Menü, welches dem JFrame hinzugefügt wird.
- GameMain estellt ein Panel mit dem GameContent selbst.
- DummyGame erstellt ein eigenes Panel mit allen mainComponents.
- DummyGame erstellt eine Liste mit allen SubGames.
- initGame fügt daraufhin alle Subgames hinzu, die später laufen sollen.
--> diese Zeile verstehe ich nicht ganz, auch wenn es banal klingt: gameContainer.add(game.getMainComponent());
- runGame startet einen neuen Thread für das Game.

[Java]
private void runGameInOwnThread()
{
notifyGameStarted();

for (final Game subGame : subGames)
{
JComponent subComponent = subGame.getMainComponent();
addComponent(subComponent);
waitUntilShowing(subComponent);

subGame.initGame();
subGame.runGame();
}

notifyGameFinished();
}
[/Java]

Hier verlassen mich die Geister. Genauer gesagt:
[Java]
for (final Game subGame : subGames)
[/code]
Verstehe ich diese Zeile nichteinmal...

und
[Java]
JComponent subComponent = subGame.getMainComponent();
addComponent(subComponent);
waitUntilShowing(subComponent);
[/Java]
Hier habe ich nur ein Bauchgefühl, was du da machst - aber die synchronized Geschichte ist dann doch (noch) zu viel für mich.

--------------------------------------

[Java]
private final List<GameListener> gameListeners;
[/code]
Hier speicherst du ja alle Listener - ich dachte "final" bedeutet, dass man daran nicht mehr ändern kann. Das ist für mich bisher ein Widerspruch.


--------------------------------------

Java:
 Game game = new DummyGame();

Was macht diese Zeile genau? Ich kenne nur:
[Java]
Game game = new Game();
oder
DummyGame game = new DummyGame();
[/Java]

----------------------------------

Was in den SubGames passiert checke ist bis jetzt (ist ja noch nicht so lange her) sogar ganz gut.

Wie würdest du anstelle von selbst generierten 2D Objekten Bilder implementieren? Das ist jetzt gerade aber eher eine Frage aus "Faulheit" heraus, da ich ja deinen Code noch nicht 100% ig verstanden habe und danach dann ja eigentlich überlegen würde, wie ich das alleine hinbekommen könnte.
 

Marco13

Top Contributor
- GameMain erstellt ein Panel mit dem Menü, welches dem JFrame hinzugefügt wird.

Pedantisch: GameMain IST ein Panel. Es enthält Links das 'controlPanel' mit dem Start-Button, und in der Mitte den 'gameContainer', in den dann das eigentliche Spiel-Panel gelegt wird.

Für den konkreten Fall wäre das (und einige der anderen Punkte, auf die du dich später beziehst) vielleicht gar nicht nötig. Aber du hattest erstens betont, dass es mehrere Spiele mit jeweils mehreren Sub-Spielen geben sollte, deswegen wurde das alles "austauschbar" gemacht, und zweitens hattest du betont, dass die Sub-Spiele "eigenständig" sein sollten. Und mit der "DummyDemo" (Code unten) sieht man, dass sie das sind - auch wenn man beim Threading ein bißchen aufpassen muss.

Die Zeile
gameContainer.add(game.getMainComponent());
macht also nichts anderes, als "das Spiel" in den gameContainer zu legen - genaugenommen eben die "Main Component" des Spiels - was genau das ist, bleibt dem Spiel überlassen. Man könnte jetzt also einfach einen zweiten "Start"-Button hinzufügen, der ein "OtherDummyGame" erstellt, und dann eben
gameContainer.add(otherGame.getMainComponent());
aufruft, damit das andere Spiel angezeigt wird. IM DummyGame selbst wird ja etwas ähnliches gemacht: Das DummyGame enthält wieder nur einen subGameContainer, in dem nacheinander die subGames angezeigt werden.


- runGame startet einen neuen Thread für das Game.
...
Hier verlassen mich die Geister. Genauer gesagt:
...
Verstehe ich diese Zeile nichteinmal...
....
Hier habe ich nur ein Bauchgefühl, was du da machst - aber die synchronized Geschichte ist dann doch (noch) zu viel für mich.


Ja, das ist ein bißchen frickelig. Das könnte man vielleicht alles VIEL einfacher machen. Dazu müßte man aber genauer wissen, wie die Abläufe und Interaktionen sein sollen (das hatte ich schonmal betont). Die Spiele müssen in einem eigenen Thread laufen, weil sie eine Animation enthalten. In diesem Fall laufen alle Sub-Games in dem Thread, der im "DummyGame" erstellt wird. Das "DummyGame" ist quasi der übergeordnete Meister, der in seinem Thread seine Sub-Spielchen der Reihe nach durchnudelt. Das passiert mit der for-Schleife, die man auch als
Java:
for (int i=0; i<subGames.size(); i++)
{
    Game subGame = subGames.get(i);
    ...
schreiben könnte. Für jedes dieser SubSpiele passiert folgendes:
- Die "Main Component" des SubSpiels wird in den subGameContainer gelegt
- Es wird gewartet, bis das SubSpiel angezeigt wird
- Das SubGame wird initialisiert und laufen gelassen
Das frickelige daran ist: Das ganze passiert in einem eigenen Thread. Das Anzeigen des Spiels (d.h. das Hinzufügen zum subGameContainer) muss aber auf dem Event-Dispatch-Thread gemacht werden (das ist das mit den "SwingUtilitites". Das SubSpiel darf aber erst loslaufen, wenn es vollständig angezeigt wird. Deswegen muss der Game-Thread warten, bis der Event-Dispatch-Thread das SubSpiel tatsächlich anzeigt - das ist dieser Krampf mit dem "waitUntilShowing".
NOCHMAL: Das könnte man vielleicht viel einfacher machen, z.B. wenn die SubSpiele vielleicht gar nicht in einem eigenen Thread laufen müßten (BRAUCHEN die SubSpiele eine Animation? :bahnhof: ) oder wenn jedes SubSpiel einen eigenen Start-Button hätte oder so. Das ist im Moment nur so "kompliziert", weil die Subspiele völlig automatisiert nacheinander in einem eigenen Thread laufen... Mit mehr Infos hätte man ggf. etwas einfacheres machen können, was ggf. auch besser zu deinen Zielen gepasst hätte, aber so... kann man nur raten... :bahnhof: Ggf. solltest du wirklich nochmal genauer sagen, wie das mit den erwähnten "Leveln" dann laufen soll. Wenn man das unüberlegt so übernimmt, wie es ist, und auf einen ganz anderen Use-Case anzupassen versucht, könnte es krampfig werden.


[Java]
private final List<GameListener> gameListeners;
[/code]
Hier speicherst du ja alle Listener - ich dachte "final" bedeutet, dass man daran nicht mehr ändern kann. Das ist für mich bisher ein Widerspruch.

'final' bedeutet in diesem Fall, dass die Liste selbst sich nicht ändert. Der Inhalt der Liste kann sich ändern. Wenn es dich stört, nimm' das 'final' einfach weg ;)



Java:
 Game game = new DummyGame();
Was macht diese Zeile genau? Ich kenne nur:
[Java]
Game game = new Game();
oder
DummyGame game = new DummyGame();
[/Java]

Das sind Grundlagen: 'Game' ist ein Interface, und DummyGame eine Implementierung. Das ist das gleiche wie
Java:
JComponent component = new JButton();
oder
Java:
List<String> list = new ArrayList<String>();
oder suggestiv
Java:
Tier tier = new KleinesFlauschigesSchwarzWeißGeflecktesKaninchen();

Man sollte immer den Typ verwenden, der "das mindeste" beschreibt, was man braucht. An dieser Stelle muss man nur wissen, dass das, was man da erstellt, ein "Game" ist, aber ob es das "DummyGame" ist, oder ein "MySpecialGame", ist egal.




Wie würdest du anstelle von selbst generierten 2D Objekten Bilder implementieren?

So, wie jetzt im DummyGameEntity ein "Shape" verwendet wird, könnte man dort zusätzlich ein "BufferedImage" verwenden. (Das Shape bräuchte man dann ggf. nur noch, um festzustellen, ob es angeklickt wurde - und in diesem Fall wäre das Shape ein Rectangle2D, das die Größe des Bildes beschreibt).
Java:
public class ImageGameEntity implements GameEntity
{
    ...
    private BufferedImage image;
    
    DummyGameEntity(BufferedImage image)
    {
        this.image = image;
        this.shape = new Rectangle2D.Double(0,0,image.getWidth(),image.getHeight());
    }
    
    @Override
    public void paintObject(Graphics2D graphics)
    {
        Graphics2D g = (Graphics2D)graphics.create();
        g.translate(position.getX(), position.getY());
        g.drawImage(image,0,0,null); // Bild statt des shapes malen
        g.dispose();
    }
...

Das Bild kann man mit ImageIO laden und dann dort im Konstruktor übergeben.









DummyDemo (siehe Text)
Java:
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class DummyDemo 
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame f = new JFrame("Game");
                final Game game = new DummySubGame("Demo", new Ellipse2D.Float(-10,-10,20,20));
                f.getContentPane().add(game.getMainComponent());
                f.setSize(600,600);
                f.setVisible(true);
                
                Thread thread = new Thread(new Runnable()
                {
                	@Override
                	public void run()
                	{
                            game.initGame();
                	    game.runGame();
                	}
                });
                thread.start();
            }
        });
    }

}
 

Darokh

Mitglied
Danke - ich schaue mir den neuen Code nach dem Essen mal genau an.

Damit du mal einen Überblick über die Subgames bekommst:

Jedes SubGame läuft (wie du weißt) für sich alleine.
Jeder SubGame besitzt auf jeden Fall ein eigenes Level, welches sich abhängig von Zeit oder Punktzahl (die man erspielen kann) erhöht.

Die SubGames werden nacheinander hinzugeschaltet. Das heißt, zuerst startet man mit SubGame1 auf Level 1.
Wenn SubGame1 Level 5 erreicht hat, wird beispielsweise Subgame2 auf Level 1 hinzugeschaltet. Da sich der Patient nun erstmal an alles gewöhnen muss, wird SubGame1 erstmal auf Level 3 zurückgesetzt. Dafür sind ja nun auch 2 SubGames parallel zu bewältigen. Aber einer neuen Bedingung wird dann SubGame 3 hinzugeschaltet, wieder mit einem Zurückstellen der Level.

Die SubGames selbst können Animierte Bilder haben, muss aber nicht.
Generell soll implementiert werden:
- statische Bilder
- animierte Bilder
- Abspielen von Sounds
- ansprechen von COM-Ports: Leuchtdioden sollen angesprochen werden. Da hab ich ziemliche Bedenken, dass ich das zu Lebzeiten noch hinbekomme.

Das Ablaufschema eines Spiels ist so:
Es gibt in der Psychologie so genannte "Trials". Ein Trial besteht immer aus einer festen Abfolge von Reizen (also Bilder, Töne...noch allgemeiner: ein Fragebogen mit einer Frage ist auch ein Trial - also im Prinzip "kleinstes Testelement, aus dem man etwas ziehen kann"). Auf einen Trial soll man natürlich (zumindest in diesem Spiel) auch reagieren.

Ein Trial wäre in diesem Spiel beispielsweise:
Subgame1:
Man sieht 8 Kreise, die in einem Kreis angeordnet sind. Zwischendurch blinkt ein Kreis auf. Aufgabe: Auf dem NumPad die äquivalenten Positionen drücken. Mit Levelaufstieg werden die Kreise immer schneller hintereinander aufblinken.

Subgame2:
In der Mitte (innerhalb des Kreises) erscheinen beispielsweise Bilder, die entweder differenziert werden müssen. Sprich, ist dort ein Kontrast zu sehen oder nicht --> WEnn ja: Pfeiltaste hoch drücken, wenn Nein, Pfeiltaste runter drücken.


Das klingt nun alles sehr artifiziell, wird aber später dann noch spannender. Wir oder besser gesagt ich muss da erstmal selbst schauen, auf welchem Level die Patienten mit Reizen stimuliert werden dürfen.

Jedenfalls muss ich also in jedes Subgame diese Trials mit bestimmten Inter-Trial-Zeiten (also wie lange braucht es, bis die nächste "Aufgabe" / der nächste Trial beginnt einbauen - abhängig vom SubGame-Level.

Ich hoffe, du hast nun einen besseren Einblick bekommen, was ein SubGame ist.

Guten Mittag!
Darokh
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N BMI Rechner Was haltet ihr von dem Code habt ihr Verbesserungsvorschläge weil design teschnisch ist das nicht das geilste würde das gerne überarbeiten Java Basics - Anfänger-Themen 12
D Verbesserungsvorschläge zur Struktur einer Client Server Desktop Chat App Java Basics - Anfänger-Themen 24
Vivien Bitte um Optimierungsvorschläge / Verbesserungsvorschläge / allgemeines Feedback Java Basics - Anfänger-Themen 8
N Verbesserungsvorschläge zu Wegfinder Programm Java Basics - Anfänger-Themen 26
S verbesserungsvorschläge? Java Basics - Anfänger-Themen 19
fLooojava first project - Verbesserungsvorschläge am Code Java Basics - Anfänger-Themen 8
Z Zahl Pi probabilistisch berechnen (Kritik/Verbesserungsvorschläge) Java Basics - Anfänger-Themen 4
B Erste Schritte Wechselgeld berechen. Verbesserungsvorschläge Java Basics - Anfänger-Themen 10
M Bitte um Verbesserungsvorschläge Java Basics - Anfänger-Themen 14
L Suche Verbesserungsvorschläge für mein erstes Programm Java Basics - Anfänger-Themen 34
Chucky Einfacher Taschenrechner Verbesserungsvorschläge Java Basics - Anfänger-Themen 13
D Quellcode für cmd funktioniert nicht Java Basics - Anfänger-Themen 9
amelie123456 Objekt Farbe Quellcode Java Basics - Anfänger-Themen 4
M Mein quellcode wird nicht in der Konsole ausgegeben Java Basics - Anfänger-Themen 3
jhCDtGVjcZGcfzug Was genau ist mit diesem Quellcode gemeint? Java Basics - Anfänger-Themen 5
jhCDtGVjcZGcfzug Was ist mit diesem Quellcode gemeint? Java Basics - Anfänger-Themen 3
J Wie bestehenden Quellcode in IDE richtig übernehmen Java Basics - Anfänger-Themen 27
TimoN11 IntelliJ , Ausgabe von einem Quellcode in Eingabe eines Quellcodes Java Basics - Anfänger-Themen 1
H Quellcode Scanner Klasse Java Basics - Anfänger-Themen 2
P Quellcode LinkedList Java Basics - Anfänger-Themen 2
M Bitte um Hilfe bei Quellcode (Rekursion) Java Basics - Anfänger-Themen 6
F Quellcode wird nicht in cmd angezeigt Java Basics - Anfänger-Themen 8
N Erste Schritte Quellcode fehlerhaft Java Basics - Anfänger-Themen 2
J Methoden Quellcode DP Fibonaaci erklärt Java Basics - Anfänger-Themen 5
L Fehler in Quellcode?! Java Basics - Anfänger-Themen 3
D Generics ArrayList: Bug im Quellcode Java Basics - Anfänger-Themen 14
G Wie kann ich mein Quellcode als Programm vom desktop starten? Java Basics - Anfänger-Themen 1
Hacer Quellcode lesen Java Basics - Anfänger-Themen 13
M Greenfoot World und Actor Quellcode Java Basics - Anfänger-Themen 13
B Quellcode einelsen "line by line" (und abspeichern in file (txt) Java Basics - Anfänger-Themen 7
G Quellcode verstehen Java Basics - Anfänger-Themen 9
F Quellcode optimieren... Java Basics - Anfänger-Themen 4
M Verstehe das Programm(Quellcode) nicht!! Java Basics - Anfänger-Themen 12
U Java Quellcode Schaltjahr Java Basics - Anfänger-Themen 13
D Quellcode verstehen Java Basics - Anfänger-Themen 4
G Quellcode "splitten" Java Basics - Anfänger-Themen 6
V Array ermitteln - in Quellcode speichern Java Basics - Anfänger-Themen 15
J Quellcode von einem Link kriegen? Java Basics - Anfänger-Themen 3
W Datentypen String in Quellcode umwandeln Java Basics - Anfänger-Themen 25
O Quellcode nach bestimmter Ausgabe durchsuchen Java Basics - Anfänger-Themen 14
J Java-Quellcode Java Basics - Anfänger-Themen 13
J Tabelle aus Website einlesen [nicht im Quellcode] Java Basics - Anfänger-Themen 6
T Quellcode zur .jar oder .exe Java Basics - Anfänger-Themen 7
P Suche Java Programme mit gutem/anfängertauglichem Quellcode Java Basics - Anfänger-Themen 8
M Quellcode kann nicht kompiliert werden Java Basics - Anfänger-Themen 6
S Grafische Oberfläche Quellcode ändern Java Basics - Anfänger-Themen 8
T Quellcode zu Jar? Java Basics - Anfänger-Themen 14
S Erste Schritte Fakultät Quellcode Java Basics - Anfänger-Themen 12
E Quellcode Erklärung Java Basics - Anfänger-Themen 8
N Feste Hardcodierte Pfade im Quellcode Java Basics - Anfänger-Themen 6
S Allgemein: Quellcode einrücken Java Basics - Anfänger-Themen 8
W Kurzer Quellcode klein aber oho! Java Basics - Anfänger-Themen 7
H frage zu meinem quellcode Java Basics - Anfänger-Themen 10
M String in Quellcode umwandeln Java Basics - Anfänger-Themen 9
S Textfragmente aus Quellcode lesen und abspeichern Java Basics - Anfänger-Themen 2
U Netzwerk Chatprogramm Quellcode funktioniert nicht Java Basics - Anfänger-Themen 6
A Quellcode aus diesem Forum für komerzielle Zwecke/Bachelor Thesis? Java Basics - Anfänger-Themen 4
F Datei Quellcode Java Basics - Anfänger-Themen 8
W Hilfe bei Interpretation von Quellcode Java Basics - Anfänger-Themen 8
X Webseite auslesen ohne Quellcode zu splitten Java Basics - Anfänger-Themen 3
A log4j - wie kann ich im Quellcode initialisieren statt in der properties-Datei? Java Basics - Anfänger-Themen 2
N Quellcode absichern? Java Basics - Anfänger-Themen 21
M mit java quellcode im browser öffnen Java Basics - Anfänger-Themen 1
hdi Programmier-Stil : Speicher vs. Quellcode Java Basics - Anfänger-Themen 67
M Quellcode verbessern Java Basics - Anfänger-Themen 6
M Brauche Hilfe beim Verstehen vom Quellcode Java Basics - Anfänger-Themen 4
I Kann nicht compilieren warum? Bei großen Quellcode. Java Basics - Anfänger-Themen 8
A Änderung im Quellcode > javac > keine Änderung in Kons Java Basics - Anfänger-Themen 6
C Quellcode richtig bisher? wie gehts weiter? Java Basics - Anfänger-Themen 13
S Problem mit url, inputStream und bytes beim Quellcode laden. Java Basics - Anfänger-Themen 6
D quellcode in webseite einbinden Java Basics - Anfänger-Themen 7
B Kann Quellcode von "Hanoi" nicht verstehen. Bitte Java Basics - Anfänger-Themen 4
D Fragen zu Quellcode QuickSorter Java Basics - Anfänger-Themen 13
F Quellcode & Ausgabe Java Basics - Anfänger-Themen 6
M Java Quellcode in eine exe datei umwandeln Java Basics - Anfänger-Themen 4
G Quellcode kommentieren Java Basics - Anfänger-Themen 6
S html quellcode runterladen Java Basics - Anfänger-Themen 2
D Quellcode richtig lesen lernen Java Basics - Anfänger-Themen 8
S Von einer jar.Datei den Quellcode. Java Basics - Anfänger-Themen 1
A Jar Datei im Quellcode einbinden Java Basics - Anfänger-Themen 3
G Problem mit Quellcode! Java Basics - Anfänger-Themen 15
D Import von Quellcode Java Basics - Anfänger-Themen 2
H Wo in GUI-Klasse bringe ich Quellcode unter? Java Basics - Anfänger-Themen 8
M Verstehe den Quellcode nicht ganz Java Basics - Anfänger-Themen 3
O mathematische Formel in quellcode Java Basics - Anfänger-Themen 5
M Quellcode einschränken?! Java Basics - Anfänger-Themen 6
L Fehler im simplen Quellcode! Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben