Como fazer com que um objeto perca menos velocidade à medida que sua velocidade aumenta


11

Estou desenvolvendo um jogo em Flash e preciso de uma ajudinha. Pode ser considerado um problema de matemática.

Meu objeto está voando com velocidade Xe meu objeto pode colidir com pedras. Quando ela colide com uma pedra, preciso que meu objeto quebre a pedra e continue, mas com menos velocidade. É fácil codificá-lo e escrever algo como:, myVelocity -= 10;mas meu principal problema é que quero perder menos velocidade quanto maior a velocidade inicial.

Por exemplo: se a velocidade for 300, quero perder 10 e, se for 200, quero 20.

Isso pode ser feito com algum tipo de fórmula?


1
Que tal algo simples como log(myVelocity + 1) * N?
Jonathan Connell

Respostas:


6

Gostaria de inverter a velocidade e multiplicar por algo que você gosta:

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;

Este exemplo fornece estes efeitos:

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

O que é "restituição"?
jprete

Restituição está saltando. O que é realista.
Martijn Courteaux 23/08/19

30

os sistemas que você e outras pessoas descrevem não irão gerar uma aparência real. a fórmula principal é diminuir 0,5 * m * v ^ 2 (energia cinemática) por um valor constante sempre que o objeto atingir algum lugar.

portanto, se um objeto com peso de 2Kg atingir algum bloco, que precisa de energia de 16j antes de quebrar: a velocidade de movimento do objeto mudará de acordo com esta tabela:

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
Isso deve ser aceito - é correto, realista, fácil de implementar e manipulará todos os casos de objetos, bloqueando a massa e a velocidade.
Tesserex

3
A menos que você tenha um efeito específico da "física dos desenhos animados" que espera obter, usar um sistema mais realista é quase sempre uma boa idéia; existem algumas maneiras melhores de garantir que você não tenha casos de borda potencialmente inovadores.
Steven Stadnicki

1
Essa resposta foi boa, eu sei. Mas meu jogo se passa no mundo dos desenhos animados e não precisa ser realista. Eu deveria ter sido mais específico ao fazer a pergunta.
Afra

1
este é um projeto comunitário, as pessoas estavam aqui para responder à pergunta e, para a pergunta feita, esta é a melhor resposta. Só porque você prefere a solução hacky para o seu caso em particular, não significa que essa resposta não seja a melhor. Ao selecionar a resposta hacky como a solução, quando outra pessoa pesquisar no site a resposta para esse tipo de pergunta, ela assumirá que a resposta não realista é a melhor.
Richard Fabian

1
@ Richard A outra solução não é hacky simplesmente porque não usa física realista, é Tetris hacky porque os blocos não caem sem problemas? Se as pessoas assumem que uma resposta aceita é a melhor, em vez de assumir que é a resposta que satisfaz o solicitante, a culpa é deles. Todas as respostas e votos ainda são evidentes.
CiscoIPPhone

2

Você realmente não forneceu informações suficientes para dizer que tipo de intervalo deseja, ou seja, se está limitado, se deseja progressão geométrica etc.

A primeira coisa que você deseja fazer é derivar um número proporcional à quantidade de velocidade que você deseja perder (não precisa ser o mesmo, mas deve diminuir à medida que a velocidade aumenta para torná-lo proporcional à sua perda). A maneira padrão de fazer isso é tomar o inverso :

temp = 1 / currentVelocity;

Agora, para 100 você terá 0,01, para 200 terá 0,005, para 300 terá 0,0033 e assim por diante.

Agora você só precisa ajustar esse número para o que realmente deseja, multiplicando-o. assim

k = 3000;
newVelocity = temp * k;

você receberá 20 por 300, mas 15 por 200 em vez de 10. Isso pode ser bom para você; nesse caso, você não precisa ler mais. Você pode ajustar k como quiser, mas pode não obter os números da maneira que preferir, a menos que faça um pouco mais, como implementar a progressão geométrica ou alterar a base para aumentar. Não vou entrar em progressões geométricas aqui, mas se você quiser alterar a base, faça o seguinte:

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)

Isso fornecerá o intervalo solicitado originalmente na sua pergunta: 300 -> perda de 10, 200 -> perda de 20. FYI 100 -> perda de 40 e 50 -> perda de 80 (!), O que significa que você precisaria restringir sua subtração - o que fiz nas linhas (1) e (2).

Existem outras maneiras de abordar todo esse problema, é claro, que tenho certeza de que aqueles que são matematicamente mais adeptos do que eu, postarão aqui.


0

Eu acho que você pode usar apenas uma simples divisão por velocidade. Por exemplo: perdido = 3 000 / myVelocity. Quando a velocidade é 300, você perde 10, quando 200, perde 15. Cabe a você escolher constantes corretas.

Se desejar, você pode usar uma fórmula mais complexa, como: constante / (constante2 * velocidade ^ 2 + constante3 * velocidade). Mais uma vez - basta escolher constantes, o que mais lhe convém.


está completamente invertido do que ele pediu e do que acontece na física real.
precisa saber é o seguinte

Eu não te entendo O que é revertido?
Zacharmarz 23/08

Acho que não entendi sua resposta, meu mal.
precisa saber é o seguinte
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.