# Problem mit Kollisionsabfrage beim Fallen Jump & Run



## Neew (3. Apr 2012)

Hallo, 
ich programmiere gerade als Schulprojekt ein Jump&Run in Java und komme dabei auch ganz gut vorwärts, allerdings beiße ich mir im Moment die Zähne dabei aus, meine Figur einfach fallen zu lassen, wenn sie keinen Boden unter den Füßen hat.

Ich benutzte die Intersects(o)-Methode wie im Tutorial von Quaxli (einfache Kollision S.64).

Mein Gedanke war, immer wie folgt zu prüfen:

```
if(this.intersects(o){
...
}
else if(!this.intersects(o)&&dy==0){
y+=0.5;
}
```

Also wenn er keine Überschneidung hat und er nicht springt, erhöht sich der Y-Wert bis er den Boden berührt. Danach sollte er nicht mehr in die Abfrage kommen und meine Figur ist am Boden. So die Theorie. In der Praxis geht er aber immer in diese Abfrage und sorgt so dafür, dass man nicht mehr springen kann oder man fällt sofort durch den Boden.

Hier noch der ganze Codeabschnitt, fürs Springen und Fallen. War es evtl. nicht ganz so schlau das so mit der move Methode zu mischen?

```
public class Spieler extends Objekt {
	
	boolean ok=true;
	boolean ersterdurchlauf=true;
	double yalt;

[...Andere Methoden etc...]

public void move(long zeit_letzte_schleife){
		
		if (dx!=0){ //Wenn Tempo nicht 0
			x+=dx*(zeit_letzte_schleife/1e9); //ändere Position 
		}
		
		if(dy!=0){ //Wenn Tempo nicht 0
			if(ersterdurchlauf){ //Speichere Absprungs Höhe
			yalt=getY();
			ersterdurchlauf=false;}
		if (ok){ //Sprunglogik
			y+=-0.8;
			System.out.println("Hoch "+y);}
		if(y<=yalt-60){
			ok=false;
			System.out.println("Oben angekommen "+y);
			GamePanel.hoch=false;
			GamePanel.runter=true;}
		if(!ok){
			y+=0.8;
			System.out.println("Runter "+y);
			}
		}
		
		if(y>=400){//Verloren wenn Figur zu weit unten
			GamePanel.setGameStarted(false);
		}
		
		}

	@Override
	public boolean kollision(Objekt o) {
		if(this.intersects(o)){
		
		System.out.println("intersect");
		ok=true;
		ersterdurchlauf=true;
		GamePanel.blocked=false; //ja nicht sehr edel aber es soll erstmal funktionieren ;)
		GamePanel.runter=false; //      -"-
		return false;
		}else{			
			if(!this.intersects(o)&&dy==0){ 
			System.out.println("bin drin");
			y+=0.5;
			return false;
			}
			}
		return false;
	}
```

Ich wäre für einen Denkanstoß sehr dankbar und sei es auch nur die Info, weshalb das so überhaupt nicht funktionieren kann . 
Ich komme jetzt seit 2 Tagen nicht mehr weiter und ich wette die Lösung ist so simpel..

Spiel, ohne "Fallen Abfrage"(Wer es testen will, muss nur den Code in der Klasse Spieler einfügen)


----------



## Fu3L (3. Apr 2012)

Ich würde tatsächlich nicht so viel mischen. Was ist denn, wenn du kollision auch für die Gegner verwenden willst? Dann fällst du ständig durch den Boden^^ (Im übrigen ist !this.intersects am Anfang vom else doppelt gemoppelt  Außerdem sollten Methodennamen tuWörter D) sein) 

Ansonsten könnten diese ganzen Variablen (müssen die unbedingt statisch sein? (Suggestivfrage^^ )) sonst was bewirken oder aber oben genanntes Negativbeispiel ist sogar der Fall oder der Boden hat eine falsche Shape, da kann so ziemlich alles schuld sein^^


----------



## Neew (3. Apr 2012)

Danke erstmal für die schnelle Antwort!

Wenn ich das richtig verstehe, kann ich meinen ganzen Ansatz noch einmal überarbeiten? 

Das mit dem else und !this.intersects(o) habe ich extra so gemacht, da es mich so aufgeregt hat, dass die Figur trotz intersect (in der Konsolo wird "intersect" ausgegeben) die else Bedingung danach auch ausführt und dadurch meine Sielfigur durch den Boden fällt..


----------



## Neew (3. Apr 2012)

So, wollte nur sagen, dass ich das Problem lösen konnte und da das für alle interessant sein kann, die Quaxlis Vorlage nutzen und genauso blöd sind wie ich, hier die Lösung:

Mein Gedanke war: Wenn die Spielfigur in der Luft steht gibt es kein intersect, also kann ich dann so lange die y-Position anpassen, bis intersect=true. Also das:

```
if(this.intersects(o){
...
}
else if(!this.intersects(o)){
y+=0.5;
}
```



Benutzt man nun nur die einfache Kollisionsabfrage, wird bei !this.intersect() auf ALLE Objekte geprüft die es gibt, bei 20 Objekten z.b.  wird 1 mal das Objekt auf dem die Spielfigur sich befindet und 19x die Objekte auf denen sich die Spielfigur nicht befindet geprüft.

Steht man nun auf einem Objekt, wird trotzdem 19x die Anweisung ausgefürt, da man 19 Objekte nicht berührt. Folge: Man fällt durch den Boden.

Ein einfaches Workaround wäre folgendes:

```
int count=0;
if(this.intersects(o){
count=0;
}
else if(!this.intersects(o)&&dy==0){
count++;
if(count>19){
y+=0.5;
}
}
```


----------



## Fu3L (3. Apr 2012)

(Tschuldige, netter gehts nicht^^)

Du weißt doch wohl, welches Objekt "der" Boden ist und prüfst dann nur den Boden, um dann zu testen, ob die Figur fällt. Was machst du denn, wenn ein Objekt auf mal in der Reihenfolge davor ist?^^


----------



## Neew (6. Apr 2012)

Um ehrlich zu sein:
ich habe das alles sehr unschön gelöst ^^

Ich weiß nicht, welches Objekt "der" Boden ist. Ich prüfe einfach immer auf alle Objekte die ich habe und wenn ich auch nur eins davon berühre, weiß ich, dass ich stehe. Das macht natürlich vieles komplexer und steigert auch den Rechenaufwand aber ich wusste mir einfach nicht anders zu helfen 

Wenn ich nur auf "den" Boden prüfen würde, müsste ich ja in irgend einer Form die x und y Positionen meiner Spielfigur und des "Boden-Objektes" vergleichen aber wie genau das geht weiß ich bis jetzt nicht. Ich versuch das alles mit Learning by Doing oder Trying 

Normal mach ich immer alles so, dass es geht, bis es zu Problemen kommt. Dann überdenke ich meinen Ansatz, Mach es anders bis wieder ein Problem auftritt usw. Das geht immer im Kreis und am Ende kommt auch meist was Gutes dabei raus. Braucht zwar länger aber ich mekrs mir dann besser


----------

