岛友你还没有注册勒.注册可以注册可以查看更多资源哦~
您需要 登录 才可以下载或查看,没有账号?注册账号
×
首先,本文讨论的是很简单的算法。高手莫入。
2 u* j( H) `7 u. H首先回忆几个三角函数sin,cos,tan(tg),arctan(arctg)7 N6 ?/ M0 Y# h4 ?3 Z8 l: I
sin(x)—对边/斜边。在1,2项限为正,3,4项限为负, S, O4 m- y* N s, u
cos(x)—邻边/斜边。在1,4项限为正,2,3项限为负
; E: y, W: r/ K4 p6 `8 i$ t0 d$ B! Utan(x)—对边/邻边。在1,3项限为正,2,4项限为负6 L" P1 Y) O3 x% r) w2 R9 a# e
1 e! H$ A5 i& b" l考虑到游戏里面的坐标系如下所示:
& Q( H7 X& n% h" r8 L9 H. a假设敌人子弹的坐标为slug.x,slug.y,子弹的速度为slug.speed(全部是double型)
N% L" c' r- F& [. ~5 T; j9 K. {* D/ H
上面的三角形的斜边就代表子弹的速度,则子弹每次移动的时候座标的改变为:
0 b/ @9 N% G/ r C' H% Z/ @/ [4 h, g4 R
slug.x += slug.speed * cos(theta);9 |5 l9 ]9 N8 p; `' J
slug.y += slug.speed * sin(theta);
# n+ d- D% ~# X' b( _( m6 U
( r" o; A5 C1 K% b$ w3 r* Y' l在敌人子弹向你发射过来的时候,首先要计算子弹位置与你所在的位置所夹的角度theta8 |; F% Z6 a7 w. A- c- Z8 t3 b
. z! u. Z+ v3 R
简单计算就是:/ s& ^! U3 a% F; x! Z8 I j
/ f* E$ r% J% H
double deltax = player.x - slug.x; // 注意,、是以主角位置为起点 在上图中表示就是x1-x0
, H; F% w! b* V+ z7 D" [& P double deltay = player.y - slug.y; // y1-y0
6 y' _: ~0 Y/ c! c. g9 s# B! ~8 E, e& ^
为了防止在相除的时候分母为0,做一个判断,使分母近似为0,究竟是负的近似还是正的近似呢?这就需要比较子弹和你的Y坐标谁大谁小了。$ y' d7 a3 S/ K' s, o( M1 S2 _
& x- z, T( I" x5 z$ l* \if( deltax == 0 ) y; c' C6 r; o i, N) R
{
1 n. Q8 v; P( J3 R# z. `/ i if( player.y >= slug.y ) // 子弹需要下移
. e! e C* G% W, w3 B, _% ] deltax = 0.0000001;
6 ^7 B; o2 `! }( z# ?) P else // 子弹需要上移/ o# z/ o& d- x# E5 N$ x- a
deltax = -0.0000001;
$ U6 J; r5 ]* R2 O' g1 b: M& T0 `8 z}
0 u) _( \2 t/ L' w0 a( \
% u+ ~* t6 O6 D( I同理,对deltay作判断
( P, y8 o1 d- U% r8 ?9 J
# g1 c3 z% ?: _2 eif( deltay == 0 )( W$ _1 D- Q0 _' X: T! s
{' L# ? S# h6 k2 z& U, @ G6 r9 O
if( player.x >= slug.x ) // 子弹需要右移4 X- Q' P) L8 R+ K: ~
deltay = 0.0000001;
% ~2 k( ?5 L$ J& ~8 D. b else // 子弹需要左移' g* o5 U- ^1 ?
deltay = -0.0000001;, l4 {: `( O5 j7 `9 \4 [. M
}
$ ~: ]& ^# N' ?* X8 i' ?7 l9 T' T& X U9 Q0 |
现在对角度所处的项限作判断
3 P/ E: j) T3 p8 i( I) K3 ^# _3 @5 W& ^: ?& |
if( deltax>0 && deltay>0 )6 g/ L. Y. x2 y& t1 C9 B# w
angle = atan(fabs(deltay/deltax)); // 第一项限
' Z$ a1 ?. E/ ?& D0 O( Q4 T
" }' f1 X$ c7 E! L* e% J a eelse if( deltax0 && deltay0 )
* \( {0 Z( Y! X( g% l% p- |& X+ w, [ angle = π-atan(fabs(deltay/deltax)) // 第二项限7 I q% M) Z4 t& T9 J/ Y! v5 T
c" b: o5 U9 m8 U+ T7 Uelse if( deltax0 && deltay0 ) " {: L6 Z, P; q# X$ _8 i
angle = π+atan(fabs(deltay/deltax)) // 第三项限
5 u/ Q, ?; E9 v9 L Q
( x: T& u! C4 {# z+ g- g7 Nelse+ a) \+ h! d1 f) f% w
angle = 2π-atan(fabs(deltay/deltax)) // 第四项限
( c2 C& w9 o/ T5 N6 F. C6 O
8 r! I7 v2 @# h3 ?: f( G9 x其中π取3.1415926…………(呵呵,别忘记近似哦)' W! o% r( D1 j7 ^, I
好了,现在已经得到正确的方向了,可以计算子弹坐标了!
7 W5 ]+ u8 W q' k9 w3 ?
- ] J2 @' t; x7 a. n' tslug.x += slug.speed * cos(theta);
" i; y. V- u8 Y# Q+ kslug.y += slug.speed * sin(theta);
) [% j F9 R, b
, K1 z- O% o& S2 b% ?$ c这样,每次子弹移动之前做一下判断,重新计算角度
5 J8 d1 c1 ~6 `$ F很多玩过飞行射击类游戏的朋友都对跟踪导弹印象深刻,手中有这样一款武器常常能够战无不胜,但是敌人射出的导弹则可能成为玩家的噩梦。其实实现导弹跟踪的方法并不复杂,只需要一些简单的平面解析几何知识就可以做到。$ H- o9 w# _9 P6 m Y- X
9 F4 q, q% V1 [$ O& c0 U) v- c算法分析+ D" p2 N' H4 N3 `
假设导弹旋转角速度为omega,运动速度为v。下图显示了导弹和目标在坐标轴中的初始状态。
3 p( t/ [' E5 F& H5 W! v& I' B) a: ]
. ^6 K; s5 b0 T z {5 f初始时刻,目标与导弹的运动方向都是-Y,位置分别为(x1,y1),(x2,y2),连接导弹与目标的坐标,得到一条线段,该线段与-Y轴夹角为c;导弹与-Y方向的夹角为b,b是导弹已旋转的角度,此时为0;导弹方向与线段的夹角为a,a就是导弹还需要旋转的角度。此时:
/ K b; ?4 p7 ~9 U
: o9 m# M$ v. c) Y" Nc=90-Math.atan2(y2-y1,x2-x1)*180/Math.PI;
6 r+ \4 S" t9 [% Y* [3 Tb=0;
' w: @+ Y6 g3 O- na=c-b;
9 Y' v! {* P, p) U9 D6 y) }2 h+ m6 H! n# j: K
为了方便计算将c转换为360度以内的正值:
/ D% L9 n7 U* n4 c
% X6 K3 m2 R* r1 C0 M |/ w$ [c=(270+Math.atan2(y2-y1,x2-x1)*180/Math.PI)%360;: G$ V X! q6 j. N- C0 P! |
' W' e/ {' O0 ?0 r3 G& d6 M注:非原创,搬砖 |