飞机大战小游戏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.οnmοusemοve=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.οnmοusemοve=null;
352             //停止创建子弹
353             clearInterval(oBox.timer);
354             //停止创建敌军
355             clearInterval(oBox.eTimer);
356         }
357     }();
358 
359 </script>
360 </body>
361 </html>

 

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

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

转载于:https://www.cnblogs.com/allenxia/p/9211122.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记一次Jquery获取值的典型错误

直接上代码&#xff1a; 代码很简单&#xff0c;通过Post的形式提交参数&#xff0c;但是发现提交的data总是空&#xff0c;昨晚有点纳闷&#xff0c;今天一看才发现。。。 获取值得时候的顺序有问题&#xff0c;获取值应该是在onclick事件中。 综上&#xff1a;写Jquery的时间…

Skype For Business 2015实战系列14:创建Office Web App服务器场

Skype For Business 2015实战系列14&#xff1a;创建Office Web App服务器场前面的操作中我们已经成功的安装了Office Web App Server&#xff0c;今天我们将创建Office Web App服务器场。具体步骤如下:配置证书&#xff1a;登陆到OWA服务器,打开服务器管理器&#xff0c;点击“…

SQL Server 2008 基础

SQL Server 2008 基础SQL流程TDS是一种协议&#xff0c;一系列描述两个计算机间如何传输数据的规则。象别的协议一样&#xff0c;它定义了传输信息的类型和他们传输的顺序。总之&#xff0c;协议描述了“线上的位”&#xff0c;即数据如何流动。表格数据流协议是建立在TCP/IP N…

如何通过Git GUI将自己本地的项目上传至Github

ithud是一个程序员以后成长都会使用到的&#xff0c;先不说很多优秀的开源框架都在这上面发布&#xff0c;光是用来管理自己的demo都已经让人感到很方便&#xff0c;用得也很顺畅。而真正让我下定决心使用github的原因是因为两次误操作&#xff0c;将自己所有的学习demo全都删除…

【JSP笔记】第三章 JSP内置对象【上】

2019独角兽企业重金招聘Python工程师标准>>> 1.内置对象简介&#xff1a;JSP内置对象是WEB容器创建的一组对象&#xff0c;不使用new关键就可以是用的对象。 <% out.println(123); %> 2.九大内置对象&#xff1a; outrequestresponsesessionapplication Page …

java 并发编程多线程_多线程(一)java并发编程基础知识

线程的应用如何应用多线程在 Java 中&#xff0c;有多种方式来实现多线程。继承 Thread 类、实现 Runnable 接口、使用 ExecutorService、Callable、Future 实现带返回结果的多线程。继承 Thread 类创建线程Thread 类本质上是实现了 Runnable 接口的一个实例&#xff0c;代表一…

Docker监控方案(TIG)的研究与实践之Influxdb

2019独角兽企业重金招聘Python工程师标准>>> 前言&#xff1a; Influxdb也是有influxdata公司(www.influxdata.com )开发的用于数据存储的时间序列数据库.可用于数据的时间排列。在整个TIG(Telegrafinfluxdbgrafana)方案中&#xff0c;influxdb可算作一个中间件&…

Java第三阶段学习(三、字符流、转换流)

一、字节流读取中文时出现的问题&#xff1a; 文件中有中文时&#xff0c;用字节流读取会出现乱码的问题&#xff0c;因为一个中文为两个字节。 二、字符编码表 编码表&#xff1a;其实就是生活中字符和计算机二进制的对应关系表。 1、ascii&#xff1a; 一个字节中的7位就可以…

windows下OpenSSL加密证书安装步骤与使用方法

OpenSSL加密证书一般用于签名认证&#xff0c;含私钥和公钥。在Linux系统中&#xff0c;OpenSSL一般是已经安装好了&#xff0c;可以直接使用。而在Windows系统中&#xff0c;是需要安装使用的。 最近在使用支付平台时&#xff0c;用到了OpenSSL&#xff0c;鉴于此分享给大家&a…

java源码影视源码搭建教程_新版千月影视app源码+搭建教程

使用notepad批量替换URL【http://】为你的域名(被替换的域名访问有成品不能发布 需要修改的到前台confing里面查询)&#xff0c;替换名称【鲸鹰影视】为你的应用名称&#xff1b;服务端&#xff1a;1.将替换好的后端源码打包上传至站点根目录后解压&#xff1b;2.配置网站伪静态…

Uboot USB模式(RK3288变砖头的解决办法)

RK3288启动后有三种模式&#xff0c;可以分别进行操作。 第一种是normal也就是正常的启动模式。这个模式无法刷固件。一般板子通电就是这个模式 第二种是loader模式。就是刷固件模式。这个模式可以刷各种image。按住recover按键再通电&#xff0c;通过uboot的检测进入这个模式 …

DEV GridView嵌套

/// <summary> /// 绑定主表和明显表到GridView /// </summary> /// <param name"machineProduct">主表</param> /// <param name"configureData">字表</param> private void Mas…

局域网大型文件分发的可能解决方案

客户原来的做法是把文件上传到服务器&#xff0c;然后后形成一个普通的HTTP地址下入网站后台系统&#xff0c;然后客户端用户看到后&#xff0c;则下载下来。但是随着文件越来越大&#xff0c;客户端下载量增加&#xff0c;在局域内网环境中这种文件分发方式的弊端立现。服务器…

一个Option请求引发的深度解析

在当前项目中&#xff0c;前端通过POST方式访问后端的REST接口时&#xff0c;发现两条请求记录&#xff0c;一条请求的Request Method为Options&#xff0c;另一条请求的Reuest Method为Post。想要解决这个疑惑还得从以下3个概念说起。 Http Options Method RFC2616标准&#x…

ionic+AnjularJs实现省市县三级联动效果

建议对ionic和AnjularJs有一定了解的人可以用到&#xff0c;很多时候我们要用到选择省份、城市、区县的功能&#xff0c;现在就跟着我来实现这个功能吧&#xff0c;用很少的代码&#xff08;我这里是根据客户的要求&#xff0c;只显示想要显示的部分省份和其相对应的城市、区县…

Confluence 6 附件存储文件系统的分级

从 Confluence 3.0 开始&#xff0c;附件的存储方式有了重大的改变和升级。如果你是从 Confluence 2.10 及其早期版本升级上来的&#xff0c;请参考 Upgrading Confluence 页面中推荐的升级路径&#xff0c;同时请阅读 Confluence 3.0 文档中 Hierarchical File System Attachm…

你不知道的JavaScript-0

【数组】 删除数组的几种方法&#xff1a; https://www.cnblogs.com/Joans/p/3981122.html http://www.cnblogs.com/qiantuwuliang/archive/2010/09/01/1814706.html 【数字转换】 parseInt(num, radix): 【宽松相等和严格相等】 允许在相等比较中进行强制类型转换&#xff0c…

真是,原来可以这样啊

一下午&#xff0c;解决了两个问题。。。。。 先列上这两个真是Bug的问题&#xff1a; 1、数据库有个表book&#xff0c;里面有个字段 create_time Datetime类型的字段&#xff0c;这个字段是 not null 的。下午下代码往数据库里插入数据时&#xff0c;总是提示&#xff0c;cre…

java运行时异常中文_JAVA——运行时异常(RuntimeException)

Exception中有一个特殊的子类异常RuntimeException运行时异常。如果在函数内抛出该异常&#xff0c;函数上可以不用声明&#xff0c;编译一样通过。如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过。之所以不用在函数上声明&#xff0c;是因为不需要让调用者处…

JavaOne 2016——首日亮点

今年&#xff0c;为期5天的JavaOne会议中&#xff0c;4个会场的议题都进行了直播&#xff0c;演讲稿也在播出之后一并提供。\\来自Terracotta公司EHCache团队的Henri Tremblay&#xff0c;做了主题为《学习Java 8&#xff1a;Lambda表达式和函数式编程&#xff08;Learn Java 8…