# Zeldaklon Problem mit Wand-Kollision



## cleanerleon (9. Mrz 2015)

Hallo liebe Community,

ich fang direkt mal mit meinem Problem an:

Ich habe angefangen ein kleines Spiel in Java zu schreiben (mit der Hilfe eines YT-Tuts) und bin mittlerweile über die Vorgaben des Tutorials weit hinaus. Bei dem Spiel handelt es sich um einen kleinen Zeldaklon im Fenstermodus. Bis jetzt gibt es einen Hintergrund auf dem der Spieler sich mit WASD bewegen kann. Die Bewegung ist animiert durch mehrere kleine Pixelart PNGs die nacheinander geladen werden um eine Bewegung darzustellen. 

Nun habe ich eine Klasse Wand erstellt, die Rechteckige Objekte erzeugt mit denen der Spieler kollidieren kann, welche ich genau an den Stellen auf dem Bildschirm platzieren möchte, an denen der Spieler nicht weiterlaufen soll (z.B. Bäume, Wände etc.). Bei einem erzeugten Wand Objekt klappt das auch soweit, aber sobald ich mehr als eins erzeuge wird die Kollision nur noch an einem der Objekte richtig simuliert. 

Ich hab mir jetzt 2 Tage den Schädel zermartert warum, aber ich komm nicht drauf...
Wahrscheinlich habe ich auch viele der Funktionen die bereits implementiert sind umständlicher gemacht als es hätte sein müssen, aber ich bin noch Anfänger in Java und das ist mein erstes Spiel was ich in Java schreibe, bin also für Tipps offen. Ich werde einfach mal mein gesamtes Projekt an diesen Post anhängen in der Hoffnung jemand kann mir vlt weiterhelfen. Der Code ist in Eclipse geschrieben. 

Gruss Leon

PS: Da das Projekt die maximale Uploadgröße überschreitet hab ich sie bei einem Filehoster hochgeladen

Spieleentwicklung.zip


----------



## BRoll (9. Mrz 2015)

Dein Problem ist, dass deine Attribute der Wand static sind.
Dadurch haben alle Wände immer genau die gleiche Position, weil sie auf 
die gleichen Attribute zugreifen.
Schmeiss das (dort sowieso nicht angebrachte) static raus, sonst bringt es dir eh nichts
neue Wand Objekte anzulegen.


----------



## Androbin (9. Mrz 2015)

BRoll hat gesagt.:


> Dein Problem ist, dass deine Attribute der Wand static sind.
> Dadurch haben alle Wände immer genau die gleiche Position, weil sie auf
> die gleichen Attribute zugreifen.
> Schmeiss das (dort sowieso nicht angebrachte) static raus, sonst bringt es dir eh nichts
> neue Wand Objekte anzulegen.


Ich will doch sehr hoffen, dass cleanerleon die Bedeutung von static kennt, sonst wird das wohl nichts.


----------



## BRoll (9. Mrz 2015)

[OT]
Ich denk nicht dass er genau weiß was static macht,
sonst hätte er es an der Stelle nicht eingesetzt.
[/OT]


----------



## cleanerleon (9. Mrz 2015)

Danke für den Tipp, 

Ihr habt Recht das static an der Stelle war wirklich nicht sinnvoll, habe das jetzt rausgeschmissen. Problem bleibt allerdings immer noch das selbe  :/


```
package Zeldaklon;

import java.awt.Rectangle;

public class Wand {
	
	private int collide; //0 = nein, 1 = links, 2 = rechts, 3 = oben; 4 = unten;
	private Rectangle bounding;
	private int x, y, width, height, i;
	
	public Wand(int x,int y, int width, int height){
		collide = 0;
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
	    i = 4;
		
		bounding = new Rectangle(x, y, width, height);
	}
	
	public int kollisionsCheck(float timeSinceLastFrame){
		if (bounding.intersects(Player.getBounding())){
			//rechts
			if((Player.getBounding().x <= x+width)&&(Player.getBounding().x>x+width-200*timeSinceLastFrame)&&(Player.getBounding().y>y-64)&&(Player.getBounding().y<y+height))collide = 2;
			
			//links
			if((Player.getBounding().x+64 >= x)&&(Player.getBounding().x<x+200*timeSinceLastFrame)&&(Player.getBounding().y>y-64)&&(Player.getBounding().y<y+height))collide = 1;
			
			//oben
			if((Player.getBounding().y+64 >= y)&&(Player.getBounding().y<y+200*timeSinceLastFrame)&&(Player.getBounding().x>x)&&(Player.getBounding().x<x+width))collide = 3;
			
			//unten
			if((Player.getBounding().y <= y+height)&&(Player.getBounding().y>y+height-200*timeSinceLastFrame)&&(Player.getBounding().x>x)&&(Player.getBounding().x<x+width))collide = 4;
			
		}
		else collide = 0;
		
		return collide;
	}
	

}
```


----------



## BRoll (9. Mrz 2015)

Dann kannst jetzt nur noch an deiner collisionCheck() Methode liegen.
Versuch dich da mal durchzudebuggen und schau ob es wirklich triggert
wenn der Spieler innerhalb des rechtecks ist.
Deine Abfragen sehen auch ziemlich unstrukturiert und unübersichtlich aus,
bau dir eine Methode dazwischen oder splitt den riesen Term mal auf.
Ansonsten verwende doch von deinem Rectangle bounding die contains Methode,
anstatt alles selber zu Berechnen.


----------



## cleanerleon (9. Mrz 2015)

Alles klar, dann mach ich mich mal an die Arbeit.
Das mit der contains Methode hört sich interessant an, aber ich muss doch wissen an welcher Seite meines Wand Objektes der Spieler sich gerade befindet, um zu verhindern, dass er weiter in die Wand reinläuft, oder seh ich das falsch? Wie kann ich denn genau das abfragen?

Danke für die Hilfe bisher.

Gruß Leon

Edit:
Habe bei Kollision einfach mal eine Konsolenausgabe triggern lassen.


```
public int kollisionsCheck(float timeSinceLastFrame){
		if (bounding.intersects(Player.getBounding())){
			//rechts
			if((Player.getBounding().x <= x+width)&&(Player.getBounding().x>x+width-200*timeSinceLastFrame)&&  (Player.getBounding().y>y-64)&&(Player.getBounding().y<y+height)){
				collide = 2;   
				System.out.println("Kollision");
			}
```

Die funktioniert auch soweit. Bei nur einem erzeugten Wand-Objekt kollidiert der Spieler und "Kollision" wird ausgegeben.
Bei zwei Objekten kollidiert der Spieler nicht mehr am ersten Objekt, die Konsolenausgabe wird allerdings trotzdem noch zum richtigen Zeitpunkt ausgegeben. Von daher kann die kollisionsCheck() Methode ja eigentlich nicht falsch sein ..bin mit meinem Latein am Ende


----------



## BRoll (9. Mrz 2015)

Ok ich denke ich habe die Stelle gefunden.
In der Schleife, wenn du mit dem ersten Block eine Collision hast, dann setzt du dein
col auf !=0. Also das eine Kollision geschehen ist.
Wenn dann der zweite block kommt und keine ist, wird col auf 0 gesetzt,
also keine kollision obwohl man eine hätte.
Also stopp die schleife mit break sobald eine collision eintritt,
damit keiner den wert wieder überschreibt danach!


----------



## cleanerleon (9. Mrz 2015)

Genial, das ist es! 
Vielen Dank für die Hilfe 

Thema kann dann geschlossen werden.


----------

