Kollisionsdetektion in einem Labyrinth



  • Hallo Forum,
    ich habe aus einer Matrix, z. B. 5x5, gefüllt mit 0 und 1 ein Labyrinth gebaut.
    Eine 0 repräsentiert dabei eine normale Bodenfläche mit Decke und eine 1 ist ein
    würfelförmiger Klotz, der eine 4 Wandteile darstellt.

    1 1 1 1 1
    1 0 0 0 1
    1 0 1 0 1
    1 0 0 0 1
    1 1 1 1 1
    

    In dem obigen Beispiel kann man in einem kreisförmigen Gang gehen.
    Wird die Kamera nun bewegt, rechne ich die Werte von der aktuellen zur
    nächsten gewünschten Position aus und übergebe sie der Kollisions-Über-
    prüfung. Darf die Kamera dort nicht hin bewegt werden, setze ich die Werte
    dort auf 0. Siehe Codebeispiel:

    struct {
        // Anzahl der Matrixelemente in der Breite
        // Für obige Matrix: 5
        unsigned char Width;
        // ...
    } Level;
    
    struct {
        float XPosition;
        float YPosition;
        float ZPosition;
        // ...
        // Aktueller Index der Matrix, auf dem die Kamera
        // steht. 0 ist oben links und 24 (obiges Bsp.) ist
        // unten rechts.
        unsigned short ActualMatrixIndex;
    } User;
    
    // Prüft ob die anvisierte Position in einer Wand liegt oder
    // auf einer erlaubten Fläche.
    void DetectCollision(float *MyDeltaX, float *MyDeltaZ){
        // Auf X-Kollision mit den Wänden prüfen und ...
        if(Level.Matrix[((int)User.ZPosition * Level.Width) + (int)(User.XPosition + (*MyDeltaX * 10))] != 0){
            // ... bei Kollision die X-Komponente auf 0 setzen
            *MyDeltaX = 0;
        }
    
        // Auf Z-Kollision mit den Wänden prüfen und ...
        if(Level.Matrix[((int)(User.ZPosition + (*MyDeltaZ * 10)) * Level.Width) + (int)User.XPosition] != 0){
            // ... bei Kollision die X-Komponente auf 0 setzen
            *MyDeltaZ = 0;
        }
    }
    

    Ich frage die neue X- und Z-Position einzeln ab, damit der Benutzer auch an
    einer Wand, auf die er fast frontal stösst, durch geradeaus-gehen, seitlich
    entlang gehen kann.
    Die Multiplikation mit 10 mache ich, weil ich nicht direkt den vom Benutzer
    gewünschten Punkt prüfen möchte, sondern den Punkt in einer 10-fachen
    Verlängerung. Sonst käme die Kamera so nah an die Wände heran, dass die durchblickt.

    Das klappt so weit ganz gut. Es gibt nur eine Ausnahme. Renne ich gegen eine
    Wand und bin nicht 100%-ig nach Norden ausgerichtet, laufe ich mit dem Gesicht
    zur Wand an dieser entlang, bis ich an eine Ecke komme. Geht die Wand nach
    hinten weg, renne ich gerade aus weiter. Leider bin ich dann so nah an der
    Wand, die nun neben mir ist, dass die Kamera teilweise hinter diese Wand blicken
    lässt.

    Wand |
    _____|^
        ^
    

    Meine Frage:
    Gibt es vielleicht schon einen Algorithmus für dieses einfache Szenario?
    Wenn nicht, kann mir jemand einen Tip geben, wie ich eine solche Berechnung
    durchführen kann?

    Vielen Dank, Titus



  • hmm.. ich würde einfach rundum im Abstand von 10 Punkten nichts mehr an mich heran lassen. So, dass nicht 4, sondern 8 Punkte um den Spieler herum nach wänden überprüft werden.

    *
     *        *
    
    *     O     * 
    
     *        *
          *
    

    sowie eine wand einen dieser 8 Punkte berührt ist diese Richtung gestrichen. d.h.
    ist im Norden(relativ zum Spieler) eine Wand, kann er dort nicht weiter, im Nordosten kann er weder nach Noren, noch nach Osten, bzw. nur an der Wand lang.

    Auf der anderen Seite setz doch einfah das Ganze auf 12 Punkte Abstand hoch..

    ach so. Ich würde der Einfachheit halber eine Änderung vornehmen:
    Nenne Dein DeltaZ deltaY. Du solltest davon ausgehen, dass der Spieler sich auf einer 2D-Map bewegt und die definierten Richtungen im 2D-Raum sind X und y. Die tiefe (Z) im ganzen ist eigentlich nur ein virtueller Trick. Das macht das Programm dann nicht ganz o verwirrsam für andere..

    [ Dieser Beitrag wurde am 14.01.2003 um 11:41 Uhr von DocJunioR editiert. ]



  • Danke, ich werde es mal so probieren.


Anmelden zum Antworten