岛友你还没有注册勒.注册可以注册可以查看更多资源哦~
您需要 登录 才可以下载或查看,没有账号?注册账号
×
首先,本文讨论的是很简单的算法。高手莫入。1 m7 P9 A2 J; @) v
首先回忆几个三角函数sin,cos,tan(tg),arctan(arctg)
+ u# }- S& r$ y" e W/ ]- jsin(x)—对边/斜边。在1,2项限为正,3,4项限为负
( a& B( a$ ~( j! Scos(x)—邻边/斜边。在1,4项限为正,2,3项限为负
1 K" O! B, K1 p- q% ~; ^+ @7 vtan(x)—对边/邻边。在1,3项限为正,2,4项限为负
5 {) q2 G. e/ O3 H9 z1 @& [* ]. V
J1 y4 @' c! b. N! L考虑到游戏里面的坐标系如下所示:6 R) a2 j. m; }# j/ [2 |
假设敌人子弹的坐标为slug.x,slug.y,子弹的速度为slug.speed(全部是double型)7 ?3 R1 C. i1 ~5 H2 Y
, T$ O! t* m/ Z5 l) O3 l( y$ M
上面的三角形的斜边就代表子弹的速度,则子弹每次移动的时候座标的改变为: |' {4 W ~* |) H. G
9 `, `8 c. R. R) i, b$ l# B/ h }
slug.x += slug.speed * cos(theta);' G6 m0 n- V8 ^4 C! l+ w
slug.y += slug.speed * sin(theta);
) _; w8 P+ a' o5 `" ?3 e8 \3 i9 V6 \- {3 _+ L H7 c5 L4 e9 Y* d& E
在敌人子弹向你发射过来的时候,首先要计算子弹位置与你所在的位置所夹的角度theta
) X6 L( Q0 h3 P7 B) H5 |" w7 ]
0 C) ]! R3 ?# W: i2 I% ^: M. Q$ m简单计算就是:
4 M4 Y6 j& S! ~" f% h* R: ]* B$ s
/ s6 U1 }$ U5 \- b% i, z0 B double deltax = player.x - slug.x; // 注意,、是以主角位置为起点 在上图中表示就是x1-x0, L- q0 v& ]0 K! j8 k4 r4 \( C
double deltay = player.y - slug.y; // y1-y0
% h. y: \/ W0 E+ {+ [3 D# ~
3 I- I9 K: n. l1 s+ c/ Q为了防止在相除的时候分母为0,做一个判断,使分母近似为0,究竟是负的近似还是正的近似呢?这就需要比较子弹和你的Y坐标谁大谁小了。: y8 J6 v; ~2 E; U/ v6 R
. y* D2 Z) ?- V% N
if( deltax == 0 )
9 a! |; v8 O& G& P% l( w7 |& e{
( v- p0 [7 T6 R! P if( player.y >= slug.y ) // 子弹需要下移
6 j8 |" N: z& Q( N deltax = 0.0000001;
. Y+ O* e. `' W7 o9 ]* y else // 子弹需要上移7 `( ^" p# b' ~
deltax = -0.0000001;' Q" l# o* n( |0 S) Y
}
* X/ C' o3 r3 D0 ]! k, c# a: z+ ?% Y9 v$ e6 |: b# X" N( N
同理,对deltay作判断
0 j1 \6 W& L' j4 i2 ^7 m# K) ?' ?( m4 O. u
if( deltay == 0 ). J9 {9 f0 r8 ^/ ]7 O+ ~! m. F8 p
{7 [1 K! x% q9 g
if( player.x >= slug.x ) // 子弹需要右移" _9 \+ } C* ^3 [3 P4 o: |
deltay = 0.0000001;
; Q7 K/ b0 C" g+ ]0 ?8 A( |) v0 h else // 子弹需要左移- [6 d/ e4 u5 ^; I; l
deltay = -0.0000001;
/ @$ O& \6 L1 q9 [1 E+ \}
0 g: r" L$ c0 V, J2 ?8 [$ Q/ f) b" w3 x8 U. w
现在对角度所处的项限作判断
! ?: F `) x2 e4 B3 B. G
8 W" R1 v6 C# U" @- s% Zif( deltax>0 && deltay>0 ); k# f, H/ ^' V& Q0 m5 h
angle = atan(fabs(deltay/deltax)); // 第一项限
7 v$ }! {1 j9 I. h# I* |4 R
3 V) q7 `& D0 [! F. r" y4 ?else if( deltax0 && deltay0 )
, i, P. p% Z$ w angle = π-atan(fabs(deltay/deltax)) // 第二项限
! C" o+ Q0 x' o. S6 V9 n" L1 u' E: _+ L q
else if( deltax0 && deltay0 )
4 G& N6 f) B- z angle = π+atan(fabs(deltay/deltax)) // 第三项限- h& w: `: Z+ U9 _. t$ p1 h
5 N, V% x' G a- z, Q2 y* m4 @
else
* l# _2 z2 M! t* S* K7 Y angle = 2π-atan(fabs(deltay/deltax)) // 第四项限' t3 Y" Q7 g1 B# H% ]3 S
8 ~: Z8 ` A9 O- N+ h; C- R) X
其中π取3.1415926…………(呵呵,别忘记近似哦) }$ J+ Y6 r5 K( p; e
好了,现在已经得到正确的方向了,可以计算子弹坐标了!0 t3 O' O P0 I: {0 l0 o! J
4 E3 F. {5 m$ _; d" } Aslug.x += slug.speed * cos(theta);' H) f1 A$ @0 Y. L4 S. J; F p
slug.y += slug.speed * sin(theta);
# h+ [: J5 F3 I% ^) W) P2 _; F1 i& H, g: Z
这样,每次子弹移动之前做一下判断,重新计算角度
5 W6 j) o' b' b/ n9 h很多玩过飞行射击类游戏的朋友都对跟踪导弹印象深刻,手中有这样一款武器常常能够战无不胜,但是敌人射出的导弹则可能成为玩家的噩梦。其实实现导弹跟踪的方法并不复杂,只需要一些简单的平面解析几何知识就可以做到。. d. }$ {* w6 E7 r$ G2 U( z
]" z. Q# [* N; s算法分析0 }% ?/ p- l- p, F+ w
假设导弹旋转角速度为omega,运动速度为v。下图显示了导弹和目标在坐标轴中的初始状态。; b x2 x5 h4 T' d. Q
6 Z5 |- w' }% |1 D9 I% b% d$ a初始时刻,目标与导弹的运动方向都是-Y,位置分别为(x1,y1),(x2,y2),连接导弹与目标的坐标,得到一条线段,该线段与-Y轴夹角为c;导弹与-Y方向的夹角为b,b是导弹已旋转的角度,此时为0;导弹方向与线段的夹角为a,a就是导弹还需要旋转的角度。此时:. o5 b2 e- ?" Z3 z$ E& x
- w" l/ Y: `/ h" o7 Pc=90-Math.atan2(y2-y1,x2-x1)*180/Math.PI;9 [5 ~+ C; O& b2 U- J/ K P
b=0;
; f; e; b: m3 s2 u% P" X {a=c-b;) a" m2 F4 y: Q& X
6 j# W/ W0 ~ f9 I: ~5 K
为了方便计算将c转换为360度以内的正值:
s n/ {6 P9 y9 D, E2 X( O! J! P( G) y: e- g, o! ^
c=(270+Math.atan2(y2-y1,x2-x1)*180/Math.PI)%360;$ `. M7 f" \# i! U. x. [
' I: i" T1 h- @. m0 E h6 G注:非原创,搬砖 |