Jak sprawić, aby obiekt tracił mniejszą prędkość wraz ze wzrostem prędkości

11

Tworzę grę we Flashu i potrzebuję pomocy. Można to uznać za problem matematyczny.

Mój obiekt leci z prędkością, Xa mój obiekt może zderzyć się z kamieniami. Kiedy zderzy się z kamieniem, potrzebuję, aby mój obiekt złamał kamień i kontynuował, ale z mniejszą prędkością. Łatwo jest go na stałe napisać i napisać coś takiego:, myVelocity -= 10;ale moim głównym problemem jest to, że chcę, aby tracił mniejszą prędkość, im wyższa jest prędkość początkowa.

Na przykład: jeśli prędkość wynosi 300, chcę, aby straciła 10, a jeśli wynosiła 200, chcę, aby straciła 20.

Czy można to zrobić za pomocą jakiejś formuły?

Afra
źródło
1
Co powiesz na coś prostego log(myVelocity + 1) * N?
Jonathan Connell,

Odpowiedzi:

6

Chciałbym odwrócić prędkość i pomnożyć przez coś, co lubisz:

float velocity = 300.0f;
float collisionEffect = 3000.0f / velocity;
if (collisionEffect > velocity)
{
    // Choose which one you like: with or without restitution

    // No restitution
    collisionEffect = velocity;

    // Restitution
    collisionEffect = velocity + (collisionEffect - velocity) * 0.3f;
}
velocity -= collisionEffect;

Ten przykład daje następujące efekty:

400 loses 7.5
300 loses 10
200 loses 15
100 loses 30
 50 loses 50  // Using no restitution
 50 loses 53  // Using restitution
 20 loses 20  // Using no restitution
 20 loses 59  // Using restitution
Martijn Courteaux
źródło
Co to jest „restytucja”?
jprete
Restytucja odbija się. Które jest realistyczne.
Martijn Courteaux,
30

system, który ty i inni opisacie, nie wygeneruje naprawdę wyglądającej fizyki. główną formułą jest zmniejszenie 0,5 * m * v ^ 2 (energia kinematyczna) o stałą wartość za każdym razem, gdy obiekt gdzieś trafi.

więc jeśli obiekt o wadze 2 kg trafi w jakiś blok, który potrzebuje 16 j energii, zanim się zepsuje: prędkość ruchu obiektu zmieni się zgodnie z poniższą tabelą:

4  m/s -> the block will not break
5  m/s -> 3   m/s
6  m/s -> 4.4 m/s
7  m/s -> 5.7 m/s
8  m/s -> 6.9 m/s
9  m/s -> 8   m/s
10 m/s -> 9.1 m/s
Ali1S232
źródło
7
Należy to zaakceptować - jest poprawne, realistyczne, łatwe do wdrożenia i obsługuje wszystkie przypadki masy i prędkości obiektu oraz bloku.
Tesserex
3
O ile nie masz określonego efektu „kreskówki fizyki”, który masz nadzieję osiągnąć, zastosowanie bardziej realistycznego systemu jest prawie zawsze dobrym pomysłem; istnieje kilka lepszych sposobów zapewnienia, że ​​nie dostaniesz potencjalnie przełomowych skrzynek.
Steven Stadnicki
1
Ta odpowiedź była dobra, wiem. Ale moja gra osadzona jest w świecie kreskówek i nie musi być realistyczna. Zadając pytanie, powinienem być bardziej szczegółowy.
Afra
1
jest to projekt społecznościowy, ludzie byli tutaj, aby odpowiedzieć na pytanie, a na zadane pytanie jest to najlepsza odpowiedź. To, że wolisz hackerskie rozwiązanie dla konkretnego przypadku, nie oznacza, że ​​ta odpowiedź nie jest najlepsza. Wybierając odpowiedź hacky jako rozwiązanie, gdy ktoś przeszukuje witrynę w poszukiwaniu odpowiedzi na tego rodzaju pytanie, zakłada, że ​​odpowiedź nierealistyczna jest lepsza.
Richard Fabian
1
@Richard Inne rozwiązanie nie jest hackerskie, ponieważ nie wykorzystuje realistycznej fizyki, czy Tetris jest hacky, ponieważ bloki nie spadają gładko? Jeśli ludzie zakładają, że zaakceptowana odpowiedź jest „lepsza” zamiast zakładać, że jest to odpowiedź zadająca pytanie, to ich wina. Wszystkie odpowiedzi i głosy są nadal widoczne.
CiscoIPPhone
2

Tak naprawdę nie podałeś wystarczającej ilości informacji, aby powiedzieć, jaki zakres chcesz, tj. Czy jest on ograniczony, czy chcesz progresję geometryczną itp.

Pierwszą rzeczą, którą chcesz zrobić, jest wyprowadzenie liczby proporcjonalnej do prędkości, którą chcesz stracić (nie musi być taka sama, ale powinna się zmniejszać wraz ze wzrostem prędkości, aby była proporcjonalna do straty). Standardowym sposobem na to jest odwzajemnienie :

temp = 1 / currentVelocity;

Teraz za 100 będziesz mieć 0,01, za 200 będziesz mieć 0,005, za 300 będziesz mieć 0,0033 i tak dalej.

Teraz wystarczy dopasować tę liczbę do tego, czego naprawdę chcesz, mnożąc ją. Więc

k = 3000;
newVelocity = temp * k;

da ci 20 za 300, ale da ci 15 za 200 zamiast 10. To może być dla ciebie w porządku, w takim przypadku nie musisz czytać dalej. Możesz dopasować k, jak chcesz, ale możesz nie otrzymywać liczb tak, jak lubisz, chyba że zrobisz trochę więcej, na przykład zastosujesz postęp geometryczny lub zmienisz podstawę wzrostu. Nie zamierzam wchodzić tutaj w postępy geometryczne, ale jeśli chcesz zmienić bazę, wykonaj następujące czynności:

base = 100;
temp = 1 / (currentVelocity - base);
if (temp < 0) temp = 0; //adjust temp so never less than zero, cannot gain force!

k = 2000;
velocityLoss= temp * k;
if (velocityLoss > currentVelocity) //(1) or make currentVelocity an unsigned int
    velocityLoss = currentVelocity; //(2)

Zapewni to zakres, o który pierwotnie prosiłeś w swoim pytaniu, 300 -> utrata 10, 200 -> utrata 20. FYI 100 -> utrata 40, i 50 -> utrata 80 (!), Co oznacza, że musiałbym ograniczyć odejmowanie - co zrobiłem w wierszach (1) i (2).

Istnieją oczywiście inne sposoby podejścia do tego problemu, które z pewnością napiszą tutaj bardziej biegli matematycznie niż ja.

Inżynier
źródło
0

Myślę, że można użyć prostego podziału według prędkości. Na przykład: lost = 3 000 / myVelocity. Gdy prędkość wynosi 300, tracisz 10, a gdy wynosi 200, tracisz 15. To od Ciebie zależy, czy wybierzesz prawidłowe stałe.

Jeśli chcesz, możesz użyć bardziej złożonej formuły, takiej jak: stała / (stała2 * prędkość ^ 2 + stała3 * prędkość). Znowu - po prostu wybierz stałe, które ci odpowiadają.

zacharmarz
źródło
jest całkowicie odwrotne od tego, o co prosił i co dzieje się w prawdziwej fizyce.
Ali1S232,
Nie rozumiem cie Co jest odwrócone?
zacharmarz
Chyba źle zrozumiałem twoją odpowiedź, mój zły.
Ali1S232,