Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Jak zrobić funkcje ślizgającą postać po przeszkodzie SDL2

Ostatnio zmodyfikowano 2019-10-06 17:08
Autor Wiadomość
morfik
Temat założony przez niniejszego użytkownika
Jak zrobić funkcje ślizgającą postać po przeszkodzie SDL2
» 2019-10-06 12:34:55
Jak zrobić funkcje ślizgającą postać po przeszkodzie SDL2

Robię grę, gdzie są strzelające do siebie i potworków pojazdy. Jest to gra 2d a logika przeszkód to linie proste wokół wielokątów oraz okręgi dla postaci.
Zrobiłem tak aby pojazdy i w przyszłości potworki nie przesuwały się po przeszkodach. Ale teraz jak wjadę na przeszkodę to muszę wykręcić,
żeby jechać dalej. Więc zrobiłem taką funkcje która ma zwracać kąt kierunku po którym pojazd ma się ślizgać. Oczywiście kąt rysowania jest inny.
Funkcja działa nieprawidłowo ponieważ pojazd owszem ślizga się ale w złym kierunku, najczęściej zawsze w tym samym.
wstawiam kod funkcji (nie widzę tu opcji wstawiania kodu w edycji nowego tematu):
C/C++
double slizg( double a, punkt p1, punkt p2 ) //przyjmuje kąt pojazdu i dwa punkty wyznaczające linię przeszkody, zwraca nowy kąt pojazdu do ślizgania
{
   
    double wa;
   
    double dx, dy;
    p1.y = 9000 - p1.y;
    p2.y = 9000 - p2.y;
   
    dx = p1.x - p2.x;
    dy = p1.y - p2.y;
   
    double wsp = dx / dy;
    wa = atan( wsp );
    double da = atan( - 1 / wsp ) - a;
   
    bool kier;
    if( da > 0 && da < 1.57 )
         kier = 1;
    else if( da > 1.57 && da < 3.14 )
         kier = 1;
    else if( da > 3.14 && da < 4.71 )
         kier = 0;
    else
         kier = 0;
   
    if( !kier )
         return wa - 3.14;
    else
         return wa;
   
   
}
pojazd w kierunku do góry na monitorze przodem to dla pojazdu 0 stopni. Wszytko jest w radianach

       0
pi*1.5     pi/2
       pi
Z góry dziękuję za pomoc.
P-175299
pekfos
» 2019-10-06 14:34:49
Po pierwsze, tangens to y/x, nie x/y. A po drugie atan2(), nie atan(). Przy pisaniu gier nie ma powodu używać atan().
https://stackoverflow.com​/questions/283406​/what-is-the-difference-between-atan-and-atan2-in-c
P-175301
morfik
Temat założony przez niniejszego użytkownika
» 2019-10-06 15:21:02
Fajnie że znam teraz nową funkcje może to pomoże, ale musi być dx/dy a nie dy/dx z tego powodu że taka jest orientacja kąta pojazdu.
Pojazd ma 0 radianów kiedy jest skierowany przodem do górnej krawędzi monitora. Teraz nie problemu aby był jakiś kąt i pojazd się ślizgał.
Tylko czasem ślizga się dobrze czasem w odwrotnym kierunku niż powinien a czasem tylko w jednym kierunku niezależnie po jakim kątem podjedzie
do ściany.
P-175302
pekfos
» 2019-10-06 15:23:45
Jak wygląda kod?
P-175303
morfik
Temat założony przez niniejszego użytkownika
» 2019-10-06 15:31:53
teraz bez retuszu kod ale poprzedni działał jak napisałem a ten to wogólę jakoś dziwnie działa:
C/C++
double kk( double a )
{
    a *= 57.32;
    int t = a;
    t %= 360;
    a = t;
    return a / 57.32;
}
double slizg( double a, punkt p1, punkt p2, punkt d, punkt s )
{
    a = kk( a );
    double wa;
   
    double dx, dy;
    p1.y = 9000 - p1.y;
    p2.y = 9000 - p2.y;
    s.y = 9000 - s.y;
    d.y = 9000 - d.y;
    dx = p1.x - p2.x;
    dy = p1.y - p2.y;
   
    double wsp = dx / dy;
    wa = atan2( dx, dy );
    double da = atan2( 2,( - 1 / wsp ) * 2 ) - a;
   
    cout << "dx= " << dx << endl;
    cout << "dy= " << dy << endl;
    cout << "rk= " << da << endl;
    bool kier = false;
    // if((dx>0&&dy>0)||(dx<0&&dy<0))
    // bool kier=true;
    da = kk( da );
    if( da > 0 && da < 1.57 )
         kier = 1;
    else if( da > 1.57 && da < 3.14 )
         kier = 0;
    else if( da > 3.14 && da < 4.71 )
         kier = 1;
    else
         kier = 0;
   
    if( !kier )
         return wa - 3.14; //-1.57;
    else
         return wa; //-(wa-1.57);
   
   
}
P-175304
pekfos
» 2019-10-06 15:44:00
C/C++
double wsp = dx / dy;
wa = atan2( dx, dy );
double da = atan2( 2,( - 1 / wsp ) * 2 ) - a;
Celem atan2() jest wyeliminowanie tych dzieleń. Wprowadzasz przez nie błędy, których nie obsługujesz i tracisz informacje, które może poprawnie odzyskujesz, a może nie. Podałeś kod z jednoliterowymi nazwami, bez kontekstu i bez możliwości przetestowania. Podaj albo dane dla których kod źle działa, albo matematyczne podstawy na podstawie których twierdzisz, że powinien działać. Z samym takim kodem możesz najwyżej czekać aż ktoś będzie miał za dużo wolnego czasu.

C/C++
double kk( double a )
{
    a *= 57.32;
    int t = a;
    t %= 360;
    a = t;
    return a / 57.32;
}
https://en.cppreference.com/w​/cpp/numeric/math/fmod
P-175305
morfik
Temat założony przez niniejszego użytkownika
» 2019-10-06 16:12:02
To może opisze dokładnie problem otóż:
pojazd ma kąt kierunku ruchu który w kierunku osi y (y maleje od góry monitora) ma 0 radianów poniżej (czyli większe y) ma pi radianów kąt rośnie w prawo.
Gdy pojazd dotknie przeszkody w następnym cyklu to się zatrzymuje (to jest dobrze zaimplementowane) można dostać dwa punkty tej przeszkody trzeba teraz mieć funkcje
która dostanie kąt kierunek ruchu pojazdu i dwa punkty przeszkody zawierające wartości x i y każdy a zwróci kąt jaki musi mieć pojazd aby poruszał się wzdłuż tej prostej.
z tym że musi być odpowiedni zwrot czyli albo return kat_zwracany; albo return kat_zwracany -3.14;
nie będę umieszczać całego kodu bo to 15 plików od 200 do 1500 linii.
P-175306
pekfos
» 2019-10-06 17:08:46
Termin jakiego szukasz to rzutowanie wektora (vector projection). Chcesz rzutować wektor ruchu postaci na wektor "kierunku przeszkody". Wzór to dot(v, n) * n, gdzie dot to iloczyn skalarny, n jest znormalizowanym wektorem przeszkody, a v to wektor ruchu postaci. To od razu uwzględnia prędkość postaci wzdłuż przeszkody po zderzeniu.
P-175307
« 1 »
  Strona 1 z 1