|
模拟投射物轨迹——函数粗略版
引用 下定决心减少来GA的时间了…… 而且是大量的减少…… 恩…… 其实很早就有这样的打算了…… 不过我这人一向是重视承诺的…… 至少自己该做的…… 绝对会做完…… 好吧……
这个函数本来时被小血逼着为位面消隐做的东西……
因为自己不会VJ,所以只是写了个简单的函数,用于测试高度公式以及效果,连排泄都没有做……
而且我也根本没有想将其发上来,至少在开始写这个帖子之前没有……
算了,还是不多说了……
演示下载: aim.w3x (22 K) 下载次数:2
复制代码 jass -
- function Getb takes real H0,real H1,real L,real K returns real
- //b
- return 2*((K*L-H0)+SquareRoot((K*L-H0)*(K*L-H1)))*10000/L
- endfunction
- function Geta takes real H0,real H1,real L,real K returns real
- //a
- local real b = Getb(H0,H1,L,K)
- return b*b/40000/(H0-K*L)
- endfunction
- function MoveProjectileB takes nothing returns nothing
- local timer udg_t = null
- local unit udg_u = null
- local integer udg_i = 0
- local integer temp = 0
- local real VX = 0
- local real H1 = 0
- local real H2 = 0
- local real dis = 0
- local real angle = 0
- local unit Aim = null
- local unit Projectile = null
- local location Aimloc = null
- local location Proloc = null
- set udg_t = GetExpiredTimer()
- set temp = udg_i
- set VX = GetStoredReal(udg_W3V,I2S(temp),"VX")
- set udg_i = GetStoredInteger(udg_W3V, I2S(temp), "AimUnitHandle")
- set Aim = udg_u
- set Aimloc = GetUnitLoc(Aim)
- set udg_i = GetStoredInteger(udg_W3V, I2S(temp), "Projectile")
- set Projectile = udg_u
- set Proloc = GetUnitLoc(Projectile)
- set dis = DistanceBetweenPoints(Proloc, Aimloc)
- set angle = AngleBetweenPoints(Proloc, Aimloc)
- if dis < VX then
- call RemoveUnit(Projectile)
- call PauseTimer(GetExpiredTimer())
- //命中目标
- //省略诸多排泄
- endif
- set H2 = GetUnitFlyHeight(Projectile)
- set H1 = GetUnitFlyHeight(Aim)
- call SetUnitFlyHeight(Projectile, H2-(H2-H1)*VX/dis, 0 )
- set Proloc = PolarProjectionBJ(Proloc,VX, angle)
- call SetUnitX(Projectile,GetLocationX(Proloc))
- call SetUnitY(Projectile,GetLocationY(Proloc))
- call SetUnitFacing( Projectile,angle)
- endfunction
- function MoveProjectileA takes nothing returns nothing
- local timer udg_t = null
- local unit udg_u = null
- local integer udg_i = 0
- local integer temp = 0
- local real VX = 0
- local real X = 0
- local real Y = 0
- local real H0 = 0
- local real T = 0
- local real a = 0
- local real b = 0
- local unit Aim = null
- local unit Projectile = null
- local location Aimloc = null
- local location Proloc = null
- local timer time
- set udg_t = GetExpiredTimer()
- set temp = udg_i
- set udg_i = GetStoredInteger(udg_W3V, I2S(temp), "AimUnitHandle")
- set Aim = udg_u
- set Aimloc = GetUnitLoc(Aim)
- set X = GetStoredReal(udg_W3V,I2S(temp),"X")
- set Y = GetStoredReal(udg_W3V,I2S(temp),"Y")
- set VX = GetStoredReal(udg_W3V,I2S(temp),"VX")
- set H0 = GetStoredReal(udg_W3V,I2S(temp),"H0")
- set udg_i = GetStoredInteger(udg_W3V, I2S(temp), "Projectile")
- set Projectile = udg_u
- if (GetLocationX(Aimloc) != X) or (GetLocationY(Aimloc) != Y) then
- set udg_t = CreateTimer()
- set temp = udg_i
- set time =udg_t
- call StoreReal(udg_W3V,I2S(temp),"VX",VX)
- set udg_u = Aim
- call StoreInteger(udg_W3V,I2S(temp),"AimUnitHandle",udg_i)
- set udg_u = Projectile
- call StoreInteger(udg_W3V,I2S(temp),"Projectile",udg_i)
- call TimerStart(time,udg_interval,true,function MoveProjectileB)
- call PauseTimer(GetExpiredTimer())
- call DestroyTimer(GetExpiredTimer())
- return
- //进入第二种移动方式
- //省略诸多排泄
- endif
- set a = GetStoredReal(udg_W3V,I2S(temp),"a")
- set b = GetStoredReal(udg_W3V,I2S(temp),"b")
- set Proloc = GetUnitLoc(Projectile)
- if DistanceBetweenPoints(Proloc, Aimloc) < VX then
- call RemoveUnit(Projectile)
- call PauseTimer(GetExpiredTimer())
- //命中目标
- //省略诸多排泄
- endif
- set T = GetStoredReal(udg_W3V,I2S(temp),"T")
- call SetUnitFlyHeight(Projectile,a*T*T/10000*VX*VX+b*T*VX/10000+H0, 0 )
- set Proloc = PolarProjectionBJ(Proloc,VX, AngleBetweenPoints(Proloc, Aimloc))
- call SetUnitX(Projectile,GetLocationX(Proloc))
- call SetUnitY(Projectile,GetLocationY(Proloc))
- call StoreReal(udg_W3V,I2S(temp),"T",T+1)
- endfunction
- function GetAim takes unit aim,location loc,integer ut,player p,real k,integer v,real h0 returns nothing//参数依次是 目标单位aim, 发动攻击单位位置loc, 投射物马甲的单位类型ut ,攻击单位的所有者(所有玩家)p, 射弹弧度k ,射弹速率v ,射弹初始高度h0
- local timer udg_t = null
- local unit udg_u = null
- local integer udg_i = 0
- local integer temp = 0
- local location l = null
- local timer temptimer
- set udg_t = CreateTimer()
- set temptimer = udg_t
- set temp = udg_i
- set udg_u = aim
- call StoreInteger(udg_W3V,I2S(temp),"AimUnitHandle",udg_i)
- call StoreReal(udg_W3V,I2S(temp),"VX",R2I(I2R(v) * udg_interval))
- set l = GetUnitLoc(aim)
- call CreateNUnitsAtLoc( 1, ut, p, loc, AngleBetweenPoints(loc,l) )
- set udg_u = GetLastCreatedUnit()
- call SetUnitFlyHeight( udg_u, h0, 0 )
- call StoreInteger(udg_W3V,I2S(temp),"Projectile",udg_i)
- call StoreReal(udg_W3V,I2S(temp),"b",Getb(h0,GetUnitFlyHeight(aim),DistanceBetweenPoints(l, loc),k))
- call StoreReal(udg_W3V,I2S(temp),"a",Geta(h0,GetUnitFlyHeight(aim),DistanceBetweenPoints(l, loc),k))
- call StoreReal(udg_W3V,I2S(temp),"X",GetLocationX(l))
- call StoreReal(udg_W3V,I2S(temp),"Y",GetLocationY(l))
- call StoreReal(udg_W3V,I2S(temp),"T",0)
- call StoreReal(udg_W3V,I2S(temp),"H0",h0)
- call TimerStart(temptimer,udg_interval,true,function MoveProjectileA)
- endfunction
-
|
以上是最简单的代码,GC版,无排泄,无变量声明(声明看最后的演示吧)。反正诸位也许会用的GAer大约也能自己改成完好的。
其中:
这两个函数的返回值是投射物曲线的抛物线方程Y=aX2+bX+c中的a、b参数,而参数c是H0,也就是投射物的初始高度。
之后的三个函数是具体模拟投射物效果的函数:
GetAim是记录各种参数,然后开始曲线方案1的计时器。具体需要绑定的参数有:
Aim,(目标,函数中保存的是Handle),
Projectile,(投射物单位,在函数里创建的,类型通过 GetAim 函数的参数获得,演示里也是用Handle值传递的)
VX,(水平方向的速度,就是每间隔时间内投射物的移动距离,其值是投射速率这个系数乘以移动间隔时间)
b,(Getb获得的, b=2*[(K*L-H0)+√((H0-K*L)*(H1-K*L)) ] 其中√代表平方根)
√a,(Geta获得的,a=b2/4/(H0-K*L) ,b用Getb获得)
X,(目标X轴坐标,用于判断目标是否移动)
Y,(同X,不过是Y轴的)
H0,(投射物的初始高度)
T,(执行次数,用于计算的,每次循环要+1)
因为不是成品,所以还是仔细说明下。
特别要提到的是
我并没有让投射物创建在攻击单位头上,而是向着目标移动一个移动间隔(VX),这是因为感觉这样效果真实。
MoveProjectileA,MoveProjectileB是两个投射物运行方式A是目标不移动的轨迹,B是移动后的,具体请自己看真实投射物曲线吧(下载 投射物.w3x (18 K) 下载次数:1 )。 调用MoveProjectileB时,你只要将VX,Aim和Projectile传递过去即可。
MoveProjectileB的调用在MoveProjectileA中(函数上面有注释),无论哪种方式,当命中目标(判断目标和投射物之间的距离小于VX)后,需要运行其他函数,请插入函数中相关注释的部分 。
演示采用的方法是不考虑地面的,也就是未曾考虑地面不平的问题。,如果诸位需要考虑,可以将H0和H1(目标高度)都加上对应点的GetLocationZ。设置投射物高度时要减去 GetLocationZ。另外还有判断计算出来的高度是否高于地面,如果高于地面,请将投射物隐藏或替换,取消投射物模型,这样更真实些。(正常地图不必考虑这些)
在
中调用即可。
关于目标不移动时投射物的曲线的方程,
还有个计算用的解释图:
如果有谁要完整能用的函数……
找小血要吧……
嘿嘿……
引用
函数是未完整的……
感觉还是很对不起大家……
恩恩……
于是躲起来……
也许会偶尔上来看看的……
|
评分
-
查看全部评分
|