Come far sì che l'oggetto perda meno velocità all'aumentare della sua velocità


11

Sto sviluppando un gioco in Flash e ho bisogno di un piccolo aiuto. Può essere considerato un problema di matematica.

Il mio oggetto vola veloce Xe il mio oggetto può scontrarsi con pietre. Quando si scontra con una pietra, ho bisogno che il mio oggetto rompa la pietra e continui, ma con meno velocità. È facile codificarlo e scrivere qualcosa del genere:, myVelocity -= 10;ma il mio problema principale è che voglio perdere meno velocità maggiore è la velocità iniziale.

Ad esempio: se la velocità è 300 voglio che perda 10 e se fosse 200 voglio che perda 20.

Questo può essere fatto con un qualche tipo di formula?


1
Che ne dite di qualcosa di semplice come log(myVelocity + 1) * N?
Jonathan Connell,

Risposte:


6

Vorrei invertire la velocità e moltiplicare per qualcosa che ti piace:

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;

Questo esempio fornisce questi effetti:

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

Che cos'è la "restituzione"?
giovedì

La restituzione sta rimbalzando. Il che è realistico.
Martijn Courteaux,

30

quei sistemi che tu e altri descrivete non genereranno una fisica dall'aspetto reale. la formula principale è di diminuire 0,5 * m * v ^ 2 (energia cinematica) di un valore costante ogni volta che l'oggetto colpisce da qualche parte.

quindi se un oggetto con peso 2Kg colpisce un blocco, che necessita di energia 16j prima che si rompa: la velocità di movimento dell'oggetto cambierà secondo questa tabella:

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

7
Questo dovrebbe essere accettato: è corretto, realistico, facile da implementare e gestirà tutti i casi di oggetti e bloccherà la massa e la velocità.
Tesserex,

3
A meno che tu non abbia un effetto specifico di "fisica dei cartoni animati" che speri di ottenere, andare con un sistema più realistico è quasi sempre una buona idea; ci sono alcuni modi migliori per assicurarsi che non si ottengano casi limite potenzialmente motori.
Steven Stadnicki,

1
Questa risposta è stata buona, lo so. Ma il mio gioco è ambientato in un mondo di cartoni animati e non deve essere realistico. Avrei dovuto essere più preciso quando ponevo la domanda.
Afra,

1
questo è un progetto della comunità, le persone erano qui per rispondere alla domanda e per la domanda posta, questa è la risposta migliore. Solo perché preferisci la soluzione hacky per il tuo caso particolare non significa che questa risposta non sia la migliore. Selezionando la risposta hacky come soluzione, quando qualcun altro cerca nel sito la risposta a questo tipo di domanda, presumerà che la risposta non realistica sia la migliore.
Richard Fabian,

1
@Richard L'altra soluzione non è hacky semplicemente perché non usa una fisica realistica, Tetris hacky perché i blocchi non cadono senza intoppi? Se le persone assumono che una risposta accettata sia quella "migliore" invece di supporre che sia la risposta a soddisfare chi chiede, è colpa loro. Tutte le risposte e i voti sono ancora evidenti.
CiscoIPPhone il

2

Non hai davvero fornito abbastanza informazioni per dire che tipo di intervallo vuoi, cioè se è limitato, se vuoi progressione geometrica, ecc.

La prima cosa che vuoi fare è derivare un numero proporzionale alla quantità di velocità che vuoi perdere (non deve essere la stessa, ma dovrebbe diminuire all'aumentare della velocità per renderlo proporzionale alla tua perdita). Il modo standard per farlo è prendere il reciproco :

temp = 1 / currentVelocity;

Ora, per 100 avrai 0,01, per 200 avrai 0,005, per 300 avrai 0,0033 e così via.

Ora devi solo adattare quel numero a quello che vuoi davvero, moltiplicandolo. Così

k = 3000;
newVelocity = temp * k;

ti darà i tuoi 20 per 300, ma ti darà 15 per 200 anziché 10. Questo potrebbe andare bene per te, in tal caso non dovrai leggere più a fondo. Puoi regolare k come preferisci ma potresti non ottenere i numeri come preferisci a meno che tu non faccia un po 'di più, come implementare la progressione geometrica o cambiare la base per aumentare. Non ho intenzione di entrare in progressioni geometriche qui, ma se vuoi cambiare la base, lo fai come segue:

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)

Questo ti fornirà l'intervallo inizialmente richiesto nella tua domanda, 300 -> perdita di 10, 200 -> perdita di 20. FYI 100 -> perdita di 40 e 50 -> perdita di 80 (!) Che significa che dovrei limitare la tua sottrazione - che è quello che ho fatto nelle righe (1) e (2).

Ci sono altri modi per affrontare l'intero problema, ovviamente, che sono sicuro che quelli più matematicamente abili di me pubblicheranno qui.


0

Penso che puoi usare solo una semplice divisione per velocità. Ad esempio: perso = 3 000 / myVelocity. Quando la velocità è 300, perderai 10, quando è 200, perderai 15. Sta a te scegliere le costanti corrette.

Se lo desideri, puoi utilizzare una formula più complessa, come: costante / (costante2 * velocità ^ 2 + costante3 * velocità). Ancora una volta: basta scegliere le costanti, che si adatteranno a te.


è completamente al contrario di ciò che ha chiesto e di ciò che accade nella fisica reale.
Ali1S232,

Non ti capisco Cosa è invertito?
Zacharmarz,

Immagino di aver frainteso la tua risposta, mia cattiva.
Ali1S232,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.