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

Kolizje w mojej platformówce

Ostatnio zmodyfikowano 2023-05-31 17:05
Autor Wiadomość
pekfos
» 2022-12-09 21:25:42
Obliczaj skorygowaną pozycję w bardziej przemyślany sposób. Co chcesz osiągnąć to przemieścić gracza z punktu A do B, gdzie strzelam że masz jakiś wektor prędkości V i B=A+V*dt. Chcesz znaleźć taki punkt C na odcinku AB, gdzie nie zachodzi żadna kolizja, ale gdyby przybliżyć trochę C do B, to już by zachodziła. Najprościej sprawdzić kolizje gracza w punkcie C=B i jeśli zachodzi, to cofnij się trochę na tym odcinku i spróbuj ponownie. Możesz metodą bisekcji szukać dobrej pozycji aż błąd będzie mniejszy od 1 piksela, albo mając dwa sporne prostokąty oblicz dokładne przesunięcie i spróbuj ponownie.
Warto rozważyć:
  • W punkcie A powinieneś być wolny od kolizji, ale jeśli jakimś cudem się zdarzy (np masz pojawiające się znikąd przeszkody, albo buga w kodzie), to zawsze dobrze jest mieć wyjście z błędnego stanu. Można oflagować przeszkody z którymi jesteś w kolizji w punkcie A i ignorować je przy sprawdzaniu kolizji w punkcie C.
  • Jeśli rozważasz duże prędkości (lub duże dt), możesz przelecieć przez przeszkodę, bo pierwsze sprawdzenie zrobisz po drugiej stronie. Żeby tego uniknąć sprawdzaj odległość między A-B i jeśli jest zbyt duża, oblicz kilka pośrednich kroków: B'=A+norm(AB)*krok*i, dla i=1,2,... Krok powinien być na tyle mały by z takim przesunięciem gracz i najmniejsza przeszkoda nie mogły się wyminąć.
  • Jeśli chcesz mieć odbicie, poślizg, albo cokolwiek po napotkaniu przeszkody, to B-C to twój niewykorzystany ruch. Mając informację z czym dokładnie się zderzyłeś możesz np obliczyć kąt odbicia i kontynuować z punktu C z nowym kierunkiem.

Jakby co dt to czas jaki upłynął od ostatniej aktualizacji stanu gry.
P-179809
AP1994
Temat założony przez niniejszego użytkownika
» 2022-12-15 23:44:42
Niestety jak narzazie w ogóle mi nie wychodzi pisanie nowego kodu.
Byłoby miło, gdyby ktoś mi to wytłumaczył prościej niż pekfos.
P-179814
pekfos
» 2022-12-16 18:54:53
Czy gdziekolwiek w tym pisaniu nowego kodu brała udział kartka papieru i długopis? W końcu to jest zadanie z geometrii.
P-179817
AP1994
Temat założony przez niniejszego użytkownika
» 2022-12-16 19:42:07
To nie z liczeniem mam problem, ale z wyobrażeniem sobie czegoś, co by działało.
P-179818
pekfos
» 2022-12-16 20:38:07
Przesuwasz obiekt po linii prostej dopóki nie ma kolizji. Zatrzymujesz się na przeszkodzie bo to ostatnia dobra pozycja. Reszta to optymalizacje i przypadki brzegowe.
P-179820
AP1994
Temat założony przez niniejszego użytkownika
» 2022-12-19 20:16:19
Zacząłem pisać kolizje na zupełnie nowy sposób.
Muszę tylko pouzupełniać warunki i chyba powinno działać.
C/C++
void Collisions::onCollision( player & gracz, mapa & m )
{
   
static bool left = false, right = false, up = false, down = false;
   
gracz.platform = false;
   
for( int i = 0; i <( int ) kolizje.size(); i++ )
   
{
       
for( int j = 0; j <( int ) kolizje[ i ].size(); j++ )
       
{
           
if( kolizje[ i ][ j ] == 0 )
           
{
               
if( left_colision( gracz.x, i * 32 ) )
               
{
                   
left = false;
               
}
               
if( right_colision( gracz.x, i * 32 ) )
               
{
                   
right = false;
               
}
               
if( up_colision( gracz.y, j * 32 ) )
               
{
                   
up = false;
               
}
               
if( down_colision( gracz.y, j * 32 ) )
               
{
                   
down = false;
               
}
            }
           
if( kolizje[ i ][ j ] == 1 )
           
{
               
if( left_colision( gracz.x, i * 32 ) )
               
{
                   
left = true;
               
}
               
if( right_colision( gracz.x, i * 32 ) )
               
{
                   
right = true;
               
}
               
if( up_colision( gracz.y, j * 32 ) )
               
{
                   
up = true;
               
}
               
if( down_colision( gracz.y, j * 32 ) )
               
{
                   
down = true;
               
}
            }
           
if( down && !up ) ///spadłem na kafelki
           
{
               
if( left && right ) ///jestem między prawym a lewym kafelkiem
               
{
                   
                }
               
else if( left || right )
               
{
                   
if( left ) ///koliduje z lewym kafelkiem
                   
{
                       
                    }
                   
else ///koliduje z prawym kafelkiem
                   
{
                       
                    }
                }
               
else ///nie koliduje po bokach
               
{
                   
                }
            }
           
else if( down && up )
           
{
               
if( left && right ) ///jestem między prawym a lewym kafelkiem
               
{
                   
///jeśli zaistnieje to bug
               
}
               
else if( left || right )
               
{
                   
if( left ) ///koliduje z lewym kafelkiem
                   
{
                       
                    }
                   
else ///koliduje z prawym kafelkiem
                   
{
                       
                    }
                }
               
else ///nie koliduje po bokach
               
{
                   
                }
            }
           
else if( !down && up )
           
{
               
if( left && right ) ///jestem między prawym a lewym kafelkiem
               
{
                   
///jeśli zaistnieje to bug
               
}
               
else if( left || right )
               
{
                   
if( left ) ///koliduje z lewym kafelkiem
                   
{
                       
                    }
                   
else ///koliduje z prawym kafelkiem
                   
{
                       
                    }
                }
               
else ///nie koliduje po bokach
               
{
                   
                }
            }
        }
    }
}
P-179825
pekfos
» 2022-12-19 20:38:20
Czemu zmienne statyczne? Wyglądają na błąd. Czy nie powinieneś najpierw ustawić flagi i dopiero potem wykonywać reakcję na kolizje, po pętlach? Dla gracza tego samego rozmiaru co kafel, max 3x3 kafle są interesujące, a tu wykonujesz obsługę kolizji dla każdego kafla na mapie (test i reakcję). Przez zmienne statyczne, będziesz mieć false positive z poprzedniego uruchomienia, więc pewnie zachowa się niepoprawnie. Nawet bez nich będziesz mieć niepoprawne wykryte kolizje, bo wyzerowanie flagi wymaga tu spełnienia bardziej ścisłego warunku niż brak kolizji z przeszkodą.
P-179826
AP1994
Temat założony przez niniejszego użytkownika
» 2022-12-23 21:41:00
Może i jestem noobem informatycznym, ale chyba nie rozumiem do czego ma służyć ta flaga. I nie pytam do czego używa się flag. Tylko do czego miałbym ją wykorzystać w tym kodzie.
P-179830
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona