定点定时抛物效果实现
定點(diǎn)定時(shí)拋物效果實(shí)現(xiàn)
要實(shí)現(xiàn)物體的移動(dòng)效果,可以通過(guò)公式簡(jiǎn)單得出。我們定義一個(gè)概念叫速度,在游戲步進(jìn)的一段時(shí)間里,會(huì)改變自身的位置。假設(shè)由A點(diǎn)移動(dòng)到B點(diǎn),則為:
其中P為物體當(dāng)前的位置,一開始為A點(diǎn)。當(dāng)隨著時(shí)間流逝,P的值是在更新的。這意味著我在說(shuō):“我會(huì)一步一步的前往目的的,最終就會(huì)按預(yù)期的時(shí)間達(dá)到B點(diǎn)。但若是速度發(fā)生了變化,則可能到不了B點(diǎn),或者沒(méi)有按期望的時(shí)間到達(dá)”,所以要其中的V是一個(gè)定值。假設(shè)我們期望t秒到達(dá)B點(diǎn),那么很簡(jiǎn)單得出V值:
不過(guò),我們也可以換一個(gè)思路來(lái)計(jì)算物體的位置,不使用速度的概念。若是t秒從A移動(dòng)到B,那么0.5t時(shí)間則走了一半路程,所以物體的位置是出發(fā)點(diǎn)位置加上已走路程。公式表示如下:
其中代表從A點(diǎn)出發(fā)已花費(fèi)的時(shí)間,當(dāng)?shù)扔跁r(shí)候,則說(shuō)明進(jìn)行了一半的路程,即是,其中B-A即是AB之間的路程。簡(jiǎn)單驗(yàn)證一下沒(méi)有問(wèn)題,很好理解。
這種做法的一個(gè)好處是,即便AB點(diǎn)的位置發(fā)生變化,最終物體還是會(huì)按時(shí)移動(dòng)到B點(diǎn),雖然路徑是不是直線了,但總比打歪了好。這正好符合了我們標(biāo)題所說(shuō)的定點(diǎn)定時(shí),代碼和效果如下:
//線性位置變換 Vector2 pos = p[0] + (p[1] - p[0]) * (_tCount / _tMax); 丟咖啡接下來(lái),我們就來(lái)實(shí)現(xiàn)更高級(jí)一點(diǎn)的拋物線軌跡。但是拋物線方程有很多種,又如何和游戲的步進(jìn)時(shí)間關(guān)聯(lián)起來(lái)呢??首先我們的起點(diǎn)與終點(diǎn)已經(jīng)確定了,然后確定了運(yùn)行需要花費(fèi)的時(shí)間。我們隱約可以還感覺(jué)到需要確定的是這個(gè)拋物線的“彎度”,但是“彎度”不太好描述,所以我們?cè)俅_定一個(gè)P點(diǎn),或者Q點(diǎn),來(lái)決定拋物線的方程。
y軸向下?確定P點(diǎn)的情況
首先變換B點(diǎn)坐標(biāo)系到A為原點(diǎn)的坐標(biāo)系:
然后假設(shè)P點(diǎn)在AB的x距離的m倍處(P點(diǎn)可以隨便調(diào)整,從而影響整個(gè)曲線),所以P點(diǎn)坐標(biāo)為
,其中y軸為0,x值是一個(gè)已知量。我們定義Px為P點(diǎn)的x坐標(biāo),然后A點(diǎn)已經(jīng)成為原點(diǎn)所以:
然后寫下拋物線方程:,代入原點(diǎn)得:,再代入P點(diǎn)得:
化簡(jiǎn)寫成b的等式:
再將B點(diǎn)代入拋物線方程,再替換b得:
所以a已經(jīng)求出為:
所以b為:
眾所周知,拋物線的x軸軌跡是線性的,所以x坐標(biāo)和時(shí)間的關(guān)系如下:
那么通過(guò)a、b、x三個(gè)變量即可表示y值,再定義最終化簡(jiǎn)為:
這個(gè)時(shí)候我們就不再需要求ab的值了,直接使用最終的公式計(jì)算結(jié)果:
觀察結(jié)果我們可以發(fā)現(xiàn)kt與m的范圍實(shí)際都在0到1,最后的式子也意外的簡(jiǎn)潔。最后效果如下:
定點(diǎn)打擊代碼如下,最后我將不必要的計(jì)算給注釋掉了:
//將B轉(zhuǎn)換到A坐標(biāo)系 Vector2 B = p->_pos[1] - p->_pos[0]; //AB x軸距離 //float d = B.a; //x方程 float k_t = GetKSafe(p->_tCount, p->_tMax);//有警告的返回,防止除數(shù)為0 float x = k_t * B.a; //y = a * x^2 + b * x + c ,由于A成為了原點(diǎn),所以c等于0 //然后假設(shè)與x相交的點(diǎn)為p,則px是我們估計(jì)的一個(gè)常數(shù)(小于d) constexpr float m = 0.75f; //float p_x = m * d; //所以 0 = a * p_x^2 + b * p_x,化簡(jiǎn)得 // b = -a * p_x; //然后方程又過(guò)點(diǎn)B,所以By = a * Bx^2 + b * Bx,再消去b化簡(jiǎn)得 //float a = B.b / (B.a * B.a - p_x * B.a); //然后求得b值 //float b = -a * p_x; //最后y值為 //float y = a * x * x + b * x; //float y = k_t * (k_t - m) * B.b / (1 - m); float y = k_t * B.b * (k_t - m) / (1 - m);//最后轉(zhuǎn)換回原坐標(biāo)系 Vector2 pos = Vector2(x, y) + p->_pos[0];??確定Q點(diǎn)的情況
以Q點(diǎn)確定拋物線的公式我還沒(méi)有推導(dǎo),太晚了,等下次再試試,說(shuō)不定是差不多的公式~
10-15更新:
其實(shí)Q的x值是P點(diǎn)的一半,所以其實(shí)是一樣的,只不過(guò)m變小了一倍。
總結(jié)
以上是生活随笔為你收集整理的定点定时抛物效果实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 光速AStar寻路算法(C++)
- 下一篇: 【C++教程】01.基本概念