本帖最后由 aa77dd@163.com 于 2015-7-22 14:30 编辑
请将下面代码保存为 HTML 文件运行, 本代码在最新版 Chrome 和 Firefox 浏览器中测试通过, 未考虑低版本浏览器(特别是IE)的兼容性
演示地址 http://a7d.net46.net/MISSILE_php/MISSILE.php
全代码+资源 包 下载 http://pan.baidu.com/s/1dDsC2cT
- <!DOCTYPE html>
- <html>
- <head>
- <style>
- * {
- margin: 0;
- padding: 0;
- box-sizing: content-box;
- }
- body {
- background: url("Metro Bliss.jpg") no-repeat center center fixed;
- background-size: cover;
- overflow: hidden;
- }
- .enemy {
- display: block;
- position: absolute;
- left: -9999px;
- }
- .missile {
- display: block;
- position: absolute;
- /* background-color: red; */
- left: -9999px;
- }
- .missile>img {
- width: 7px;
- height: 44px;
- }
- audio,#btn {
- display: inline-block;
- bottom: 0px;
- position: absolute;
- width: 0px;
- }
- #btn {
- width: auto;
- cursor: pointer;
- color: white;
- }
- #btn:hover {
- background-color: rgba(192, 192, 192, 0.3);
- }
- </style>
- </head>
- <body>
- <div class=enemy>
- <img src="JetFighter.png">
- </div>
- <div class=missile>
- <img src="missile122x734.png">
- </div>
- <div id=btn onclick="$('audio').width(function (i, old) {return 300 - old});">
- 显/隐音效控件
- </div>
- <audio id=audio_hit controls>
- <source src="CruiseMissileDeath.wav" type="audio/wav">
- </audio>
- <audio id=audio_miss controls>
- <source src="JetFighterAttackMissile.wav" type="audio/wav">
- </audio>
- </body>
- </html>
- <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
- <!-- <script src="jquery-1.10.2.min.js"></script> -->
- <script>
- var vxe = [], vye = [], xe = [], ye = [];
- vxe[0] = 10, vye[0] = 0, xe[0] = 0, ye[0] = document.documentElement.clientHeight * .8;
- var vxm = [], vym = [], xm = [], ym = [];
- xm[0] = document.documentElement.clientWidth / 2, ym[0] = 10;
- var vwm = [], vm = [], am = [];
- vwm[0] = 2 * Math.PI / 72; // 导弹转向角速度极限 5deg
- vm[0] = 20; // 导弹飞行速度; vxm = vm * cos(am); vym = vm * sin(am);
- am[0] = Math.PI / 2; // 导弹飞行角度
- vxm[0] = vm[0] * Math.cos(am[0]);
- vym[0] = vm[0] * Math.sin(am[0]);
- var lastdistSQ = Array(1 + 1).join(Number.MAX_VALUE).split('');
- var xOffs_e = -$('.enemy').width() / 2, yOffs_e = -$('.enemy').height() / 2;
- var xOffs_m = -$('.missile').width() / 2, yOffs_m = -$('.missile').height() / 2;
- var audio_hit = $('#audio_hit')[0], audio_miss = $('#audio_miss')[0];
- $('audio').map(function (i) {
- $(this).css('left', (120 + i * 300) + 'px');
- $('audio')[i].muted = true;
- });
- window.setInterval('tick();', 1000 / 60);
- function tick() {
- $('.enemy').map(function (i) {
- $(this).css({'left': (xe[i] + xOffs_e) + 'px',
- 'bottom': (ye[i] + yOffs_e) + 'px',
- 'transform': 'scaleX(' + (vxe[i] >= 0 ? 1 : -1) + ')'
- });
- xe[i] += vxe[i];
- ye[i] += vye[i];
- if (xe[i] >= document.documentElement.clientWidth) {
- vxe[i] = -Math.abs(vxe[i]);
- }
- if (xe[i] <= 0) {
- vxe[i] = Math.abs(vxe[i]);
- }
- });
- $('.missile').map(function (i) {
- $(this).css({'left': (xm[i] + xOffs_m) + 'px', 'bottom': (ym[i] + yOffs_m) + 'px',
- 'transform': 'rotate(' + ((Math.PI / 2 - angle(vxm[i], vym[i])) * 180 / Math.PI) + 'deg)'
- });
- xm[i] += vxm[i];
- ym[i] += vym[i];
- // 导弹相对速度方向调整为与敌位置方向一致
- // 姿态角差 = 相对位置角 - 相对速度角
- // 姿态调整角方向 = |姿态角差| <= PI ? 姿态角差方向 : 姿态角差负方向
- // 姿态调整角模值 = min(|姿态角差|, 导弹转向角速度极限)
- var distSQ = Math.pow(xe[i] - xm[i], 2) + Math.pow(ye[i] - ym[i], 2);
- if (distSQ < 10 * 10) { // 目标距离在引爆半径内时引爆 引爆半径 10
- audio_miss.pause();
- audio_hit.load();
- audio_hit.play();
- } else if (distSQ < 40 * 40 && distSQ < lastdistSQ[i]) { // 逼近目标
- audio_hit.pause();
- audio_miss.load();
- audio_miss.play();
- }
- lastdistSQ[i] = distSQ;
- var a_pos = angle(xe[i] - xm[i], ye[i] - ym[i]);
- if (a_pos != null) {
- var a_vel = angle(vxm[i] - vxe[i], vym[i] - vye[i]); // 相对速度角
- if (a_vel == null) {
- // 导弹和目标等速度, 无法成功击中
- } else {
- var a_d = a_pos - a_vel;
- // 计算姿态调整角
- var a_adjust = (Math.abs(a_d) <= Math.PI ? (a_d >= 0 ? 1 : -1) : (a_d >= 0 ? -1 : 1))
- * Math.min(Math.abs(a_d), vwm[i]);
- am[i] += a_adjust;
- vxm[i] = vm[i] * Math.cos(am[i]);
- vym[i] = vm[i] * Math.sin(am[i]);
- }
- } else {
- // 拦截成功, 引爆
- }
- });
- }
- // 角度计算
- function angle(x, y) {
- var ang;
- return x == 0 ? (y == 0 ? null : (y > 0 ? Math.PI / 2 : -Math.PI / 2))
- : (ang = Math.atan(Math.abs(y / x)), x > 0 ?
- (y >= 0 ? ang : 2 * Math.PI - ang) :
- (y >= 0 ? Math.PI - ang : ang + Math.PI));
- }
- </script>
复制代码
|