How to get object to lose less velocity as its speed increases

I'm developing a game in Flash and I need a little help. It can be considered a math problem.

My object is flying with speed X and my object can collide with stones. When it collides with a stone, I need my object to break the stone and continue, but with less velocity. It's easy to hard-code it and write something like: myVelocity -= 10;, but my main problem is that I want it to lose less velocity the higher the initial velocity is.

For example: If the velocity is 300 I want it to lose 10 and if it was 200 I want it to lose 20.

Can this be done with some kind of formula?

• How about something simple like log(myVelocity + 1) * N? Aug 23, 2011 at 8:13

I would invert the speed and multiply by something you like:

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;


This example gives these effects:

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

• What is "restitution"?
– user5290
Aug 23, 2011 at 18:54
• Restitution is bouncing. Which is realistic. Aug 23, 2011 at 20:54

those system you and others describe will not will not generate real looking physics. the main formula is to decrease 0.5*m*v^2 (kinematic energy) by a constant value whenever object hits somewhere.

so if an object with weight 2Kg hits some block, which needs 16j energy before it breaks: object movement speed will change according to this table :

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

• This should be accepted - it's correct, realistic, easy to implement, and will handle all cases of object and block mass and velocity. Aug 23, 2011 at 11:42
• Unless you have a specific 'cartoon physics' effect you're hoping to achieve, going with a more realistic system is almost always a good idea; there are few better ways to ensure that you won't get potentially engine-breaking edge cases. Aug 24, 2011 at 1:32
• This answer was good, I know. But my game is set in a cartoon world and it doesn't need to be realistic. I shouldv'e been more specific when asking the question.
– Afra
Aug 24, 2011 at 9:10
• this is a community project, people were here to answer the question and for the question asked, this is the best answer. Just because you prefer the hacky solution for your particular case doesn't mean that this answer is not the best answer. By selecting the hacky answer as the solution, when someone else searches the site for the answer to this kind of question, they will assume that the non-realistic answer is the better one. Aug 24, 2011 at 11:19
• @Richard The other solution isn't hacky simply because it doesn't use realistic physics, is Tetris hacky because the blocks don't fall smoothly? If people assume an accepted answer is the 'better' one instead of assuming it's the answer that satisfies the asker, it is their fault. All the answers and votes are still evident. Aug 26, 2011 at 8:36

You've not really given enough information to tell what sort of range you want, i.e. whether it is capped, whether you want geometric progression, etc.

First thing you want to do is derive a number proportional to the amount of speed you want to lose (it doesn't have to be the same, but it should decrease as the speed increases to make it proportional to your loss). The standard way to do that is to take the reciprocal:

temp = 1 / currentVelocity;


Now, for 100 you will have 0.01, for 200 you'll have 0.005, for 300 you'll have 0.0033 and so on.

Now you just need to adjust that number to whatever you really want, by multiplying it. So

k = 3000;
newVelocity = temp * k;


will give you your 20 for 300, but it will give you 15 for 200 rather than 10. This may be fine for you, in that case you don't need to read further. You can adjust k as you like but you may not get numbers the way you like them unless you do a little more, such as implement geometric progression, or change the base for increase. I'm not going to go into geometric progressions here, but if you want to change the base, you do it as follows:

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)


This will provide you with the range you originally asked for in your question, 300 -> loss of 10, 200 -> loss of 20. FYI 100 ->loss of 40, and 50 -> loss of 80(!) which means you'd need to restrict your subtraction -- which is what I've done in lines (1) and (2).

There are other ways of approaching this whole problem, of course, which I'm sure those more mathematically adept than I, will post here.

I think, you can use just simple division by velocity. For example: lost = 3 000 / myVelocity. When velocity is 300, you will lose 10, when it's 200, you will lose 15. It's up to you to choose correct constants.

If you want, you can use more complex formula, like: constant / (constant2 * velocity^2 + constant3 * velocity). Again - just choose constants, which will suit you.

• it's completely reversed of what he asked for and what happens in real physics. Aug 23, 2011 at 8:42
• I don't understand you. What is reversed? Aug 23, 2011 at 9:55
• I guess I misunderstood you answer, my bad. Aug 23, 2011 at 10:27