# Problem mit Kollisionsabfrage



## baddestpoet (29. Apr 2010)

Hallo erstmal, dies ist mein erster Post hier. 

Ich versuche mich zur Zeit an einem Jump And Run und mache dabei auch ganz gute Fortschritte, allerdings bin ich jetzt auf ein Problem gestoßen. Und zwar habe ich eine Kollisionsabfrage geschrieben, mit der getestet wird, ob die Spielfigur von unten/oben/links/rechts gegen ein Objekt stößt. Klappt soweit schon ganz gut, das heißt wenn man gegen oder auf Objekte läuft/springt, wird die Spielfigur gestoppt.
Dummerweise klappt das bisher nicht für den Fall, dass man von einer Kante herunterläuft, die Figur fällt dann nich runter. Meine Idee ist, dass wann immer man kein Objekt unter sich hat (->nodown ist false) der Status auf falls gesetzt wird, man sich also im Fall befindet. Eigentlich müsste ich dazu ja in der Kollisionsabfrage nodown = false setzen wenn die Hit-Bedingung nicht erfüllt wird (das habe ich im Quelltext mal groß geschrieben), aber das führt dann immer dazu, dass die ganze Abfrage nicht mehr für den Fall funktioniert, dass der Spieler ein Objekt von oben trifft. Wenn ich diesen Teil rausnehme, geht halt alles außer der Fall von der Kante. Komischerweise fällt der Spieler auch korrekt bis zum Boden wenn ich ihn beim Programmstart in der Luft anfangen lasse...

Hat jemand ne Idee, was da noch nicht hinhaut, muss ich vielleicht nodown irgendwoanders auf false setzen?

Hier ist die Kollisionsmethode der Spielfigur:
(bx, by, bh und bw sind die Koordinaten und Dimensionen des Objektes)


```
public void collide(float bx, float by, float bw, float bh) {
        w=image.getWidth(null);
        h=image.getHeight(null);
        if( y+h>=by-1 && y+h<=by+7 && x<bx+bw && x+w>bx ) {// von oben
            nodown = true;
            hity = by - h;
        } ELSE 
            NODOWN = FALSE;
        if( y<by+bh && y>by+bh-3.5f && x+w>bx && x<bx+bw) //von unten
            noup = true;
        if( x+w>=bx && x+w<=bx+2.5f && y<=by+bh && y+h>=by ) //von links
            noright = true;
        if( x<=bx+bw && x>=bx+bw-2.5f && y<=by+bh && y+h>=by )//von rechts
            noleft = true;
    }
```

Und hier die Bewegunsmethode:


```
public void move() {
        if(!nodown && !jumps) { //Spieler bewegt sich von Objekt herunter
            falls = true;
        } 
        if (drin() && !moveScreen() && (!ducks || jumps || falls)) {
            if((noleft && pressr) || (noright && pressl) || (!noright && !noleft)) {
                x += dx;
                noright=false;
                noleft=false;
            }
        }
        if((jumps || falls)) { //Sprung
            jump();
        }
        y += dy;
    }
```


----------



## Quaxli (29. Apr 2010)

Es ist schwierig, hier genau etwas zu sagen, ohne den ganze Code oder Aufbaue zu kennen.
Aber:



baddestpoet hat gesagt.:


> ```
> public void collide(float bx, float by, float bw, float bh) {
> w=image.getWidth(null);
> h=image.getHeight(null);
> ...



Der Teil sieht ja schonmal relativ umständlich aus. Schon mal drüber nachgedacht, Deine Objekte von Rectangle bzw. Rectangle2D.Double erben zu lassen und die in der API bereitgestellten Methoden zu verwenden? Zum Beispiel intersects(..) und dann erst mal die aktuelle Bewegung grundsätzlich zu stoppen.
Das "Runterfallen oder nicht" würde ich dann losgelöst vom Rest betrachten. Hierfür würde es z. B. ausreichen, einen oder mehrere Punkte am unteren Rand der Spielfigur zu definieren und für die separat zu prüfen, ob sie in Kontak mit einem Objekt sind.


----------



## baddestpoet (29. Apr 2010)

Okay, danke schonmal. Das mit der Rectangle Klasse hört sich ziemlich gut an, das habe ich vorhin auch flüchtig in einem Tutorial von hier gelesen. Oh, ich seh grad, das war sogar von dir :toll:

Im Allgemeinen hab ich eine Klasse, die für den ganzen GameLoop und die Darstellung zuständig ist und dabei halt auch für alle sichtbaren Objekte (deren Eigenschaften vorerst noch in einem Array gespeichert sind) die collide Methode vom Helden aufruft. Im Grunde würde der erste Teil meiner Abfrage ja schon genau dem entsprechen, dass für den unteren Rand der Spielfigur getestet wird ob der obere Rand eines Objekts damit zusammentrifft.

Ich hatte es auch mal so gemacht, dass die collide Methode in den Objekten war und dem die Koordinaten vom Helden übergeben wurden aber das hat das Programm merkwürdigerweise langsamer gemacht. Ob meine Struktur so optimal ist, war mir auch nicht so recht klar.

Naja, ich werde mal versuchen das so umzuschreiben wie du's vorschlägst, das dauert bestimmt ein bisschen.


----------



## Antoras (30. Apr 2010)

Wenn du dich nach rechts bewegst macht es macht keinen Sinn zu prüfen ob auf der linken Seite eine Kollision stattgefunden hat. Das kann niemals true werden (es sei den es gibt mehrere Objekte, die sich einander nähern).

Berücksichtige das in deinen Abfragen, dann kannst du nämlich viel Rechenzeit sparen. Dein Problem würde ich so lösen, dass abgefragt wird ob ein Objekt keinen Boden mehr unter sich hat. Dann kannst du es nämlich fallen lassen. Sobald dann wieder ein Boden existiert wird die Fallbewegung wieder gestoppt.

Dazu ist es wohl am einfachsten wenn du in den KeyListenern Zustandsvariablen setzt, damit sie später in der Endlosschleife auf ihren Wert überprüft werden. Wenn also die rechte Pfeiltaste gedrückt wird, dann wird die Variable right auf true gestezt. In der Spielschleife wird dann abgefragt ob diese Variable true ist und wenn ja (und nur wenn ja), dann wird überprüft ob eine Kollision mit einem Objekt rechts vom zu bewegenden Objekt auftritt. Wenn nicht wird das Objekt bewegt.


----------



## baddestpoet (30. Apr 2010)

Antoras hat gesagt.:


> Dazu ist es wohl am einfachsten wenn du in den KeyListenern Zustandsvariablen setzt, damit sie später in der Endlosschleife auf ihren Wert überprüft werden. Wenn also die rechte Pfeiltaste gedrückt wird, dann wird die Variable right auf true gestezt. In der Spielschleife wird dann abgefragt ob diese Variable true ist und wenn ja (und nur wenn ja), dann wird überprüft ob eine Kollision mit einem Objekt rechts vom zu bewegenden Objekt auftritt. Wenn nicht wird das Objekt bewegt.



Das ist allerdings ne gute Idee, damit spar ich mir auf jeden Fall einigen Umstand im Vergleich zu meiner Version. Bei mir läufts quasi genau andersherum, falls eine Kollision auftritt wird zB noright auf true gesetzt und beim Bewegen wird jedesmal getestet ob sich der Held bewegen darf und das ist wirklich ziemlich umständlich.


----------



## baddestpoet (3. Mai 2010)

Okay, ich habs jetzt mit Rectangles umgeschrieben und die Kollisionserkennung klappt ziemlich gut, jetzt hätt ich nur noch eine Frage zur Optimierung des Ganzen.
Wie gehe ich am besten vor um abzufragen wo die Kollision aufgetreten ist, also oben, unten, links oder rechts? Ich würde jetzt die Koordinaten des kollidierten Blocks übergeben und mit denen vom Held vergleichen aber da wär ich ja wieder da wo ich mal angefangen hab ???:L


----------



## Quaxli (4. Mai 2010)

Hast Du die Anmerkung von Antoras ebenfalls umgesetzt? Das könnte Dir nämlich eine Menge Abfragen ersparen. 
Nachdem Du jetzt Rectangles einsetzt reduziert sich der Abgleich doch eigentlich erheblich? Um zu Wissen, ob ein Objekt von rechts oder links kollidiert ist, reicht es doch jetzt für das kolliderte Objekte die x-Werte zu Vergleichen und gut ist's?


----------



## baddestpoet (5. Mai 2010)

Ach, ja klar, hatte ich dabei jetzt völlig vergessen, danke 

Jetzt funktioniert die Abfrage schon recht gut, aber folgendes Problem hab ich dabei noch. Und zwar kommt es recht oft vor, dass die Spielfigur wegen ihrer Geschwindigkeit auch mal Pixel überspringt und deshalb einfach über den abgefragten Rand in ein Objekt hineinrennt oder springt. Ich hab versucht das zu kompensieren indem ich den Bereich etwas vergrößert hab und somit außer dem exakten Rand einer Box auch noch etwas Spielraum nach innen lasse.
Sieht aber zum einen etwas unschön aus, wenn man kurzzeitig die Figur in der Box sehen kann und sie dann wieder davor oder darauf gesetzt wird und zum anderen überschneiden sich diese Bereiche auch in den Ecken. Ich hab das hier mal versucht zu illustrieren:







Bin ich das jetzt wieder zu umständlich angegangen? Meine collide Methode sieht jetzt so aus, dass eben zuerst geprüft wird in welche Richtung sich der Held bewegt und je nachdem weiter ob er den Rand der Box übertreten hat. l und r lass ich nur mitzählen um nach der Abfrage mit mehreren Objekten noch zu wissen, was alles aufgetreten ist.
hx und hy sind die Koordinaten des Helden, hw und hh seine Breite und Höhe. bx, by, bw und bh analog dazu die Eigenschaften der Box mit der die Kollision auftrat.


```
if(hero.getJumps() && hx+hw>bx+11 && hx<bx+bw-11 && hy<=by+bh) {
        	hero.setJumps(false); //springt von unten gegen Objekt
        	hero.setFalling(true);
    	if(hero.getRight() && hy+hh>=by && hy<=by+bh && hx+hw>=bx && hx+hw<=bx+bw+15 {
        	l++; //von links gegen Objekt
    	}
    	if(hero.getLeft() && hy+hh>=by && hy<=by+bh && hx<=bx+bw && hx>bx+bw-15) {
        	r++; //von rechts gegen Objekt
    	}
    	if(hx+hw>bx+10 && hx<bx+bw-10 && hy+hh>by && hy+hh<by+bh-10) { //steht auf Objekt
    		hero.setHitGr(by-hh);
    	}
```


----------



## Antoras (5. Mai 2010)

Dein Problem tritt deshalb auf, weil du die Geschwindigkeit der Spielfigur nicht mit in die Rechnung einbeziehst. D.h. du musst prüfen ob die nächste Position der Spielfigur kollidiert und nicht die Momentane.


----------



## Steev (5. Mai 2010)

Wenn man es genau nimmt müssen sogar die Positionen geprüft werden, die zwischen der aktuellen und der nächsten Position liegen, da man sonst mit hoher Geschwindigkeit "durch Wände" (schmale Kollisionsobjekte) gehen kann, was nicht immer gewünscht ist. Oder man bleibt irgendwo stecken, wo man dann nicht mehr rauskommt.

Gruß
Steev


----------



## baddestpoet (5. Mai 2010)

Uff, wie geht man da denn ran? Da bei mir die collide Methode ja nur aufgerufen wird, wenn Intersect für eins der Objekte mit dem Helden true liefert, ist das ja immer schon zu spät:


```
for (Block box:boxes) {
        	if(hero.intersects(box))
        		collide(box);
        }
```

Ich würde jetzt spontan versuchen einen zweiten Helden anzulegen, dem ich vor jedem Intersect die zukünftigen Koordinaten des richtigen Helden gebe und die boxes darauf testen. Beim Collide dann gucken welche der Grenzen im Intervall [Koordinaten Held; Koordinaten Zweitheld] liegen, richtig?


----------



## Antoras (6. Mai 2010)

Du hast doch die Bewegungsgeschwindigkeit deines Helden. Du musst deinen Algorithmus eben nun so umschreiben, dass eine Kollision eben erst auftritt wenn die Position des Helden zusammen mit der Bewegung ein Objekt schneidet. Wenn der Abstand zwischen Held und Objekt kleiner ist als die Bewegungsgeschwindigkeit, dann wird eine Kollision auftreten, der Held kann dann also nur noch mit dem Abstand weiterbewegt werden und nicht mehr mit der Bewegungsgeschwindigkeit. Bei der nächsten Prüfung ist der Abstand dann null und der Held kann sich überhaupt nicht mehr weiterbewegen.

Im Grunde musst du die Kollisionsprüfung auch nur mit dem nächsten Objekt durchführen, alle anderen sind weiter entfernt und deswegen kann mit ihnen auch keine Kollision auftreten wenn beim nächsten keine Auftritt. Dabei musst du halt auf den Typ des Objekts achten; Hintergrundobjekte benötigen natürlich keine Kollisionsüberprüfung.


----------



## Quaxli (6. Mai 2010)

Ich habe den Eindruck, daß man das Problem etwas weniger aufwändig lösen könnte - zumindest aus rechnerischer Sicht. 
Die Bewegung der Spielfigur mit l++ oder r++ finde ich nicht optimal. Davon ausgehend, daß nicht jede Wiederholung Deiner Spielschleife gleich lange dauert, kann es sein, daß die Figur sich ungleichmäßig bewegt - vor allem wen die Sache komplexer wird und viele Objekte zu bewegen sind. Meiner Ansicht nach ist es besser, die Figur in Abhängigkeit der Zeit des Schleifendurchlaufs zu bewegen (guck' ins Tutorial  ). Wenn man dann noch ein bißchen darauf achtet, die FPS zu steigern, erhält man eine relativ feine Auflösung des Bewegungsablaufs und die Figur bewegt sich pro Runde des GameLoops nur um wenige Pixel, so daß kleinere Korrekturen nicht auffallen.

Des weiteren könntest Du mal gucken, ob Du das über den Ablauf Deines GameLoops lösen kannst.
Mal angenommen der sieht so aus:

1. Eingaben prüfen
2. Alles bewegen
3. Logiken abfragen
4. alles malen

Dann müßtest Du doch nur bei 3. abfragen, ob eine Kollision stattgefunden hat (in 2.) und das entsprechend korrigieren. Damit sieht der Anwender gar nicht, daß Deine Figur irgendwo zu weit rein gerannt ist. Wenn die Bewegung, wie oben beschrieben, noch relativ fein ist, fällt das nicht weiter auf.

Noch eine Frage zu Deinem Code. Was genau wird hier alles geprüft? Das sieht so aus, als könnte man das noch optimieren, aber ohne genaue Kenntnis, kann man da schlecht einen Tipp geben. 

```
if(hero.getLeft() && hy+hh>=by && hy<=by+bh && hx<=bx+bw && hx>bx+bw-15) {
            r++; //von rechts gegen Objekt
        }
```


----------



## Steev (6. Mai 2010)

Am schnellsten bzw. am wenigsten rechenaufwendig würde es warscheinlich sein, wenn man mithilfe einer linearen Gleichung einen oder mehrere Strahlen von der aktuellen Spielerposition bis zur nächsten Position ausgesendet werden. Diese Strahlen müssen dann auf Überschneidung mit den Kollisionsobjekten geprüft werden.


----------



## baddestpoet (6. Mai 2010)

@Antoras: Hintergründe hab ich ausgeschlossen, die haben ne extra Klasse. Ich brauch doch zur Intersects Abfrage ein Rectangle oder nicht? Dazu meinte ich ja, dass ich einen unsichtbaren DummyHelden erzeuge, der immer die doppelte Geschwindigkeit hat wie der eigentliche Held (also bewegt der sich immer ein Stück weiter vorne) und für den die Intersects Abfrage durchführe!? hab ich schon versucht umzusetzen aber das Ergebnis ist weniger zufriedenstellend als ohne den Dummy.

@Quaxli: ich hab's zeitabhängig gemacht, l und r dienen in meiner Kollisionsmethode nur dazu festzuhalten wo die Kollision nun auftrat, das hab ich jetzt zum Boolean geändert.

Mein GameLoop sieht von der Struktur her so aus, wie du meintest: 

```
public void run() {

        while(game_running) {

            computeDelta(); //berechnet Dauer des letzten Durchlaufs

            hero.checkKeys(); //Tastatureingabe
            doLogic(); //Abfragen und so
            moveObjects(); //berechnet Koordinaten

            repaint(); //aktualisiert Screen

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

In doLogic steckt die Intersects Abfrage, die für den Kollisionsfall dann die collide Methode aufruft. Sollte also so funktionieren, dass man die Bewegung ins Objekt nicht sieht. Was die genaue Abfrage angeht:

```
if(hero.getLeft() //Held will sich nach links bewegen
&& hy+hh>=by //HeldY + Heldhöhe >= BoxY (d.h. Unterkante des Helden liegt unter Oberkante der Box)
&& hy<=by+bh // HeldY <= BoxY+Boxhöhe (d.h. Oberkante des Helden liegt über Unterkante der Box)
&& hx<=bx+bw //HeldX <= BoxX+Boxbreite (d.h. linke Kante des Helden liegt vor der rechten Kante der Box)
&& hx>bx+bw-15) //HeldX > BoxX+Boxbreite-15 (d.h. linke Kante des Helden kann noch bis zu 15 Bildpunkten in der Box liegen)
{...}
```

@Steev: Das hört sich interessant an, aber da müsste man sich ja erstmal richtig gut überlegen, wo man die Strahlen ansetzt. Ich glaube da kommt man nicht drumherum für jede Ecke des Bildes einen Strahl auf deren nächste Position zu setzen, weil sonst viele Kollisionsfälle gar nicht erkannt werden würden. Das hier ginge ja zum Beispiel einfach unter, wenn man den Strahl nur in die Mitte setzen würde:






Gtibs denn sowas wie eine "Strahlen"-Klasse, mit der man ein Intersects mit einem Rectangle durchführen kann?


----------



## Quaxli (6. Mai 2010)

baddestpoet hat gesagt.:


> ```
> if(hero.getLeft() //Held will sich nach links bewegen
> && hy+hh>=by //HeldY + Heldhöhe >= BoxY (d.h. Unterkante des Helden liegt unter Oberkante der Box)
> && hy<=by+bh // HeldY <= BoxY+Boxhöhe (d.h. Oberkante des Helden liegt über Unterkante der Box)
> ...


Ein paar Anmerkungen:

1. Dein Held erbt doch mittlerweile von Rectangle oder? Dann verstehe ich nicht warum Du immer noch mit hy + hh arbeitest. Das sollte doch durch hero.getY() und hero.getHeight() zu erschlagen und eindeutiger sein?

2. Gleiches gilt für die Box.

3. Zu diesem Code-Fragment: ...&& hx>bx+bw-15)  Das sieht so aus als würdest Du damit versuchen transparente Kollisionen über einen Pauschalwert abzufangen? Wenn das so ist, wird das nicht auf Dauer gut gehen bzw. gut aussehen.

4. Solltest Du die Logiken grundsätzlich überdenken. Mit so einem Konstrukt wie oben, machst Du Dir das Leben ganz schnell schwer, wenn Du irgendwann später feststellst, daß die Figur nicht so reagiert, wie Du willst.

5. Wenn beide Objekte von Rectangle erben, kannst Du mit der intersects-Methode erstmal prüfen, ob überhaupt eine Kollision stattfindet. Wenn nein brauchst Du alle anderen Bedingungen gar nicht. Die Position würde ich erst prüfen, wenn wirklich eine Kollision da ist.

6. Steht alles im Tutorial, lies das endlich mal .


----------



## Landei (6. Mai 2010)

Eh du weiter im Nebel rumstocherst, such doch mal ein ordendliches Game-Tutorial, das sollte das behandeln. Neben dem von Quaxli gibt es z.B. Killer Game Programming online, und Kollisionsabfragen sollten da in Kapitel 11 (Sprites) oder 12 (Side Scroller) behandelt werden (hab's jetzt aber nicht nachgeschlagen).


----------



## baddestpoet (6. Mai 2010)

Quaxli hat gesagt.:


> Ein paar Anmerkungen:
> 1. [...] 6.



Hab ich doch alles so schon drin!? Kann sein, dass das durch meine geposteten Fragmente jetzt nicht so rüberkam aber Hx und Hy und das alles übernehm ich von hero.getY() und hero.getHeight() das mach ich nur, damit's wenigstens ein bißchen übersichtlich bleibt und nicht überall nur noch hero.getDings() steht. Aus deinem Tutorial hab ich das meiste erst alles, sonst würde mein Programm sicher gar nicht laufen. Kannst mir schon glauben, dass ich das gelesen hab  Mein eigentliches Problem ist ja eben nicht die Kollision zu erkennen, sondern korrekt auszulesen wo die auftritt, das funktioniert vielleicht für 85% der Fälle korrekt.
Ich weiß, dass das eure Geduld mittlerweile vielleicht etwas strapaziert aber ich hab erst ein jahr Erfahrung mit Java an der Uni und wir sind eigentlich noch nicht einmal bei grafischen Oberflächen angekommen. In nem Jahr lach ich vielleicht auch über das Problem hier aber noch ists eben nicht soweit. :rtfm:

Ich mach's mal ausführlicher. Meine GamePanel Klasse:


```
public class GamePanel extends JPanel implements Runnable, KeyListener {
 [...] //Variablen und dies und das

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

    public GamePanel (int w, int h) {
        [...]
        doInitializations();
    }

    private void doInitializations() {
       [...] //initialisiert Hintergründe und Sprites
    }

    //GAMELOOP
    public void run() {
        while(game_running) {
            computeDelta(); //berechnet Dauer des letzten Durchlaufs
            hero.checkKeys(); //Tastatureingabe
            moveObjects(); //berechnet Koordinaten
            doLogic(); //Abfragen und so
            repaint(); //aktualisiert Screen
            try {
                Thread.sleep(15);
            } catch (InterruptedException e) {}
        }
    }

    private void computeDelta() {...}

    private void doLogic() {
    	l=false;
    	r=false;

        for (Block blo:boxes) {
        	if(hero.intersects(blo))
        		collide(blo);
        	hero.setHitL(l);
        	hero.setHitR(r);
        }
        if(heroo.getX()<=500 || hero.getX()>=800) {

            for (Background b:backs) { //bewegt alle Hintergründe
            	b.Position(delta, hero.getDx());
            }

            for (Block b:boxes) { //bewegt alle Blöcke
            	b.Position(delta, hero.getDx());
            }
        }
    }

    private void moveObjects() {
        for(Movable mov:actors) {
            mov.move(delta);
        }
        for(Movable mov:actors) { 
            mov.doLogic(delta);
        }
        for(Movable mov:boxes) {
            mov.doLogic(delta);
        }
    }

   public void collide(Block b) {
    	hx = hero.getX();
    	hy = hero.getY();
    	hw = hero.getWidth();
    	hh = hero.getHeight();
    	bx = b.getX();
    	by = b.getY();
    	bw = b.getWidth();
    	bh = b.getHeight();
    	if(hero.getJumps() && hx+hw>bx+11 && hx<bx+bw-11 && hy<=by+bh) {
        	hero.setJumps(false); //springt von unten gegen Objekt
        	hero.setFalling(true);
        	hero.setJx(0);
        	hero.setY(by+bh);
    		b.setLoop(1,1);
    	} else
    		b.setLoop(0,0);
    	if(hero.getRight() && hy+hh>=by && hy<=by+bh && hx+hw>=bx && hx+hw<=bx+15 ) {
        	l=true; //von links gegen Objekt
    	}
    	if(hero.getLeft() && hy+hh>=by && hy<=by+bh && hx<=bx+bw && hx>bx+bw-15) {
        	r=true; //von rechts gegen Objekt
    	}
    	if(hy<by && hy+hh>by && hx+hw>bx+15 && hx<bx+bw-15) {
    		hero.setHitGr(by-hh);
    	}
    }

    public void paintComponent (Graphics g) {...}
    private BufferedImage[] loadPics(String path, int pics) {...}
    private void createBack() {...}
    und die KeyListener Methoden
```

Meine Hero Klasse:


```
public class Hero extends Sprite{ //Sprite erbt von Rectangle

   [...]Variablendeklarationen

    public Hero(BufferedImage[] i, double x, double y, long delay, GamePanel p) {
        super(i,x,y,delay,p); //übernimmt Konstruktor von Sprite
    }

    public void doLogic(long delta) {
        super.doLogic(delta);

        if(getX()<500) //checkt ob Held den zulässigen Bereich verlässt
            setX(500); //um die Hintergründe entsprechend mitzuscrollen
        if(getX()>800)
            setX(800);
        if(getY()<0) {
            setDy(0);
            setY(0);
        }
    }

    public void move(long delta) {
    	if((hitl==false || dx<0) && (hitr==false || dx>0)) {
    		x += dx*(delta/1e9); //bewegt abhängig davon wie lange die letzte
    	}
		y -= dy*(delta/1e9); //Aktualisierung zurücklag
    }

    public void checkKeys() { //Laufen und Sprinten
        if(left && !right) { //nach links
            setDx(-250);
            blickl = true;
            if(szene!="walkl") {
            	setLoop(0,3);
            	szene = "walkl";
            }
        }

        if(right && !left) { //nach rechts
            setDx(250);
            blickl = false;
            if(szene!="walkr") {
            	setLoop(10,13);
            	szene = "walkr";
            }
        }

        if(up) { //Sprint
        	if(dx>0) {
        		dx=375;
        		if(szene!="runr") {
        			setLoop(15,17);
        			szene="runr";
        		}
        	}
        	if(dx<0) {
        		dx=-375;
        		if(szene!="runl") {
        			setLoop(5,7);
        			szene="runl";
        		}
        	}
        }

        if((jumps || falling)) { //SPRUNG
            if(dx>0) {
                if(!up) {
                	setLoop(14,14);
                    dx=375;
                } else {
                	setLoop(18,18);
                    dx=425;
                }
            }
            if(dx<0) {
                if(!up) {
                    dx=-375f;
                    setLoop(4,4);
                } else {
                    dx=-425;
                    setLoop(8,8);
                }
            }
            if(jumps && jx>0) { //ABSPRUNG
                setDy(70*jx);
                jx-=0.3f;
                hitsground=712;
            }
        }
        if((jumps && jx<=0)){ //MAXIMUM
            jumps = false;
            falling = true;
        }
        if(falling) { //FALL
        	setDy(-85*jx);
            jx+=0.3f;
        }
        if ((falling && y>=hitsground)) { //LANDUNG
            falling = false;
            y=hitsground;
            setDy(0);
            if(up) {
            	if(dx<0)
            		setLoop(5,7);
            	if(dx>0)
            		setLoop(15,17);
            } else{
            	if(dx<0)
                	setLoop(0,3);
            	if(dx>0)
                	setLoop(10,13);          	
            }
            if(down) {
            	if(blickl)
            		setLoop(9,9);
            	else
            		setLoop(19,19);
            }
        }

        if(!left&&!right) { //stehen bleiben
            setDx(0);
            if(!down) {
                if (blickl)
                    setLoop(0,0);
                else
                    setLoop(10,10);
            }
        }

        if(down && !jumps && !falling) { //ducken
        	setDx(0);
        		if(blickl)
        			setLoop(9,9);
        		else
        			setLoop(19,19);
        }
    }

   [...] Getter und Setter Methoden
```

Ansonsten hab ich hier mal die exportierte Jar Datei hochgeladen, kann aber gut sein, dass es nicht ausführbar ist: http://birdvscage.net23.net/game.jar

@Landei: Danke, ich gucks mir mal an.


----------



## baddestpoet (7. Mai 2010)

Okay, Kollision funktioniert jetzt auch ohne Vorhersage ganz ordentlich, ich hab einfach außer Acht gelassen, dass der x-Wert der Kisten sich durchs Scrolling auch verändert  Die Frage des Falls wenn man von einer Kante läuft hab ich nach 3 Stunden Suche jetzt auch gelöst.
Vielen Dank für eure Hilfe!


----------

