# LWJGL - Kollisions-Bug (Fallen)



## Androbin (7. Dez 2014)

Hallo Leute,
ich habe ein Problem mit der Kollisions-Erkennung beim Fallen in LWJGL!

Vorwort:
Ich habe vor kurzem angefangen, eine Art Minecraft/Cubeworld-Klon zu erschaffen.
Der sieht soweit eigentlich schon ganz gut aus, bis auf einen kleinen Fehler:

Aufgabe:
Die Kollisions-Erkennung in X-/Z-Richtung funktioniert bereits, nicht aber in Y-Richtung:
Mein Character soll eine Größe von 2 (LWJGL-Einheiten) haben, dementsprechend muss ich
bei der Kollision im Fallen den Voxel (Block) 2 Einheiten unter dem Kopf (Kamera) abprüfen.

Problem:
Mein Character hält stets 1 Voxel (Block) über dem Boden an.

zuständiger Code:

```
...

float old_y = y;

y += speedY /*      */ * delta * 10;
speedY -= Constants.GRAVITY * delta * 10;

if ( y - 2 < 0 || world[ (int) x ][ (int) y - 2 ][ (int) z ] != null ) {
    y = old_y;
    canJump = true;
}

...
```

Weiß da eventuell jemand von euch Rat?

PS. Der Code des Spiels auf dem momentanen Stand ist im Anhang hinterlegt.


----------



## Ruzmanz (7. Dez 2014)

Was soll man da (er)raten? Nimmst anstatt der Zwei eine Eins und es funktioniert wahrscheinlich. Warum das funktioniert solltest du wissen, da das dein Programm ist :bahnhof:


```
if ( y - 1 < 0 || world[ (int) x ][ (int) y - 1 ][ (int) z ] != null ) {
y = old_y;
canJump = true;
}
```


----------



## Androbin (7. Dez 2014)

Ruzmanz hat gesagt.:


> Was soll man da (er)raten? Nimmst anstatt der Zwei eine Eins und es funktioniert wahrscheinlich. Warum das funktioniert solltest du wissen, da das dein Programm ist :bahnhof:
> 
> 
> ```
> ...


Möchte man meinen, oder?
Nur leider funktioniert es nicht!

PS. Glaubst du wirklich ich wäre so blöd, das nicht auszuprobieren?


----------



## Ruzmanz (7. Dez 2014)

Um ehrlich zu sein? Ja. Sonst hättest du geschrieben, was dann passiert.


----------



## Androbin (7. Dez 2014)

EDIT:
Hab's nochmal getestet:
Man hält immer auf der Höhe an,
auf der man losgesprungen ist.
(Mit besagter Umstellung)


----------



## Ruzmanz (7. Dez 2014)

Gehen wir von deinem speziellen Fall aus, dann muss es einen Boden geben!


```
if (world[ (int) x ][ (int) y - 2][ (int) z ] != null) {
    y = old_y;
    canJump = true;
}
```

PS: Was passiert bei "y-3?
PS2: Und wenn der weiterhin an der selben Stelle landet würde ich einfachmal das if-Statement entfernen. Vielleicht bewirkt die auch gar nichts.


----------



## Androbin (7. Dez 2014)

Ruzmanz hat gesagt.:


> Gehen wir von deinem speziellen Fall aus, dann muss es einen Boden geben!
> 
> 
> ```
> ...


1. Einen Boden gibt es + zufällig in der Landschaft verteilte Voxel (Blöcke)
2. Bei "y - 3" kann ich überhaupt nicht mehr springen
3. Natürlich bewirkt das was, sonst würde ich ja durch den Boden krachen


----------



## Androbin (8. Dez 2014)

Ich habe die Abarbeitung der Physik (etwas) abgeändert:

```
/* Physik */ {
    
    /* Springen & Fallen */ {
        
        /**/ y += speedY  * delta * 10f;
        speedY -= GRAVITY * delta * 10f;
        
    }
    
    /* Kollision */ {
        
        /*   */ if ( world[ (int) x ][ (int)   old_y /*                  */ ][ (int) old_z ] != null ||
                /**/ world[ (int) x ][ (int) ( old_y + 0.5f * PLAYER_SIZE ) ][ (int) old_z ] != null ||
                /**/ world[ (int) x ][ (int) ( old_y + /*  */ PLAYER_SIZE ) ][ (int) old_z ] != null )
            /*    */ x = old_x;
        
        /**/ if ( y < 0f || y > WORLD_HEIGHT - 1f ||
                /**/ world[ (int) old_x ][ (int)   y /*                  */ ][ (int) old_z ] != null ||
                /**/ world[ (int) old_x ][ (int) ( y + 0.5f * PLAYER_SIZE ) ][ (int) old_z ] != null ||
                /**/ world[ (int) old_x ][ (int) ( y + /*  */ PLAYER_SIZE ) ][ (int) old_z ] != null )
        /*   */ { y = old_y; canJump = true; }
        
        /*   */ if ( world[ (int) old_x ][ (int)   old_y /*                  */ ][ (int) z ] != null ||
                /**/ world[ (int) old_x ][ (int) ( old_y + 0.5f * PLAYER_SIZE ) ][ (int) z ] != null ||
                /**/ world[ (int) old_x ][ (int) ( old_y + /*  */ PLAYER_SIZE ) ][ (int) z ] != null )
            /*    */ z = old_z;
        
    }
    
    /* Weltabgrenzung */ {
        
        if ( x - 0.5f < 1 ) x = 1.5f;
        else if ( x + 0.5f > WORLD_WIDTH - 1 )
            x = WORLD_WIDTH - 1.5f;
        
        if ( y < 1f ) { y = 1f; canJump = true; }
        else if ( y + PLAYER_SIZE > WORLD_HEIGHT - 1f )
            y = WORLD_HEIGHT - 1f - PLAYER_SIZE;
        
        if ( z - 0.5f < 1f ) z = 1.5f;
        else if ( z + 0.5f > WORLD_WIDTH - 1f )
            z = WORLD_WIDTH - 1.5f;
        
    }
    
}
```
Nur leider ohne Erfolg! Hat denn wirklich keiner von euch eine brauchbare Idee, wieso ich immer in Absprungs-Höhe hängen bleibe?


----------



## Ruzmanz (8. Dez 2014)

Implementiere es halt nochmal. Schritt für Schritt. Wie schnell fällst du eigentlich? Nicht, dass dein deltaY so groß ist, dass du nie auf den Boden fallen kannst ...

if(collision auf Y-Achse) {
   // anstatt y = old_y;
   y = Spieler.getY()+1.999d
}


----------



## Androbin (8. Dez 2014)

Ruzmanz hat gesagt.:


> Implementiere es halt nochmal. Schritt für Schritt. Wie schnell fällst du eigentlich? Nicht, dass dein deltaY so groß ist, dass du nie auf den Boden fallen kannst ...
> 
> if(collision auf Y-Achse) {
> // anstatt y = old_y;
> ...


Was ist der Sinn hinter "y = Spieler.getY()+1.999d" ?


----------



## Ruzmanz (8. Dez 2014)

Ziel ist es dich so nah wie möglich an den Boden zu setzen, sodass keine "Lücke" entsteht.


----------



## Androbin (8. Dez 2014)

Ruzmanz hat gesagt.:


> Ziel ist es dich so nah wie möglich an den Boden zu setzen, sodass keine "Lücke" entsteht.


1. Erklärt das noch immer nicht, WIESO es so nicht funktioniert
2. Zu deinem Vorschlag:
2.1 Kann es ja nach wie vor sein, dass ich in einen Block krache, wenn ich es so mache, wie du
2.2 Könnte ich mich denn nicht GLEICH 2 Blöcke nach unten schieben (anstatt 1.999)? Was ist denn da der Hintergedanke?


----------



## lord239123 (9. Dez 2014)

Kann es evtl sein, dass die Position des Spielers sich an dessen Füßen befindet?
Dann müsstest du statt y-2 einfach y verwenden.


----------



## Androbin (9. Dez 2014)

lord239123 hat gesagt.:


> Kann es evtl sein, dass die Position des Spielers sich an dessen Füßen befindet?
> Dann müsstest du statt y-2 einfach y verwenden.


Ursprünglich nicht, nein; allerdings habe ich das so abgeändert!


----------



## Androbin (9. Dez 2014)

PROBLEM GELÖST !!!
Ich hatte schlichtweg vergessen, bei einer Kollision speedY = 0 zu setzen 

PS. Wo ist denn eigentlich der "Thema schließen"-Button geblieben?


----------

