定点定时抛物效果实现

定点定时抛物效果实现

要实现物体的移动效果,可以通过公式S=vt简单得出。我们定义一个概念叫速度,在游戏步进的一段时间里,会改变自身的位置。假设由A点移动到B点,则为:

P = P + V * \Delta t

其中P为物体当前的位置,一开始为A点。当随着时间流逝,P的值是在更新的。这意味着我在说:“我会一步一步的前往目的的,最终就会按预期的时间达到B点。但若是速度发生了变化,则可能到不了B点,或者没有按期望的时间到达”,所以要其中的V是一个定值。假设我们期望t秒到达B点,那么很简单得出V值:

V=\frac{(B-A)}{t}

不过,我们也可以换一个思路来计算物体的位置,不使用速度的概念。若是t秒从A移动到B,那么0.5t时间则走了一半路程,所以物体的位置是出发点位置加上已走路程。公式表示如下:

P=A+(B-A)*\frac{t_{cur}}{t}

其中t_{cur}代表从A点出发已花费的时间,当t_{cur}等于\frac{1}{2}t时候,则说明进行了一半的路程,即是(B-A)*\frac{1}{2},其中B-A即是AB之间的路程。简单验证一下没有问题,很好理解。

这种做法的一个好处是,即便AB点的位置发生变化,最终物体还是会按时移动到B点,虽然路径是不是直线了,但总比打歪了好。这正好符合了我们标题所说的定点定时,代码和效果如下:

//线性位置变换
Vector2 pos = p[0] + (p[1] - p[0]) * (_tCount / _tMax);
丢咖啡

接下来,我们就来实现更高级一点的抛物线轨迹。但是抛物线方程有很多种,又如何和游戏的步进时间关联起来呢? 首先我们的起点与终点已经确定了,然后确定了运行需要花费的时间。我们隐约可以还感觉到需要确定的是这个抛物线的“弯度”,但是“弯度”不太好描述,所以我们再确定一个P点,或者Q点,来决定抛物线的方程。

y轴向下

 确定P点的情况

首先变换B点坐标系到A为原点的坐标系:

B=B-A

然后假设P点在AB的x距离的m倍处(P点可以随便调整,从而影响整个曲线),所以P点坐标为

((B_x-A_x)*m,0),其中y轴为0,x值是一个已知量。我们定义Px为P点的x坐标,然后A点已经成为原点所以:

P_x =m*B_x

然后写下抛物线方程:y=ax^{2}+bx+c,代入原点得:c=0,再代入P点得:

0=aP_x^{2}+bP_x

化简写成b的等式:

b=-aP_x=-mB_x*a

再将B点代入抛物线方程,再替换b得:

B_y=(1-m)aB_x^{2}

所以a已经求出为:

a=\frac{B_y}{(1-m)B_x^{2}}

所以b为:

b=-\frac{mB_y}{(1-m)B_x}

众所周知,抛物线的x轴轨迹是线性的,所以x坐标和时间的关系如下:

x=B_x*\frac{t_{cur}}{t}

那么通过a、b、x三个变量即可表示y值,再定义k_t=\frac{t_{cur}}{t}最终化简为:

y=k_tB_y\frac{k_t-m}{1-m}

这个时候我们就不再需要求ab的值了,直接使用最终的公式计算结果:

k_t=\frac{t_{cur}}{t}

x=B_xk_t

y=k_tB_y\frac{k_t-m}{1-m}

观察结果我们可以发现kt与m的范围实际都在0到1,最后的式子也意外的简洁。最后效果如下:

定点打击

代码如下,最后我将不必要的计算给注释掉了:

//将B转换到A坐标系
Vector2 B = p->_pos[1] - p->_pos[0];
//AB x轴距离
//float d = B.a;
//x方程
float k_t = GetKSafe(p->_tCount, p->_tMax);//有警告的返回,防止除数为0
float x = k_t * B.a;
//y = a * x^2  + b * x + c ,由于A成为了原点,所以c等于0
//然后假设与x相交的点为p,则px是我们估计的一个常数(小于d)
constexpr float m = 0.75f;
//float p_x = m * d;
//所以 0 = a * p_x^2 + b * p_x,化简得
// b = -a * p_x;
//然后方程又过点B,所以By = a * Bx^2 + b * Bx,再消去b化简得
//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);

//最后转换回原坐标系
Vector2 pos = Vector2(x, y) + p->_pos[0];

  确定Q点的情况

以Q点确定抛物线的公式我还没有推导,太晚了,等下次再试试,说不定是差不多的公式~


10-15更新:

其实Q的x值是P点的一半,所以其实是一样的,只不过m变小了一倍。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值