岛友你还没有注册勒.注册可以注册可以查看更多资源哦~
您需要 登录 才可以下载或查看,没有账号?注册账号
×
首先,本文讨论的是很简单的算法。高手莫入。5 X0 K6 j ]# C- Y/ ^/ b" Y+ L1 @3 p
首先回忆几个三角函数sin,cos,tan(tg),arctan(arctg)
# q0 ^0 e- w/ L4 Bsin(x)—对边/斜边。在1,2项限为正,3,4项限为负* `2 \ k+ B8 J/ `8 O. C; i8 J
cos(x)—邻边/斜边。在1,4项限为正,2,3项限为负
# w, M. B. S+ B0 N& C) Ztan(x)—对边/邻边。在1,3项限为正,2,4项限为负% S' V1 a T4 \+ Y2 ^6 h" ^
& Q. A$ D; G! ~9 o! o
考虑到游戏里面的坐标系如下所示:
" F; Q# Q" m, y6 c4 |# t( b假设敌人子弹的坐标为slug.x,slug.y,子弹的速度为slug.speed(全部是double型)
3 _- y6 j! o+ l' K/ X* z W$ E8 k( E% ]5 [! [/ ]$ I
上面的三角形的斜边就代表子弹的速度,则子弹每次移动的时候座标的改变为:
" b( m7 K0 W' Q5 J# d2 S4 t4 k X) W0 L* z7 c
slug.x += slug.speed * cos(theta);
1 \3 N& _4 m( }# R" ~0 t/ c3 A slug.y += slug.speed * sin(theta);* G3 H3 o+ H# }; l- e+ u
$ O4 X4 g Q# |# ?
在敌人子弹向你发射过来的时候,首先要计算子弹位置与你所在的位置所夹的角度theta
' U0 f. X* O! ?! x7 g: i" b0 @# P3 c& s
简单计算就是:, n% l6 r4 r0 O6 Z* }$ g8 ?: {( e# H
5 \! Q. m" X1 }5 d% s% u+ n4 a) v- c
double deltax = player.x - slug.x; // 注意,、是以主角位置为起点 在上图中表示就是x1-x0+ f+ M; e' J# \( z8 T7 t) l
double deltay = player.y - slug.y; // y1-y0
1 r9 r' c, T& j* E9 _: _9 D- p/ W4 n4 P9 h% @% F4 X
为了防止在相除的时候分母为0,做一个判断,使分母近似为0,究竟是负的近似还是正的近似呢?这就需要比较子弹和你的Y坐标谁大谁小了。
" r) b9 t* M0 g8 O6 [
" L) z, ^% L" Y1 Q, @. w$ _if( deltax == 0 )! a1 x# s6 y9 m3 t2 ?! r
{* i9 H0 P9 E" l1 ^. C5 Z7 E
if( player.y >= slug.y ) // 子弹需要下移
- N' X* T& f, A& s0 f deltax = 0.0000001;: g' O( X, B) Y+ u
else // 子弹需要上移! S6 u8 n) i) ]" ^, i( C( J
deltax = -0.0000001;
" n+ L y' E$ A% T- J' C}% i; |1 m6 ^ V( I7 \- B
* y+ e& d9 u { d* S1 z
同理,对deltay作判断( Q" h7 Z! u/ |
9 a4 T, |" i- }' O
if( deltay == 0 ); @+ d7 `+ c6 M" i
{! V; Z' q- s$ [3 d
if( player.x >= slug.x ) // 子弹需要右移5 a4 B/ H j8 l) w) X
deltay = 0.0000001;2 Q/ [! c# _( y2 S. d5 d
else // 子弹需要左移/ |0 v" R6 h% l
deltay = -0.0000001;, p- G7 w$ p: k9 _2 F" r
}
. z- }) y) A) G6 R( w& V, S9 b- P! F- @( D8 y" W3 Z: N3 B! w1 H( V8 k
现在对角度所处的项限作判断
5 w+ @+ Q; e# ^! t# q" v! \" Z- _( ?: ?1 n" D3 U
if( deltax>0 && deltay>0 )* u* R) i+ _4 v! T( } z
angle = atan(fabs(deltay/deltax)); // 第一项限' x- A9 Z6 Z; d. X5 p0 l5 n# w. ^5 {
O7 T) |. u1 K9 y' x0 ~
else if( deltax0 && deltay0 )
3 \& Y( r5 S# L& Z2 z; n angle = π-atan(fabs(deltay/deltax)) // 第二项限
( w' x% K% v9 g3 ~/ s2 b U2 a* J1 @1 T8 n6 t
else if( deltax0 && deltay0 )
* E0 S9 \+ _3 K0 _# ]5 Z$ l angle = π+atan(fabs(deltay/deltax)) // 第三项限
, Z. s0 n0 q( z7 j2 o* d6 Y. A- V0 K1 f! g |3 U) W; _
else
& m) z8 ]) H) i+ A; Y, L$ { angle = 2π-atan(fabs(deltay/deltax)) // 第四项限2 h# D7 Z# c3 \ R9 \
- K- d1 L* c6 v j* s
其中π取3.1415926…………(呵呵,别忘记近似哦)
, `! j6 a O1 E" t/ C" f好了,现在已经得到正确的方向了,可以计算子弹坐标了!" m' O: V6 ]" x2 A7 r
9 r/ N' ^+ q; }$ r: `slug.x += slug.speed * cos(theta);
* t9 I: r4 X" Q) v& ~( Aslug.y += slug.speed * sin(theta);4 g4 f) P5 B9 H; G8 ?
- ?1 E+ e" d/ V% ?+ B/ x6 g
这样,每次子弹移动之前做一下判断,重新计算角度, e; n/ v2 H+ p4 {7 v: Z% o
很多玩过飞行射击类游戏的朋友都对跟踪导弹印象深刻,手中有这样一款武器常常能够战无不胜,但是敌人射出的导弹则可能成为玩家的噩梦。其实实现导弹跟踪的方法并不复杂,只需要一些简单的平面解析几何知识就可以做到。
6 ]3 C, z6 J) W* J; ~9 L2 |; s3 E' @: l' U7 j: `8 C
算法分析; X( _: i" {* ]2 \; e0 M. s% f
假设导弹旋转角速度为omega,运动速度为v。下图显示了导弹和目标在坐标轴中的初始状态。
- s, d# X- c; K& |8 \# q3 I7 J- d
( N: K$ q* t% H) q; V初始时刻,目标与导弹的运动方向都是-Y,位置分别为(x1,y1),(x2,y2),连接导弹与目标的坐标,得到一条线段,该线段与-Y轴夹角为c;导弹与-Y方向的夹角为b,b是导弹已旋转的角度,此时为0;导弹方向与线段的夹角为a,a就是导弹还需要旋转的角度。此时:
- y; B `/ U1 P; c& f4 Z8 a. h+ m q( Z* S T, c- o
c=90-Math.atan2(y2-y1,x2-x1)*180/Math.PI;
! y7 M8 f. f+ _$ L: Q' Ab=0;
+ c6 M- R( }5 e- t( o9 pa=c-b;2 w$ q2 s0 ?' g$ _
0 C! R% W( S& T/ ]- s3 z为了方便计算将c转换为360度以内的正值:* q+ \$ v+ e x$ ~; \
) Y$ q* \- ]7 `
c=(270+Math.atan2(y2-y1,x2-x1)*180/Math.PI)%360;
$ f) L4 Y: [4 n$ v: B
5 z7 h& D- X" L$ r注:非原创,搬砖 |