數量緩中出功能
如果我們考慮平臺作爲一個單元從一側移動到另一側的時間(可能是10秒,或17幀,這沒關係,我們現在單位工作)。
我們對距離做了同樣的處理。平臺必須在一個單位時間內移動一個單位距離。
對於此回答時間是t
和位置是寫作爲時間的函數f(t)
是在時間t
平臺位置。
對於簡單的線性運動,那麼功能只是f(t)=t
。所以在時間t=0
移動的距離是0,在時間0.5(中途)距離是0.5(中途),等等。
所以讓我們把它變成更實用的東西。
請原諒我的swift我從來沒有使用過它(我相信你可以糾正任何語法錯誤)。
// First normalise the distance and time (make them one unit long)
// get the distance
let distance = Double(xPositionStopGoingLeft - xPositionStopGoingRight);
// use that and the velocity to get the time to travel
let timeToTravel = distance/Double(velAmountX);
// first we have a frame ticker
gameTick += 1; // that ticks for every frame
// We can assume that the platform is always moving back and forth
// Now is the unit time where at now = 2 the platform has move there and back
// at 3 it has move across again and at 4 back again.
let now = Double(gameTick)/timeToTravel; // normalize time.
// get the remainder of 2 as from 0-1 is moving forward and 1-2 is back
let phase = now % 2.0;
// We also need the unit time for the function f(t)=t
let t = abs(phase - 1);
if phase >= 1 { t = 1 - t } // reverse for return
// implement the function f(t) = t where f(t) is dist
let dist = t
// and convert back to pixel distance
platform.position.x = Int(dist * distance + Double(xPositionStopGoingLeft));
這就是線性平臺。爲了讓運動改變一切,我們需要做的是改變功能f(t)=?
,在其行let dist = t
對於出便於上面有是在最方便的應用f(t) = t * t/((t * t) + (1 - t) * (1 - t))
曾經有一個方便的功能是一些t*t
哪些是權力,t
的權力2或t^2。在迅速其pow(t,2)
所以重寫如上代碼
let dist = pow(t,2)/(pow(t,2) + pow((1-t),2);
這給出了在開始和結束作爲行進的距離和時間的好的易於恆定在中點01速度必須更大,以趕上緩慢的開始和結束。 (注意,得到上述函數的導數可以讓你在每一個時間點都能測出速度f'(t) = speed(t) = 2(-(t-1)t)^(2-1) /(t^2+(1-t)^2)^2
)
這個函數很好,時間0.5的速度是2,與功率相同旅程將是1)。該函數的一個便利特性是中途點的速度總是與功率相同。如果你想讓它在中點移動得非常快,比如說4倍的速度,那麼你可以使用4的冪數來使得dist = pow(t,4)/(pow(t,4)+ pow((1-∞) T),4);
如果你想讓它只有加快一點說,在中心有1.2倍的速度,則功率爲1.2
let dist = pow(t,1.2)/(pow(t,1.2) + pow((1-t),1.2);
所以現在我們可以引入另一個術語,maxSpeed
這是標準化的maxSpeed(更準確地說,它是在t = 0.5時的速度,因爲它可以慢於1,但是對於我們需要的最大速度將會這樣做)
let maxSpeed = Double(velAmountX + 3)/Double(velAmountX); // 3 pixels per frame faster
和函數f(t) = t^m/(t^m + (1-t)^m)
其中m是maxSpeed
。
並作爲代碼
令DIST = POW(T,MAXSPEED)/(POW(T,MAXSPEED)+ POW((1-T),MAXSPEED);
所以把所有一起
現在
// the next 3 lines can be constats
let distance = Double(xPositionStopGoingLeft - xPositionStopGoingRight);
let timeToTravel = distance/Double(velAmountX);
let maxSpeed = Double(velAmountX + 3)/Double(velAmountX);
gameTick += 1; // that ticks for every frame
let now = Double(gameTick)/timeToTravel; // normalize time.
let phase = now % 2.0;
let t = abs(phase - 1);
if phase >= 1 { t = 1 - t } // reverse for return
// the next line is the ease function
let dist = pow(t, maxSpeed)/(pow(t, maxSpeed) + pow((1-t) ,maxSpeed);
// position the platform
platform.position.x = Int(dist * distance + Double(xPositionStopGoingLeft));
你可以在任何剔計算平臺的位置。如果你想慢下來,整場比賽,並在半步幀蜱它仍然會正常工作。如果你的速度比賽了gameTick += 2
它仍然有效。
最大速度也可以低於線速度。如果您希望平臺的速度爲正常速度的一半t=0.5
設置maxSpeed = 0.5
並且在中途點速度將是一半。爲了讓所有工作在開始和結束時都更加輕鬆,將會更快地進入和趕出。 (和作品反向也一樣)
爲了幫助可能的可視化表示
圖像顯示平臺的來回運動一段時間。距離約爲60像素,時間可以是1分鐘。所以在1分鐘左右就會有一個右邊的2分鐘,依此類推。
然後,我們通過僅查看運動的一個部分來規範運動和時間。
該圖表示從左至右側移動,距離爲1,時間是1。剛剛被縮放以適合單元箱(1由1盒)。
紅線代表線性運動f(t)=t
(恆速)。在任何時候,你都可以在移動的路線上移動,並且可以找到行駛的距離。
綠線代表緩和功能f(t)=t*t/(t*t+(1-t)*(1-t))
,它的工作原理是一樣的。在任何時間點掃描找到綠線並向下移動以獲得距離。函數f(t)爲你做。
隨着最高速度,dist 0.5處的線條陡度發生變化,陡峭的坡度代表更快的行程。
謝謝對於深奧的答案...我只是把它扔在那裏,這是我的頭肯定哈哈。我會花一些時間來研究這一點,以瞭解發生了什麼... – Discoveringmypath
@Discoveringmypath我添加了一個可以幫助您瞭解解決方案的視覺表示。 – Blindman67
這個答案很棒。 – Fluidity