Rozwijam grę, w której gracz może używać lin do huśtania się (tak jak to zrobił Spiderman lub Bionic Commando ) i mam problem z implementacją tego zachowania. Czy ktoś może mi pomóc, jak to zrobić, mam na myśli wzory fizyki itp. Do tej pory wpadłem na 3 pomysły. Jeden używa wiosny, ale zajmuje dużo czasu, a czasem jest nerwowy. Pozostali dwaj próbują obliczyć następny krok (jeden poprzez obliczenie energii potencjalnej i jeden przez obliczenie momentu obrotowego) i oba z nich prawie się zawieszają, gdy aktor próbuje się kołysać.
Oto kod, który napisałem, aby obliczyć moment obrotowy:
float dx = Runner->getPosition().x - ancher.x;
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;
physics
platformer
rope-physics
Ali1S232
źródło
źródło
Odpowiedzi:
Jeśli chcesz sztywnego huśtania, więc odległość do punktu obrotu jest stała, po prostu traktuj postać jako punkt na okręgu wyśrodkowanym w punkcie obrotu. Daj mu jednowymiarową (wzdłuż koła) prędkość kątową. W każdej klatce powinno być przyspieszenie kątowe
accelerationDueToGravity * cos(angleOfPlayerOnCircle)
(z 0 stopni skierowanymi w prawo).Jeśli chcesz, aby lina była dłuższa / krótsza, możesz skorzystać z powyższego schematu i po prostu zmienić promień każdej ramy.
źródło
po wielu próbach poszedłem z box2d.
do tej symulacji są zasadniczo dwa podejścia lub przynajmniej znalazłem 2:
w każdym senario musisz mieć anchera (który w moim przypadku był statycznym pudełkiem). lepiej, jeśli zmniejszysz ciężar części liny (albo użyjesz kształtów koła, albo prostokątów), na przykład, aby uzyskać bardziej realistyczną fizykę, ustawię ich gęstość na 0,1, a dla pudełka podłączonego na końcu liny zastosowałem gęstość 10.
kolejną rzeczą, którą musisz się martwić o to, jak Twój segment liny reaguje na siebie. chciałem tylko, żeby moja lina poruszała się swobodnie na scenie, więc oznaczyłem wszystkie urządzenia linowe jako czujniki. możesz potrzebować innej approch.
Następną rzeczą, o którą musisz się martwić, jest liczba iteracji, które przekazujesz do aktualizacji światowej: dla niskiego segmentu liny (może najwyżej 8) nie ma potrzeby używania wysokiej wartości iteracji, może 10/10, która sama box2d sugerowała wystarczy, ale jeśli zwiększysz liczbę segmentów, na przykład wypróbowałem 30 segmentów, przy małej liczbie iteracji lina wydaje się zwiększać swoją długość bardziej niż powinna, więc być może potrzebujesz 40/40 iteracji, aby rozwiązać te sytuacje.
po niektórych testach wydaje się, że pole 2d jest przeznaczone do scen o rozmiarach obiektów od 0,1 m do 10 m, a maksymalny rozmiar sugerowany dla dużych scen wynosi około 50 x 50 m. więc w zasadzie musisz przeskalować obiekt, aby dopasować te parametry. w moim przypadku najpierw próbowałem przekazać pozycje pikseli bezpośrednio do box2d, ale wydawało się, że istnieją pewne ograniczenia prędkości, które uniemożliwiają światowi ruch tak szybko, jak powinien, więc musiałem przeskalować scenę około 64 razy, aby uzyskać najlepsze wyniki. chociaż sam nie testowałem, w box2d są pewne ograniczenia, które uniemożliwiają korzystanie z większych scen. na przykład w
b2Setting.h
pliku jest zdefiniowana wartość ,#define b2_maxTranslation 2.0f
którą można zmienić ustawienia box2d, ale nie wydaje się to zalecane.źródło
Czy zastanawiałeś się nad spowolnieniem prędkości ruchu wahadłowego w zależności od odległości liny od linii pionowej (środek)?
źródło
Gdy gracz znajdzie się dalej niż długość liny, zostanie natychmiast odepchnięty z siłą równą odległości, którą przeszedł. To powinno działać bez poczucia sprężystości i powinno być intuicyjne dla gracza. Być może będziesz musiał dostosować swoją fizykę, aby uzyskać najlepsze wyniki w grze.
Kiedy lina jest przymocowana. Zapisz
maxLength
wartość.Przy każdej aktualizacji sprawdź
distance
międzyplayer
iattachPoint
Jeśli wartość
distance
jest mniejsza niżmaxLength
normalnie, brak efektów ze strony liny.Jeśli odległość jest większa niż
maxLength
, znajdźnormal
odattachPoint
do gracza. Uzyskaj różnicę międzydistance
imaxLength
. Dodaj doplayerVelocity
,normal
pomnożonej przez różnicę.Pseudo kod:
źródło
dx = player.x - attachpoint.x
idy = player.y - attachpoint.y
.Jeśli spojrzysz na http://www.cocos2d-iphone.org/archives/1112 istnieje implementacja liny ze sztywnym korpusem przymocowanym do końca liny. Wykorzystuje Box2D do silnika fizyki. Jeśli spojrzysz na kod źródłowy, jestem pewien, że możesz go zaimplementować w dowolnym języku, który ci się podoba.
Ponadto powyższy link do pytania na temat liny jest mój, a powyższa wersja demo (link podany powyżej) naprawdę pomogła.
źródło