Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Pong, aber ich find einen großen Bug nicht



Andy1988
23-03-2006, 19:21
Hi,
Ich habe mal im Unterricht angefangen meine eigene Pong Version zu schreiben. Es soll mal übers Netzwerk spielbar sein und sowas. Einfach mal um was anderes, als die langweiligen Aufgaben auf der Webseite meines Lehrers, die ich eh schon alle fertig hab :D

Nunja, das funktioniert soweit ganz gut. Ich hab mir irgendein Space Invaders Tutorial angeschaut und das so adaptiert, wie ich das brauchte. Allerdings hab ich da einen riesen Bug drin, den ich nicht finde. Wenn der Ball relativ schnell ist und auf einen Schläger trifft fliegt dieser einfach durch.
Ich hab mir auf der Konsole mal ausgeben lassen, ob die Methode, die bei einer Kollision aufgerufen wird auch ausgeführt wird. Und es passiert, allerdings fliegt der Ball nicht in eine andere Richtung.

Kann sich das vielleicht mal jemand anschauen? Ich suche schon 2 Tage und ich find es einfach nicht. Vor allem, weil das ja mit langsamen Bällen einwandfrei funktioniert.

Achja nochwas:
Bisher kann man nicht/kaum gewinnen :D Die KI ist noch zu gut.
Dann zittern die Schläger von der KI noch ein bischen usw. Das sind alles noch Sachen, um die ich mich noch nicht gekümmert hab. Ich will erstmal, dass der Ball nicht mehr durch die Schläger fliegt ^^
Evtl. könnte ich dann anstatt gif Dateien auch einfach Java Klassen für die Rechtecke und Kreise benutzen. :D Is nich so Ressourcenlastig.

bischi
23-03-2006, 19:41
Ohne den Code anzuschauen: Das sieht bös nach diesem Typ von Fehler aus:


if(ball == Schläger)
then reflect

Wenn du das ganze jetzt scheller laufen lässt (=Sprünge grösser) ist die Koordinate vorher vor dem Schläger und nachher hintendran.

besser: if(ball <= Schläger)

MfG Bischi

PS: Hab mir noch schnell den Code angeschaut: Kaum einen Kommentar - da würd ich meine Fehler auch nicht finden ;) Tipp: Bei gutem Quellcode sind mindestens die Hälfte aller Zeilen Kommentare! Erstens fallen dir dabei die Fehler auf, die du machst, zweitens wird das ganze auch für andere Leute lesbar und drittens weisst du zwei Wochen später immer noch, was genau du geproggt hast...

peschmae
23-03-2006, 20:16
Der mit der Hälfte ist wohl ein Witz - bei den meisten Zeilen gibts eh nichts zu sagen. :D
(Jetzt mal von Assembler abgesehen ;))

MfG Peschmä

Andy1988
23-03-2006, 20:39
Naja ich glaub daran liegts ehr weniger. So eine Abfrage habe ich nicht. ich spanne um jedes Objekt ein Rectangle und schaue, ob sich die beiden Rectangles zweier Objekte überschneiden.

Ich hab eine ArrayList, in der alle Objekte, die auf den Bildschirm gezeichnet werden und kollidieren können. Die werden in einer for Schleife alle 10ms durchlaufen:

for (int i = 0; i < entities.size(); i++)
{
for (int j = i + 1; j < entities.size(); j++)
{
Entity me = (Entity) entities.get(i);
Entity him = (Entity) entities.get(j);

if(me.collidesWith(him))
{
me.collidedWith(him);
him.collidedWith(me);
}
}
}
Wenn also die beiden Objekte kollidieren wird die abstrakte Methode collidedWith(Object) ausgeführt. Und in der gibt mir aber auch der Debugging Code aus, dass sie aufgerufen wurde und entsprechend gehandelt wurde. Ich habe so eine Abfrage, wie du oben hast gar nicht. Deswegen verzweifel ich einfach mitlerweile ^^
Zu langsam kann mein Code auch nicht sein, weil ich ohne Threads arbeite, also alles nacheinander abläuft.

bischi
23-03-2006, 20:44
Naja ich glaub daran liegts ehr weniger. So eine Abfrage habe ich nicht. ich spanne um jedes Objekt ein Rectangle und schaue, ob sich die beiden Rectangles zweier Objekte überschneiden.

Genau das ist es: Wenn du sie schneller laufen lässt (=grössere Sprünge), überschneiden sie sich nicht mehr!

Und zu den Kommentaren: Ich mein das Ernst! Bei mir sinds normalerweise eher noch mehr; Dafür kann ich später auch mal wieder den Code anschauen und weiss gleich wieder, was ich damals überlegt hab.

MfG Bischi

Andy1988
23-03-2006, 20:56
OK, dann mach ich doch einfach mal den Ball größer ^^

Ja, ich hab die Main Klasse schon fast komplett durchkommentiert.
Ich merk das ja selber. Vor allem bei dem OOP.
Die eine Klasse erbt von der, hat die und die abstrakte Methode. Dann wird in einer Methode über super was von der übergeordneten Klasse aufgerufen usw. :eek:

edit:
Hmm... Jetzt hab ich den Ball sogar auf 100x100 Pixel gebracht und es passiert immernoch.
Und meine Debugging Ausgaben beschreiben mir auch eindeutig eine Kollision mit dem Schläger, auch wenn der Ball durchfliegt! Aber das kann ja irgendwie nich....

nochmal edit:
OK... Ich muss gestehen, dass es doch besser geht, wenn ich den Ball vergrößere. Nur gefällt mir das alles irgendwie nicht. Evtl. lass ich die Kollisionserkennung parallel zur Anzeige der Objekte einfach in nem Thread laufen und zwar OHNE 10ms Pause. Damit hab ich dann ja sozusagen eine höhere Auflösung, als wenn ich das nacheinander ausführe.

Andy1988
24-03-2006, 21:12
So. Ich hab das ganze mal in einen Thread gebastelt. Das funktioniert auch, nur is jetzt die nächste Kuriosität aufgetreten.
Ich habe an jedem Entity zwei Attribute für die Beschleunigung: dx und dy.
Diese setze ich per Zufall bei der Kollision mit einem Schläger auf 5*Math.random() (seit neustem, der Source oben stimmt schon nicht mehr). Positive oder negative Werte geben die Richtung an. Das wird auch noch mal per Zufall bestimmt. Nur nicht für die Seite mit dem Schläger. Wär ja doof, wenn der Ball auf den unteren Schläger trifft und dann weiter nach unten fliegt ^^

Auf jeden Fall fliegt der Ball ganz gut, bis zur ersten Kollision. Dann wird er höllisch schnell. Das sieht in meinen Konsolen Ausgaben ungefähr so aus:

dx: -3.913731282538219
dy: -4.365766551652948
dx: -3.913731282538219
dy: -4.365766551652948
New Position because of collision with HorizontalKiEntity...
Collided with HorizontalKiEntity
Collided
New Position because of collision with HorizontalKiEntity...
Collided with HorizontalKiEntity
Collided
New Position because of collision with HorizontalKiEntity...
Collided with HorizontalKiEntity
Collided
New Position because of collision with HorizontalKiEntity...
Collided with HorizontalKiEntity
dx: -114.76567646488111
dy: 994.1808340303595
Collided
dx: -114.76567646488111
dy: 994.1808340303595

Wenn ich die Kollisionsbestimmung nicht in einem Thread laufen lasse funktioniert alles einwandfrei.
Hat jemand ne Idee?

bischi
25-03-2006, 09:32
Kommunikation zwischen Threads kann zu sehr lustigen Ergebnissen führen, wenn sie nicht sauber ausgeführt ist... synchronized dürfte hier unter Umständen dein Freund sein.

MfG Bischi

Andy1988
25-03-2006, 23:46
Aber das komische ist ja, dass ich ja über den Thread nur einen neuen Wert (die Beschleuning, die in diesem Fall ja extrem hoch wird; immer um die 1000) zuweise. Ich addiere ja nichts oder sowas.
Wie kann denn dann der Wert so hoch werden? Das kapier ich nicht. Das einzige kann sein, dass der Wert, der von Math.random() zurückgegeben wird, zu hoch wird. Aber selbst das verstehe ich nicht. Aber synchronized Threads werd ich auf jeden Fall testen.

bischi
26-03-2006, 18:48
Threads sind im Allgemeinen NICHT trivial. Probleme kanns beispielsweise dann geben, wenn gleichzeitig:

Thread eine Variable schreibt und anderer die selbe Variable lesen will (und ähnliche Fälle).

Solche Fehler sind dann im Allgemeinen auch nicht (einfach) reproduzierbar.

Weitere Probleme mit Threads kann die Ressourcenverteilung sein (unser Inf-Prof hat mal gesagt, dass für eine einfache Ressourcenverwaltung, die einigermassen zuverlässig ist, du selbst etwa 10'000 Zeilen Code schreiben musst!).

Darum: Bei Threads immer aufpassen und nach Möglichkeit weglassen, falls:

- viele gemeinsame Variablen existieren (bei wenigen bietet sich wie gesagt synchronized an - bei vielen verlangsamt sich das ganze unnötig)
- zeitkritische Abläufe

MfG Bischi

Andy1988
28-03-2006, 15:15
Thread eine Variable schreibt und anderer die selbe Variable lesen will (und ähnliche Fälle).
Ja... das ist bei mir genau der Fall...