发现岛论坛

 找回密码
 注册账号
查看: 304|回复: 0

子弹追踪思路搬

[复制链接]
发表于 2021-10-18 02:48:26 来自手机 | 显示全部楼层 |阅读模式

岛友你还没有注册勒.注册可以注册可以查看更多资源哦~

您需要 登录 才可以下载或查看,没有账号?注册账号

x
首先,本文讨论的是很简单的算法。高手莫入。+ j% ]; S- W5 G
首先回忆几个三角函数sin,cos,tan(tg),arctan(arctg)
+ k, i. H& W' k; ~" U" P2 y" }sin(x)—对边/斜边。在1,2项限为正,3,4项限为负9 d8 o8 b4 `) b4 L" R+ x
cos(x)—邻边/斜边。在1,4项限为正,2,3项限为负
+ h) R. }& S: v* c, Vtan(x)—对边/邻边。在1,3项限为正,2,4项限为负
" t0 m' j- S1 S5 N2 z4 G; |5 w) {' I; n2 D8 S3 n* w# c' T
考虑到游戏里面的坐标系如下所示:- X9 \  H* y) S; v! v9 u
假设敌人子弹的坐标为slug.x,slug.y,子弹的速度为slug.speed(全部是double型)
' d7 Y$ {# _4 v7 x: x3 x4 X  r* F6 M, ^- ]# r3 ?/ O9 n! @" ?' y
上面的三角形的斜边就代表子弹的速度,则子弹每次移动的时候座标的改变为:+ [, p, H" t; R% G. F) p2 s3 t2 u
9 f" g% j8 W3 Q; s+ S! X
    slug.x += slug.speed * cos(theta);
7 ~% Q* w/ q, V6 n2 F& c) ]    slug.y += slug.speed * sin(theta);
, D1 F7 `% [1 N3 x* Z- C" A, `! c) T) o6 B+ D& A# ]5 o. `
在敌人子弹向你发射过来的时候,首先要计算子弹位置与你所在的位置所夹的角度theta
5 S' O, B4 e' {% P5 _, q% P4 r" f0 _. R1 {
简单计算就是:: l2 c& ~( l& t- x

, u3 ^! }6 g2 F' n    double deltax = player.x - slug.x; // 注意,、是以主角位置为起点 在上图中表示就是x1-x09 N4 P- h& V9 M8 X
    double deltay = player.y - slug.y; // y1-y0( q2 m( X$ }2 R6 w# R

# T4 N$ ?, Z  n" ]$ ^1 z9 @为了防止在相除的时候分母为0,做一个判断,使分母近似为0,究竟是负的近似还是正的近似呢?这就需要比较子弹和你的Y坐标谁大谁小了。
4 s, O9 y( Q! A  h5 a9 ?) J8 B5 G! |* v
) ]% R. H& ^) n1 K9 ]6 F3 n8 Lif( deltax == 0 )
% @5 [, G( x; e4 X{% K0 F* B7 O9 p# |* {; J+ r
    if( player.y >= slug.y )             // 子弹需要下移9 H3 Y" J7 G$ v/ n# n* L
        deltax = 0.0000001;/ _8 ]8 b8 A( R
    else                                 // 子弹需要上移
7 N, x0 C0 E( ^        deltax = -0.0000001;! A' u5 X8 R8 I! Y3 r+ m, T
}
' m, `( @+ v$ \. l) S" k- U$ {& B3 d
0 r: D! R, D, y% @( X同理,对deltay作判断
! ]9 `2 b+ _# Y3 J1 |+ Q" h1 ~. v) }! ^
if( deltay == 0 ); @( b$ i- r0 W5 g! s, ~4 N
{
* C* l0 ]5 n( i1 ~8 v    if( player.x >= slug.x )             // 子弹需要右移
! j' a1 I1 q8 w9 p! ?        deltay = 0.0000001;
1 ^+ |) q# ]# d1 Y( f( u    else                                 // 子弹需要左移
3 N; e, Z8 ?8 O3 Z& x        deltay = -0.0000001;
# r8 ]+ z( q) w" p}- Y# f& ]& ]  x7 b" T7 K

4 V- B4 J$ x+ Z1 ^/ N7 `现在对角度所处的项限作判断
2 T8 |5 V4 Y, x9 b
; p9 |* Z$ J5 E( O  Jif( deltax>0 && deltay>0 )4 P! |- u% `* K: o. }# D9 E) W
    angle = atan(fabs(deltay/deltax));           // 第一项限
- \2 F- u8 j- i7 [4 K6 t; j' m/ ]
1 \" L  P0 |. i& S7 Gelse if( deltax0 && deltay0 )
# {1 M0 |! Y, o( l( s) ~    angle = π-atan(fabs(deltay/deltax))          // 第二项限- w% a' K2 y. c0 x$ t) Z  z
4 _- N' ^% J+ X
else if( deltax0 && deltay0 )                    
1 ^) W3 W+ i* K4 i8 |    angle = π+atan(fabs(deltay/deltax))          // 第三项限& V+ x6 k- [* K/ }5 @

' \4 a* X4 P2 ^0 B5 ]# x' J1 yelse
+ p$ C. N- E" U& U, y; V1 j    angle = 2π-atan(fabs(deltay/deltax))         // 第四项限! Y* G, O% m8 }" V3 n; d, C5 \% V

* i0 J4 {8 j+ D  w其中π取3.1415926…………(呵呵,别忘记近似哦)7 C. ~( @8 V3 x& [+ ^2 y! O0 [7 g
好了,现在已经得到正确的方向了,可以计算子弹坐标了!. u* F- N" Q& @+ a2 p. E; d
+ }( P+ w6 X6 h9 R# Y% u# n7 C
slug.x += slug.speed * cos(theta);9 x3 y1 g% r2 p- p' \; A! H
slug.y += slug.speed * sin(theta);7 j1 s8 m1 ^4 w) l

% u3 d. n3 x# `& n' ?! R这样,每次子弹移动之前做一下判断,重新计算角度
) I9 i, O( O) j很多玩过飞行射击类游戏的朋友都对跟踪导弹印象深刻,手中有这样一款武器常常能够战无不胜,但是敌人射出的导弹则可能成为玩家的噩梦。其实实现导弹跟踪的方法并不复杂,只需要一些简单的平面解析几何知识就可以做到。7 f' R/ w# u3 e2 F

% {) G2 |: ?" s/ ?0 r0 W. F算法分析7 H9 I" Q" J& s
假设导弹旋转角速度为omega,运动速度为v。下图显示了导弹和目标在坐标轴中的初始状态。
- s( u( K& X' a6 A- r
# W) G/ U6 A1 c; C5 u4 f5 t. y初始时刻,目标与导弹的运动方向都是-Y,位置分别为(x1,y1),(x2,y2),连接导弹与目标的坐标,得到一条线段,该线段与-Y轴夹角为c;导弹与-Y方向的夹角为b,b是导弹已旋转的角度,此时为0;导弹方向与线段的夹角为a,a就是导弹还需要旋转的角度。此时:; V* M7 G3 V, f% \# i' N

7 i  j9 X% }/ I7 o' h8 Ac=90-Math.atan2(y2-y1,x2-x1)*180/Math.PI;
( l; `7 s! F* w$ Mb=0;0 b8 D6 D1 e( [" s' a' O
a=c-b;
7 F4 `' o) p+ V$ J
1 r" |7 t3 s; Y; ~# i为了方便计算将c转换为360度以内的正值:
6 ^+ t5 p8 P9 M% F# @6 B
7 {$ `( E- G$ D3 gc=(270+Math.atan2(y2-y1,x2-x1)*180/Math.PI)%360;% E6 c! ?: e  `6 o3 V" F6 J) y/ Z

5 }1 F1 i# }- }+ x注:非原创,搬砖
IMG_20211017_193657.jpg
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

QQ|手机版|小黑屋|精品辅助资源聚集地_Www.Faxdao.CoM辅助网 |网站地图|网站地图

GMT+8, 2022-7-3 00:50

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表