   Acceleration/friction problem    
  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 speedaccel = CGame:mv.pm_accel * frameTime * wishspeed;m_velocity = m_velocity + wishdir * accel; // Add accelerated speed// Clamp to max speedspeed = 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.9I 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]
  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];  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 ;  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 * dtFt = 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 speedspeed = 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  v2It seems k must very   small for it to work correctly.[edited by - ZiM on April 2, 2003 4:22:06 AM]