游戏里面经常有转盘活动, 为了让转盘表现自然一点, 就需要自己模拟阻尼运动, 分为三个过程: 匀加速运动, 匀速运动, 匀减速运动
设定最高速度为MaxSpeed, SpeedUp1(匀加速运动的加速度), SpeedUp2(匀减速运动的加速度), Expect(期望停留的弧度点)
其实模拟只需要把两个加运动的区间模拟出来, 剩下的就是匀速运动的区间.
1 public struct DampingMotion 2 { 3 /// 最大速度 4 /// 加速运动1 5 /// 减速运动2 6 /// 期望停留在某个弧度 7 public DampingMotion(double maxSpeed, double speedUp1, double speedUp2, double expected) 8 { 9 this.maxSpeed = maxSpeed;10 this.speedUp1 = speedUp1;11 this.speedUp2 = speedUp2;12 this.expected = expected;13 14 time1 = maxSpeed / speedUp1;15 time3 = maxSpeed / speedUp2;16 distance1 = speedUp1 * Math.Pow(time1, 2) / 2;17 distance3 = speedUp2 * Math.Pow(time3, 2) / 2;18 distance2 = expected - (distance1 + distance3) % (Math.PI * 2) + Math.PI * 4;19 time2 = distance2 / maxSpeed;20 }21 22 //单位是秒23 public double GetRotate(double time)24 {25 if (time >= 0 && time < time1)26 {27 return Math.Pow(time, 2) / 2 * speedUp1;28 }29 if (time >= time1 && time < time1 + time2)30 {31 return distance1 + (time - time1) * maxSpeed;32 }33 if (time >= time1 + time2 && time < time1 + time2 + time3)34 {35 var f = time - (time1 + time2);36 return distance1 + distance2 + (37 speedUp2 * Math.Pow(time3, 2) / 2 - 38 speedUp2 * Math.Pow((time3 - f), 2) / 2 39 );40 }41 return distance1 + distance2 + distance3;42 }43 44 public double maxSpeed;45 public double speedUp1;46 public double speedUp2;47 public double expected;48 49 public double time1; //第一段匀加速的时间50 public double time2; //第二段匀速运动时间51 public double time3; //第三段匀减速运动时间52 private double distance1;53 private double distance2;54 private double distance3;55 }
构造好之后, 只需要调用GetRotate函数, 就可以获取某一个时间转盘停留的弧度
这样一个50行不到的代码, 实际上可以当做一个面试题目