Vector überschreibt Elemente bei add()-Methode

Memorius

Mitglied
Hallo zusammen, dies ist mein erster Beitrag hier.

Ich habe folgendes Problem: Ich habe einen Vector, in den ich Elemente schreiben will. Das mache ich mit .add() . Jetzt ist es aber so, dass er alte Elemente plötzlich überschreibt, was er bei add() bzw. addElement() nicht tun sollte.

Java:
entVec.addElement(new Player(player.getX(), player.getY(), this));

Das ganze gehört zu einem Game, ich kann wörtlich dabei zuschauen, wie Elemente verschwinden, wenn ich die addElement()-Methode aufrufe.

Danke im Voraus!
 
An der einen Zeile wird definitv nicht liegen.
Code:
addElement
überschreibt nichts.
 
vielleicht sind die Attribute in Player statisch, dann kann es eh nur insgesamt eine Positionen für alle Player geben,
wobei Werte aus altem Player nicht gerade ein Problem sein sollten, wären ja dieselben 😉

poste doch wenigstens mal diese Klasse
 
Wow, kommen hier schnell Antworten, danke! 🙂

Es ist schwierig, zu entscheiden was hier relevant ist, da es mittlerweile schon so viel Code ist. Also zu Beginn wird der Vector mit den Elementen gefüllt, da funktioniert alles richtig. Jetzt wollte ich einfach mal aus Testgründen mehrere "Figuren" in der Welt platzieren, einfach da wo ich gerade stehe. Dazu erstelle ich einfach einen neuen "Player", was eigentlich nichts machen sollte, beim Player ist nix statisch und die Kontrolle der Figur läuft über eine Referenz die eh nur auf dem ersten Player bleibt.

Java:
public void keyPressed(KeyEvent e) {

		switch (e.getKeyCode()) {
		case KeyEvent.VK_LEFT:
			player.goLeft(true);
			break;
		case KeyEvent.VK_RIGHT:
			player.goRight(true);
			break;
		case KeyEvent.VK_UP:
			player.goUp(true);
			break;
		case KeyEvent.VK_DOWN:
			player.goDown(true);
			break;
		case KeyEvent.VK_F1:
			switchDev();
			break;
		case KeyEvent.VK_F12:
			printInfo();
			break;
		case KeyEvent.VK_SPACE:
			entVec.addElement(new Player(player.getX(), player.getY(), this));
			break;
		}

Das Ganze läuft mit Swing und wird von nem Thread aus animiert. Swing hat angeblich so einige Eigenheiten, kann es damit zusammenhängen? Dass das keyPressed-Event und das Swing-Zeug nicht richtig zusammenspielt?

new Player() macht nichts, was den Vector irritieren könnte, würde ich mal sagen.

Java:
public Player(double initX, double initY, Board b) {
		super(initX, initY, b);

		Img[] images = { b.imgP_Front_Stand };
		super.setImages(images);
	}
 
wovon erbt Player?

wie genau wirkt sich das 'überschreiben' oder 'verschwinden' aus?
hast du selber paint-Methoden, die dann was anderes zeichnen?
logge dort was warum gezeichnet wird, was sieht diese paint-Methode, welche Player im Vector mit welchen Positionen usw.,
Vorher/ Nachher-Vergleiche
 
Der Player erbt von Drawable, das erbt von Entity - alles selbst geschriebene Klassen.

In entVec sind alle Level Elemente (im Moment nur Wände) und eben der Player, bzw. mehrere Player wobei die anderen nichts machen außer rumstehen. Ich zeichne über die paint(Graphics g) Methode, die ich von JPanel überschreibe. Ich sehe also die Wände im Spiel und habe außerdem eine Anzeige eingebaut, die mir zu jeder Zeit entVec.size() ausgibt. Zum Start sind da 116 Elemente drin. Wenn ich nun die Leertaste drücke erscheint an der Stelle, wo ich stehe, ein weiterer Player. Es ist dann anscheinend immer Zufall, ob entVec.size() sich um 1 erhöht - wie es ja sein soll - oder die Zahl gleichbleibt und stattdessen ein Stück Wand verschwindet (und zwar das, das im Vector an letzter Stelle stand). Wenn ich schon mehrere Player geaddet habe, verschwinden auch gerne mal die statt der Wand.

Nochmal zu Swing - kann es vielleicht echt sein, dass das keyTyped Event nicht sauber mit Swing zusammenarbeitet? Ich begrenze die FPS nicht, das Programm ist ständig am Arbeiten, wenn keyTyped in einem eigenen Thread arbeitet oder so kanns da bestimmt leicht zu interferenzen kommen oder?
 
Interferenzen kann es geben, ja, wenn auch andere deine Threads gleichzeitig einfügen und entfernen,
aber eher gibts bei sowas Exceptions als verlorene Elemente..,
entfernt irgendeine Programmstelle aktiv? ist die hier wirklich nicht verdächtig?

wenn schon size()-Probleme macht, dann kannst du ja direkt in der keyPressed vor und nach dem Einfügen die size loggen,
ebenso zu Beginn und Ende von paint, außerdem vielleicht noch in einer vorhandenen Spielschleife eines Threads usw.,

du könntest auch eine eigene Klasse statt des Vectors verwenden, kann intern ja einen Vector haben,
nach außen nur add/remove anbieten + size + get, kein direktes iterieren über die Elemente, sonder for-i-Schleifen,
dann logge alle Methodenaufrufe, zumindest erstmal alle add+remove mit jeweils size davor/danach, ein so kontrolliertes Objekt kann nicht heimlich verändert werden,
um zu erkennen woher die Aufrufe kommen kannst du einen String als zweiten Parameter verwenden oder komplizierter mit dem StackTrace des Threads arbeiten,

das add() sollte weiterhin keine Auswirkungen haben,
bei manchen Collections oder auch Listen-Methoden wie contains(), Sortieren könnte man noch an kaputte equals- + hashCode-Methoden denken,
aber add() macht nun wirklich nicht viel
 
Hi, ich habe jetzt an ein paar Stellen geloggt und mein Verdacht hat sich bestätigt.

Ich sortiere den Vector in jedem Frame, um die Figuren in der richtigen Reihenfolge rendern zu können. KeyPressed() pfuscht nun, wenn es dumm läuft, direkt in diesen Vorgan rein - dadurch geht ein Element verloren.

Okay, Problem erkannt - aber wie lösen? Soll ich das Element, das ich hinzufügen will vielleicht in einer Separaten Variablen erst ablegen, und das Programm dann in jedem Frame prüfen lassen ob in dieser Variablen was zum adden liegt? Oder soll ich das ganze irgendwie synchronisieren, das Ganze scheint ja ein Thread Problem zu sein. Wär toll, wenn mir erfahrene Leute da nen kleinen Tipp geben könnten 🙂

Vielen Dank für die klasse Hilfe hier!
 
Sortieren nebenbei.., das gibts ja auch noch, stimmt

die Standardlösung sieht für separate Threads
SwingUtilities.invokeLater(Runnable)
vor, in den Runnable-Objekt die Änderungen an GUI-relevanten Daten, aber nur die Änderungen, nicht die sekundenlangen Berechnungen/ Spiel-Schleifen

vielleicht etwas veraltet und SwingWorker moderner, zu solchen Themen sicherlich lieber erstmal groß suchen und lesen,
sollte ich irgendwann auch mal machen..

Lesson: Concurrency in Swing (The Java™ Tutorials > Creating a GUI With JFC/Swing)
 
Hi,

ich habe es jetzt einfach so geregelt:

Der KeyListener darf nur in Variablen schreiben, ob ein Key gerade gedrückt wird. Das Spiel liest dann in jedem Tick diese Variablen. Dadurch kann der KeyListener nicht mehr auf z.B. den Vector zu ungünstigen Zeitpunkten zugreifen.

Vielen Dank euch allen!
 

Zurück
Oben