Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

ZiM

Acceleration/friction problem

This topic is 5649 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In very simple top-down 2D game I'm writing I need player characters to accelerate and, when user releases the key, decelerate smootly until stopping completely. So far I have been able to write a system that works, well, partially. The problem is that the with current system the maximum speed player can move is depedent on framerate, and I cannot seem to figure out how to fix it. I have limited the framerate to 60 FPS, and the speed only goes up to about 91 at most although max speed is 160 units/sec. If I decrease update rate down to 30 FPS then it goes up to 142 units at most. The way I apply friction (or deceleration force) seems to be the culprit; eg. I multiply the velocity vector by friction coefficient of 0.9 every frame. Here's the code: // --- PlayerMove() ------------------------------------- // fmove and smove inputs contain the desired forward/backward // and strafe speeds, respectively (units per second). CVector forward, right; CVector wishdir, wishvel; float speed, wishspeed, dotspeed, diffspeed, accel; forward.x = cos(DEG2RAD(m_yaw)); forward.y = sin(DEG2RAD(m_yaw)); right = CVector::CrossProduct(CVector(0, 0, 1), forward); wishvel = forward * fmove + right * smove; wishdir = wishvel; wishspeed = wishdir.Normalize(); // Accelerate (Quake-style accel routines) dotspeed = CVector::DotProduct(m_velocity, wishdir); diffspeed = wishspeed - dotspeed; if(diffspeed <= 0) return; // No increase in speed accel = CGame:mv.pm_accel * frameTime * wishspeed; m_velocity = m_velocity + wishdir * accel; // Add accelerated speed // Clamp to max speed speed = m_velocity.Length(); if(speed > CGame:mv.pm_maxspeed) m_velocity.Scale(CGame:mv.pm_maxspeed/speed); // // Very last I apply friction to the velocity so that player // slows down if user releases the key. m_velocity.Scale(CGame:mv.pm_friction); // About 0.9 I haven't figured out any other ways of applying friction (or deceleration, whatever its called) to a vector quantity (velocity). Any suggestions? Also suggestions on how to rather do this all in a way consistent with modern physics are welcome. TIA. [edited by - ZiM on April 1, 2003 11:44:40 AM] [edited by - ZiM on April 1, 2003 11:47:46 AM]

Share this post


Link to post
Share on other sites
Advertisement

  
m_velocity.Scale(pow(CGame::Pmv.pm_friction,frameTime));


You'll need to raise your pm_friction value.


[edited by - Bagel Man on April 1, 2003 9:06:57 PM]

Share this post


Link to post
Share on other sites
It sounds like you could do with looking at a few high-school mechanics problems that involve friction. A constant friction function is okay but another interesting one is to have friction being a function of velocity for eg drag(v) = kv^2 (as for the simple particle falling through fluid model) that would allow you to get rid of the *nasty* max vel clamp as this form of friction naturally gives rise to a "terminal velocity".

Also, on the timing front, I guess you don''t want to over-egg the pudding but have you considered using a millisecond timer to manage your dynamics so the speed/responsiveness of your sim doesn''t depend on the current frame-rate - just an idea

Share this post


Link to post
Share on other sites
I came up with following solution which is more close to physics laws of motion. Thrust and friction are both treated as forces. Friction is inverse of the current velocity with some predefined magnitude (units to slow down per second). By tweaking mass I can effectively change "quickness" of acceleration.


CVector forward, right;
float fmove, smove, speed;
float mass = 0.5;
CVector a, F, Ft, Fd;

// Physics formulas needed:
// F = Ft - Fd
// a = F/m
// v += a * dt
// r += v * dt

Ft = forward * fmove + right * smove;

Fd = m_velocity;
Fd.Normalize();
Fd = Fd * PM_FRICTION;

F = Ft - Fd;
a = F/mass;

m_velocity = m_velocity + a * cmd.dt;

// Clamp to max speed
speed = m_velocity.Length();

if(speed > CGame:mv.pm_maxspeed)
m_velocity.Scale(CGame:mv.pm_maxspeed/speed);


I should probably start using using the drag formulae you suggested to calculate Fd; Fd=k v2
It seems k must very small for it to work correctly.

[edited by - ZiM on April 2, 2003 4:22:06 AM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!