岛友你还没有注册勒.注册可以注册可以查看更多资源哦~
您需要 登录 才可以下载或查看,没有账号?注册账号
×
首先,本文讨论的是很简单的算法。高手莫入。1 n& Q9 s& W+ L0 A
首先回忆几个三角函数sin,cos,tan(tg),arctan(arctg)4 E; V3 W) S6 l; f9 y* f
sin(x)—对边/斜边。在1,2项限为正,3,4项限为负# {3 E4 D7 _: ~) t0 p$ Q
cos(x)—邻边/斜边。在1,4项限为正,2,3项限为负
8 N4 |6 `$ _- ~4 L9 v& \9 ctan(x)—对边/邻边。在1,3项限为正,2,4项限为负+ P" v v: {$ m5 p" M! D
L1 b) l7 C1 j
考虑到游戏里面的坐标系如下所示:
' C) [" u! M9 ]2 d9 z假设敌人子弹的坐标为slug.x,slug.y,子弹的速度为slug.speed(全部是double型) w4 E6 i1 p1 d. J3 A$ c$ B
4 K/ z- U4 b% k3 G* W. J- I5 P
上面的三角形的斜边就代表子弹的速度,则子弹每次移动的时候座标的改变为:
% w: R9 p( W& h; L% w6 C% C4 Q
9 A# S3 P: F) M- _, P* U0 j! F( D slug.x += slug.speed * cos(theta);9 B7 n: G l9 a1 w
slug.y += slug.speed * sin(theta);
4 N' E1 z# ~5 a/ X$ S' q8 O# U3 Y3 R/ F/ T0 |) S8 h/ O& r4 a6 o
在敌人子弹向你发射过来的时候,首先要计算子弹位置与你所在的位置所夹的角度theta
6 y# }# }; b% J5 z
5 t5 i7 v2 N3 d" i& x2 h$ w简单计算就是:
, ]* W8 t$ j% B* l
0 g8 ^" }9 Y; T! k1 s* b8 u double deltax = player.x - slug.x; // 注意,、是以主角位置为起点 在上图中表示就是x1-x05 R, m Y9 p. Q
double deltay = player.y - slug.y; // y1-y0
$ q+ S1 x+ E. q5 Z1 s" X; ^1 L) @
) h: ?3 R' K: B' L! Y6 U9 ]为了防止在相除的时候分母为0,做一个判断,使分母近似为0,究竟是负的近似还是正的近似呢?这就需要比较子弹和你的Y坐标谁大谁小了。( ~, L. ?6 X/ F! _4 X
( z- J6 T2 x) i8 ^7 v
if( deltax == 0 )7 C; A* e9 S, k4 v3 X! t# [
{
2 S2 [+ r4 z: k* W if( player.y >= slug.y ) // 子弹需要下移9 S" g, E" M) w( o* @8 p5 ]
deltax = 0.0000001;
* E. u* z" I, U; q8 j# R, e& H else // 子弹需要上移4 V; Z+ Q' s% l( z
deltax = -0.0000001;
' r( U4 K8 _9 w, R9 T}" r+ R% i9 Q4 r( Z
$ E$ V/ O: U+ B0 ]' c3 P2 F同理,对deltay作判断
/ x; H( g& w' k# a# M" X" T' d2 `. C W5 ]0 A
if( deltay == 0 )% |. P/ H9 _0 E- H
{
( y3 x0 i6 E0 w9 Y if( player.x >= slug.x ) // 子弹需要右移
! r% n, C- z1 \$ U* d deltay = 0.0000001;3 g% u- M& V1 j/ w* C( i: p/ ~
else // 子弹需要左移 ]! {5 K0 z, V& r# _" x/ q( S
deltay = -0.0000001;
. O i* h- a" p9 V( s% w% o t* U}
" ]; Z4 N* ?( S" ]1 f! B2 l2 }4 ?, ]# y% h9 l
现在对角度所处的项限作判断
8 i: \# F* \, O
: `3 ~$ e/ [& b4 N$ F. `+ jif( deltax>0 && deltay>0 )9 }( v8 u9 ^( u9 _
angle = atan(fabs(deltay/deltax)); // 第一项限6 X8 c+ d1 j1 ]! u
" K6 x% m! q9 e. K3 Z# h+ j- f
else if( deltax0 && deltay0 )
6 G+ m0 G# `* O. F7 O/ W6 T% E! } angle = π-atan(fabs(deltay/deltax)) // 第二项限
; D: v4 H2 R, z0 j, `4 \3 y8 m1 _( J; {2 m9 s) ^& G. |$ G9 k
else if( deltax0 && deltay0 )
[" s/ b( Q0 {! ?7 n2 F0 t" W angle = π+atan(fabs(deltay/deltax)) // 第三项限0 `" B% z4 H: a: S% `% ]
# r# w% R5 O; W# n4 I+ |3 L7 Q
else
& g5 ?. x+ t$ V" I3 b" a: G angle = 2π-atan(fabs(deltay/deltax)) // 第四项限
/ v3 J' _ _- G' O% a7 N# ~# m4 ]- p7 A! N) ~) s0 u3 A- z8 E
其中π取3.1415926…………(呵呵,别忘记近似哦)
# z5 o: U/ Y+ D( h5 E$ n7 t好了,现在已经得到正确的方向了,可以计算子弹坐标了!
4 X% h' k, v2 H4 N$ G- V( j4 J* m: Z6 S( h
slug.x += slug.speed * cos(theta);
1 L% O+ S+ J. o- @- pslug.y += slug.speed * sin(theta);
# L0 W# ?9 a, P5 C3 m+ g, B6 K7 d+ Z: W8 e' V
这样,每次子弹移动之前做一下判断,重新计算角度7 e% f: h) i0 A- z h
很多玩过飞行射击类游戏的朋友都对跟踪导弹印象深刻,手中有这样一款武器常常能够战无不胜,但是敌人射出的导弹则可能成为玩家的噩梦。其实实现导弹跟踪的方法并不复杂,只需要一些简单的平面解析几何知识就可以做到。7 E) c# M. C& o+ n% e \2 R; Y
4 p" e+ {( L% f3 g# ^8 w4 ~- J6 ]算法分析
& I" H- `' [4 U# v3 e假设导弹旋转角速度为omega,运动速度为v。下图显示了导弹和目标在坐标轴中的初始状态。
4 \/ m; ~; G) y% I* T7 c I( x1 j/ m2 L9 i2 z4 \% m
初始时刻,目标与导弹的运动方向都是-Y,位置分别为(x1,y1),(x2,y2),连接导弹与目标的坐标,得到一条线段,该线段与-Y轴夹角为c;导弹与-Y方向的夹角为b,b是导弹已旋转的角度,此时为0;导弹方向与线段的夹角为a,a就是导弹还需要旋转的角度。此时:
2 T3 Z: @+ u4 H: G( S
, O: V) U+ i4 j6 bc=90-Math.atan2(y2-y1,x2-x1)*180/Math.PI;
$ {# m5 }# U8 x$ D0 s7 T$ ^b=0;
9 d- A( I' j" n% y; }a=c-b;
* G2 c$ k) _# P+ R/ w# x9 d" l7 U* w8 V
为了方便计算将c转换为360度以内的正值:) x4 q) \4 A6 g3 L6 I& ?2 y& J& e* u
+ E! m6 C% k* ~' a: Pc=(270+Math.atan2(y2-y1,x2-x1)*180/Math.PI)%360;
* B2 Z3 L# S( c. {
) j3 V9 [5 Z5 p9 i6 V注:非原创,搬砖 |