基于指數(shù)衰減的qte狂點(diǎn)功能
游戲中,經(jīng)常會出現(xiàn)qte的時候,需要玩家狂點(diǎn)某個鍵:

通常這種功能實(shí)現(xiàn)和判斷辦法有2種:
累加判斷。
在規(guī)定的時間內(nèi)按滿多少次:

????通常規(guī)定時間會比較短,這樣能保證玩家的按鍵頻率一定是高的。
變體:只記錄距離上下兩次的平均dt<a的按鍵進(jìn)入累加計(jì)數(shù)。這種適用于判定時間較長,但是又要求玩家高頻點(diǎn)擊的情況(比如動畫的時間比較長,所以出現(xiàn)了這種情況)
2.高頻連續(xù)時間判斷
? ? 跟上面的變體類似,不過這回判斷的是高頻連續(xù)時間,也就是說中間不能“慢”,“斷”,即不能出現(xiàn)突然低頻的情況。一旦斷了就結(jié)束這段時間的累加,或者嚴(yán)格的游戲會直接結(jié)束QTE。

PS:值得注意的是由于首尾點(diǎn)沒有前/后點(diǎn),所以頻率可以丟棄或者和前/后相等。類似多點(diǎn)曲線插值的切線方向。
但都不太適合我。我需要一個特殊的狂點(diǎn)機(jī)制,又能表現(xiàn)雙方對決時互相頂撞的力度感:


于是我想到了沖擊函數(shù)和指數(shù)衰減。由于有指數(shù)衰減的存在,玩家的點(diǎn)擊必須高頻,才能使留存值增加到1。一旦低頻,先前的貢獻(xiàn)會隨著時間流逝而衰減。指數(shù)衰減又能保證在留存值非常低的情況下會衰減得很慢,保證玩家在極端劣勢的情況下仍有一線生機(jī)。
由于這個系統(tǒng)類似燃料箱,我們的沖擊相當(dāng)于瞬時添加燃料,而燃料以指數(shù)衰減。所以接下來簡稱這個系統(tǒng)為impulseTank。它的燃料留存初始值為y0,最大值為1,最小值為0。
實(shí)現(xiàn)細(xì)節(jié):
第一:使用遞推式而非解析式。
解析式是:y=y0*e^(-a*t) 。
其中y0是初始留存值,e是自然常數(shù)e,a是衰減系數(shù),t是當(dāng)前系統(tǒng)時間,y是當(dāng)前留存值。
可以看出,當(dāng)t=0,y=y0,當(dāng)t->∞,y->0。a越大,衰減越快。
為什么不用解析式?
不方便編程。玩家可能暫停游戲,繼續(xù)游戲。而且我也希望這個impulseTank的更新頻率能夠手動控制,類似一個物理模擬的物理幀數(shù)可以自己設(shè)置30PS/60FPS....不管怎么說都是遞推式方便。
遞推式推導(dǎo):
y1 = y0*e^(-at)
y2 = y0^e(-a*(t+dt))
? ? =y1*e^(-a*dt)
所以每次更新的代碼就是:
第二,自定義物理幀一定要注意的問題。
這段代碼的:
我原先寫成了
這樣會漏掉了微小的時間差,因?yàn)椴荒鼙WCt_update到時候會正好累加成interval_update。
對于其他功能,這點(diǎn)極小時間差也許不影響功能,但在這里影響了。因?yàn)閠ank里是累加的。這個錯誤最終導(dǎo)致我在Play Focus和Play Maximum的時候,狂點(diǎn)之后留存值y不同。因?yàn)镻lay Focus和Play Maximum的幀率不同,導(dǎo)致了微小的時間差的不同,累計(jì)之后就會出現(xiàn)比較大的不同,即在高屏幕幀率下累計(jì)的y少于低屏幕幀率的y,即便都是同一個tank,同一個物理模擬幀率。
最終效果:

