2D Kollisionsberechnung schlägt fehl



  • Hallo an alle,

    kurze Beschreibung des Problems:
    Ich schreibe einen Server für ein Spiel (2D - Ansicht von Oben - Counter Strike 2D).
    Gegeben:
    - Die X und Y Koordinaten eines Spielers in Pixeln (1 Tile = 32 Pixel) (Player[id].x und Player[id].y).
    - Rotation in Grad von -180 bis +180. Dabei entspricht 0° oben.
    - Oben links ist der Punkt 0|0
    - Ein Array angegeben in Tiles (map[][]) ob man durch dieses durchschießen kann
    - Player[id].x + 16, da die Position nicht genau mit der Schussposition übereinstimmt.

    Nun der Code:

    int OnFire(int id, int writesocket)
    {
        int i;
        int range = 10*32;
        printf("Start\n");
        for(i = 2; i <= range; i++)
        {
            int newxpx;
            int newypx;
            float temprot = player[id].rotation;
    
            newxpx = player[id].x+16 + i*cos(temprot*PI/180);
            newypx = player[id].y+16 - i*sin(temprot*PI/180);
    
            int newx = (int)newxpx/32;
            int newy = (int)newypx/32;
            if(newx <= 0 || newy <= 0) break;
            int tilemode = map[newx][newy].mode;
            printf("(%d|%d) + %d*cos(%f)\n", player[id].x+16, player[id].y+16, i, temprot);
            if(tilemode == 1 || tilemode == 3 || tilemode == 4)
            {
                SendSpawnMessage(id, newxpx, newypx, writesocket); //Debug
                printf("(Debug) Wall hit (%d:%d|%d:%d) Rot: %f; XY (%d|%d); i %d.. Abort!\n", newx, newxpx, newy, newypx, temprot, player[id].x, player[id].y, i);
                break;
            }
            printf("DBG:%f\n", atan((player[id].y+16 - newypx) / (player[id].x+16 - newxpx)));
        }
        return 0;
    }
    

    Nun wird die Kollision korrekt berechnet, jedoch für die Falsche Richtung. Jeweils Oben und Rechts sowie Unten und Links sind vertauscht.

    Ich habe schon versucht, die Rotation in 0° - 360° anzugeben, hat jedoch keinen Erfolg gebracht. Genausowenig wie im Falle eines Negativen Cosinus (Oder Sinus?) *-1 anzuhängen.
    Da wir in Mathe leider noch nicht so weit sind, musste ich mir die Formeln selber erarbeiten. Deshalb tippe ich auch auf einen Fehler bei Sinus und Cosinus, denn dort erscheint mir der logische Fehler (ich hab alles mit dem Taschenrechner nachgerechnet - auch falsch) am wahscheinlichsten.
    Ich hoffe ihr könnt mir helfen. Vielen Dank für das Lesen!

    Gruß Jermuk



  • auch wenn ich dein koordinatengeschiebe nicht ganz verstehe weil ich zu wenig informationen kenne... versuchs doch mal mit

    sin (temprot +90)
    cos (temprot +90)

    verstehe deine sin/cos berechnung in zusammenhang mit deiner angabe eh ned so ganz, deine winkelangaben sind ja im vergleich zum einheitskreis lediglich um 90° verschoben...



  • likegliss schrieb:

    auch wenn ich dein koordinatengeschiebe nicht ganz verstehe weil ich zu wenig informationen kenne... versuchs doch mal mit

    sin (temprot +90)
    cos (temprot +90)

    verstehe deine sin/cos berechnung in zusammenhang mit deiner angabe eh ned so ganz, deine winkelangaben sind ja im vergleich zum einheitskreis lediglich um 90° verschoben...

    Vielen Dank für deine Antwort likegliss.
    Ich habe mal versucht das Programm zu vereinfachen und zu kommentieren.

    int OnFire(int id, int writesocket)
    {
        int i;
        int range = 10*32;
        printf("Start\n");
    
        int startx = player[id].x;
        int starty = player[id].y;
        float rotx;
        float roty;
        float temprot = player[id].rotation;
    
        if(temprot < 0)
        {
            temprot = 360 - (temprot *-1);
        }
    
        temprot += 90;
        if(temprot < 0)
        {
            temprot = 360-(360+temprot);
        }
    
        rotx = cos((temprot)*PI/180);//Streckenveränderung für den Einheitskreis (1 Pixel)
        roty = -sin((temprot)*PI/180);
    
        printf("(Debug) Temprot: %f\n", temprot);
    
        for(i = 0; i <= range; i++) //Für jedes Pixel
        {
            startx += rotx; 
            starty += roty;
    
            //Der Rest ist eigentlich unwichtig
    
            int tilex = (int)(startx)/32;
            int tiley = (int)(starty)/32;
    
            if(tilex <= 0 || tiley <= 0) break;
            int tilemode = map[tilex][tiley].mode;
            if(tilemode == 1 || tilemode == 3 || tilemode == 4)
            {
                SendSpawnMessage(id, startx, starty, writesocket);
                break;
            }
        }
        return 0;
    }
    

    Ergebnis:
    0° bis 180° : 0°
    180° bis 270° : 315°
    270° bis 0° : 270°

    Weiß jemand vielleicht Rat?

    EDIT:
    Die Ergebnisse wurden noch ohne +90 gerechet (hattem ich an das alte sytsem zu sehr gewöhnt) Hier sind die RIchtigen Ergebnisse:
    0° bis 90° : 225°
    90° bis 180° : 180°
    180° bis 270° : Nichts?
    270° bis 0° : 270°


Anmelden zum Antworten