飞机大战小游戏1.0版本

小时候大家应该都玩过飞机大战吧,这就是仿的一个飞机大战,但是没有写的很全,只能玩一次,死掉之后需要刷新页面玩第二次,话不说多,上代码:


初始页面:

  

  整个的html代码还是很少,如下:

<div id="box">
    <!--存难度-->
    <div id="level">
        <h1>飞机大战 1.0</h1>
        <p>简单</p>
        <p>中等</p>
        <p>困难</p>
        <p style="color:#f00">WM 难度</p>
    </div>
    <!--放地图,每个难度的地图都是不同的-->
    <div id="map">
        <!--统一管理敌军-->
        <div id="BiuAll"></div>
    </div>
</div>

 困难点:

  代码的重点就是判断飞机之间的距离从而来确定是否碰撞到了,敌军与子弹的距离判断是否击落敌军

  

上代码:

    //碰撞检测
        function coll(obj1,obj2) {
            //物体 1 的边界
            var T1=obj1.offsetTop,
                B1=T1+obj1.clientHeight,
                L1=obj1.offsetLeft,
                R1=L1+obj1.clientWidth;
            //物体 2 的边界
            var T2=obj2.offsetTop,
                B2=T2+obj2.clientHeight,
                L2=obj2.offsetLeft,
                R2=L2+obj2.clientWidth;

            if(B1<T2 ||R1<L2 ||T1>B2 || L1>R2){
                //没有撞到的情况
                return false;
            }else{
                //撞到了的情况
                return true;
            }
        }  

子弹的碰撞检测需要倒着遍历,就像遍历数组去重一样,如果你从第一个开始遍历,若数组第一个就重复的话,删除第一个,原先的第二个会顶替到第一个的位置,会造成漏网之鱼。

  

 1                             //子弹碰撞 倒着遍历
 2                             for(var i=allBiu.length-1;i>=0;i--){
 3                                 var objBiu=allBiu[i];
 4                                 if(coll(oEnemy,objBiu)){
 5                                     boom(oEnemy.offsetLeft,oEnemy.offsetTop,0);
 6                                     BiuAll.removeChild(objBiu);
 7                                     oMap.removeChild(oEnemy);
 8                                     return;
 9                                 }
10                             }

飞机的移动是用拖拽实现的,拖拽需要注意的一点就是不要把飞机拖出屏幕,需要有一个临界值,如图:

      

  代码:

               left=Math.max(-oImg.clientWidth/2,left);
                left=Math.min(oBox.clientWidth-oImg.clientWidth/2,left);
                top=Math.min(oBox.clientHeight-oImg.clientHeight/2,top);
                top=Math.max(0,top);
                oImg.style.left=left+"px";
                oImg.style.top=top+"px";

  选择的难度不同,子弹速度不同

附上全部代码:

  1 <!DOCTYPE html>
  2 <html lang="en" onselectstart="return false">
  3 <head>
  4     <meta charset="UTF-8">
  5     <meta name="Author" content="">
  6     <title>demo1</title>
  7     <style>
  8         * {
  9             margin: 0;
 10             padding: 0;
 11             font-family: Microsoft YaHei, serif;
 12         }
 13 
 14         li {
 15             list-style: none;
 16         }
 17 
 18         body {
 19             overflow: hidden;
 20             user-select: none;
 21             -moz-user-select: none;
 22             -ms-user-select: none;
 23         }
 24 
 25         #box {
 26             position: relative;
 27             width: 512px;
 28             height: 768px;
 29             margin: 20px auto;
 30         }
 31 
 32         #map {
 33             position: absolute;
 34             top: 0;
 35             left: 0;
 36             width: 100%;
 37             height: 100%;
 38             background: url("../img/bg_1.jpg");
 39         }
 40 
 41         #level {
 42             position: absolute;
 43             top: 0;
 44             left: 0;
 45             width: 100%;
 46             height: 100%;
 47             z-index: 1;
 48         }
 49 
 50         #level.hid {
 51             display: none;
 52         }
 53 
 54         #level h1 {
 55             font-size: 40px;
 56             padding-top: 60px;
 57             padding-bottom: 30px;
 58             line-height: 60px;
 59             text-align: center;
 60             color: white;
 61         }
 62 
 63         #level p:hover {
 64             background: #ee4411;
 65             color: #fff;
 66         }
 67 
 68         #level p {
 69             margin: 100px auto;
 70             width: 200px;
 71             height: 35px;
 72             line-height: 35px;
 73             text-align: center;
 74             background: #fff;
 75             font-weight: bolder;
 76             cursor: pointer;
 77         }
 78 
 79         #map .plane ,#map .biu , #map .enemy,#map .boom1 ,#map .boom2{
 80             position: absolute;
 81         }
 82         #map .biu{
 83             z-index: 10;
 84         }
 85         #map .plane{
 86             z-index: 8;
 87         }
 88         #map .boom1{
 89             z-index: 7;
 90             animation: fade 1s 2;
 91             animation-fill-mode: forwards;
 92         }
 93         @keyframes  fade{
 94             from{opacity: 1}
 95             to{opacity: 0}
 96         }
 97         #map .enemy{
 98             z-index: 9;
 99         }
100         #map .boom2{
101             z-index: 11;
102             animation: bling 2s 1;
103         }
104         @keyframes bling {
105             0%{opacity: 1}
106             50%{opacity: 0}
107             75%{opacity: 1}
108             100%{opacity: 0}
109         }
110 
111     </style>
112 </head>
113 <body>
114 <div id="box">
115     <!--存难度-->
116     <div id="level">
117         <h1>飞机大战 1.0</h1>
118         <p>简单</p>
119         <p>中等</p>
120         <p>困难</p>
121         <p style="color:#f00">WM 难度</p>
122     </div>
123     <!--放地图,每个难度的地图都是不同的-->
124     <div id="map">
125         <!--统一管理敌军-->
126         <div id="BiuAll"></div>
127     </div>
128 </div>
129 <script>
130     ~function () {
131         //动画兼容
132         window.requestAnimationFrame=window.requestAnimationFrame  || function (fn) {
133           return  setTimeout(fn,1000/60)
134         };
135         window.cancelAnimationFrame= window.cancelAnimationFrame || clearTimeout;
136         //获取局部的全局变量
137         var oLevel = document.getElementById("level"),
138             BiuAll=document.getElementById("BiuAll"),
139             allBiu=BiuAll.children,
140             oBox = document.getElementById("box"),
141             oMap = document.getElementById("map"),
142             boxOffsetTop = oBox.offsetTop,
143             boxOffsetLeft = oBox.offsetLeft;
144 
145         //启动游戏
146         exe();
147 
148         //选择关卡 难度的点击事件
149         function exe() {
150             var aP = oLevel.getElementsByTagName("p");
151             for (var i = 0, len = aP.length; i < len; i++) {
152                 !function (i) {
153                     aP[i].onclick = function (e) {
154                         e = e || window.event;
155                         //第一个实参为关卡难度序号
156                         //第二个存储鼠标距离map边缘距离的jn
157                         startGame(i, {
158                             x: e.clientX - boxOffsetLeft,
159                             y: e.clientY - boxOffsetTop
160                         });
161                     }
162                 }(i);
163             }
164 
165 
166         }
167 
168         //开始游戏
169         function startGame(level, pos) {
170             //执行清理
171             clearMap();
172             //执行创建我军
173             var rImg=plane(level, pos);
174             //执行敌军
175             enemy(level, rImg);
176 
177 
178         }
179 
180         //隐藏与清理地图
181         function clearMap() {
182             //隐藏选择关卡的选择框
183             oLevel.classList.add("hid");
184         }
185 
186         //创建我军
187         function plane(level,pos) {
188             //创建飞机的我军图片
189             var oImg = new Image();
190             oImg.src = "../img/plane_0.png";
191             oImg.width = 70;
192             oImg.height = 70;
193             oImg.className = "plane";
194             oImg.style.left=pos.x-oImg.width/2+"px";
195             oImg.style.top=pos.y-oImg.height/2+"px";
196             oMap.appendChild(oImg);
197 
198 
199             //加入mousemove事件
200             document.onmousemove=function (e) {
201                 e = e || window.event;
202                 //获取飞机的实时坐标
203                 var left=e.clientX-boxOffsetLeft-oImg.width/2,
204                     top=e.clientY-boxOffsetTop-oImg.height/2;
205                 //控制飞机的边界值
206                 left=Math.max(-oImg.clientWidth/2,left);
207                 left=Math.min(oBox.clientWidth-oImg.clientWidth/2,left);
208                 top=Math.min(oBox.clientHeight-oImg.clientHeight/2,top);
209                 top=Math.max(0,top);
210                 oImg.style.left=left+"px";
211                 oImg.style.top=top+"px";
212 
213             }
214             //等级不同子弹速度不同
215             fire(oImg,level);
216             //返回出去便于敌军里面接收到这个函数
217             return oImg;
218         }
219         //我军子弹
220         function fire(oImg,level) {
221             //选择创建子弹的速率
222             var time=[100,200,200,20][level];
223             oBox.timer=setInterval(function () {
224                 //创建子弹
225                 var oBiu=new Image();
226                 oBiu.src="../img/fire.png";
227                 oBiu.width=30;
228                 oBiu.height=30;
229                 oBiu.className="biu";
230                 oBiu.style.left=oImg.offsetLeft+oImg.width/2-oBiu.width/2 +"px";
231                 oBiu.style.top=oImg.offsetTop-oBiu.height+5+"px";
232                 BiuAll.appendChild(oBiu);
233                 //子弹运动
234                 function move() {
235                     if(oBiu.parentNode){
236                         var top=oBiu.offsetTop-30;
237                         if(top<-oBiu.height){
238                             top=-oBiu.height
239                             BiuAll.removeChild(oBiu);
240                         }else{
241                             oBiu.style.top=top+"px";
242 
243                             requestAnimationFrame(move);
244                         }
245                     }
246                 }
247                 //用定时器把队列往后拖一下,让top不会重复计算一次
248                 setTimeout(function () {
249                     requestAnimationFrame(move)
250                 },20);
251 
252 
253             },time);
254         }
255         //创建敌军
256         function enemy(level,rImg) {
257             //敌军下落速度;
258             var speed=[5,6,8,10][level];
259             oBox.eTimer=setInterval(function () {
260                 //生成敌军
261                 var oEnemy=new Image();
262                 oEnemy.src="../img/enemy_small.png";
263                 oEnemy.className="enemy";
264                 oEnemy.width=54;
265                 oEnemy.height=40;
266                 oEnemy.style.left=Math.random()*oMap.clientWidth-oEnemy.width/2 +"px";
267                 oEnemy.style.top=-oEnemy.height+"px";
268                 oMap.appendChild(oEnemy);
269                 //敌方运动
270                 function move () {
271                     //检测下在不在页面中;
272                     if(oEnemy.parentNode){
273                         var top=oEnemy.offsetTop;
274                         top+=speed;
275                         if(top>=oMap.clientHeight){
276                             oMap.removeChild(oEnemy);
277                         }else{
278                             oEnemy.style.top=top+"px";
279                             //子弹碰撞 倒着遍历
280                             for(var i=allBiu.length-1;i>=0;i--){
281                                 var objBiu=allBiu[i];
282                                 if(coll(oEnemy,objBiu)){
283                                     boom(oEnemy.offsetLeft,oEnemy.offsetTop,0);
284                                     BiuAll.removeChild(objBiu);
285                                     oMap.removeChild(oEnemy);
286                                     return;
287                                 }
288                             }
289                             //我军碰撞检测
290                             if(rImg.parentNode&&coll(oEnemy,rImg)){
291                                 //敌军爆炸图
292                                 boom(oEnemy.offsetLeft,oEnemy.offsetTop,0);
293                                 //我军爆炸图
294                                 boom(rImg.offsetLeft,rImg.offsetTop,1);
295                                 //移除敌军 我军;
296                                 oMap.removeChild(oEnemy);
297                                 oMap.removeChild(rImg);
298                                 //游戏结束
299                                 gameover();
300                                 return;
301                             }
302                             requestAnimationFrame(move);
303                         }
304                     }
305 
306 
307                 }
308                 requestAnimationFrame(move)
309             },[350,250,120,80][level]);
310         }
311         //爆炸函数
312         function boom(l,t,i) {
313             var oBoom=new Image();
314                 oBoom.src="../img/"+["boom_small","plane_0"][i]+".png";
315                 oBoom.width=[54,70][i];
316                 oBoom.height=[40,70][i];
317                 oBoom.className=["boom1","boom2"][i];
318                 oBoom.style.left=l+"px";
319                 oBoom.style.top=t+"px";
320                 oMap.appendChild(oBoom);
321                 setTimeout(function () {
322                     oMap.removeChild(oBoom);
323                 },[1200,2500][i])
324         }
325 
326 
327         //碰撞检测
328         function coll(obj1,obj2) {
329             //物体 1 的边界
330             var T1=obj1.offsetTop,
331                 B1=T1+obj1.clientHeight,
332                 L1=obj1.offsetLeft,
333                 R1=L1+obj1.clientWidth;
334             //物体 2 的边界
335             var T2=obj2.offsetTop,
336                 B2=T2+obj2.clientHeight,
337                 L2=obj2.offsetLeft,
338                 R2=L2+obj2.clientWidth;
339 
340             if(B1<T2 ||R1<L2 ||T1>B2 || L1>R2){
341                 //没有撞到的情况
342                 return false;
343             }else{
344                 //撞到了的情况
345                 return true;
346             }
347         }
348         //游戏结束
349         function gameover() {
350             //清除移动事件
351             document.onmousemove=null;
352             //停止创建子弹
353             clearInterval(oBox.timer);
354             //停止创建敌军
355             clearInterval(oBox.eTimer);
356         }
357     }();
358 
359 </script>
360 </body>
361 </html>

这是1.0版本,后期我会把功能完善下,加上计分等。

上述代码有问题请各位大佬们指出,谢谢啦。如果觉得有意思的麻烦点个赞哦。

猜你喜欢

转载自www.cnblogs.com/allenxia/p/9211122.html