小時候你們應該都玩過飛機大戰吧,這就是仿的一個飛機大戰,可是沒有寫的很全,只能玩一次,死掉以後須要刷新頁面玩第二次,話不說多,上代碼:javascript
初始頁面:html
整個的html代碼仍是不多,以下:java
<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>
困難點:數組
代碼的重點就是判斷飛機之間的距離從而來肯定是否碰撞到了,敵軍與子彈的距離判斷是否擊落敵軍app
上代碼:dom
//碰撞檢測 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 }
飛機的移動是用拖拽實現的,拖拽須要注意的一點就是不要把飛機拖出屏幕,須要有一個臨界值,如圖:動畫
代碼:url
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";
選擇的難度不一樣,子彈速度不一樣spa
附上所有代碼:
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版本,後期我會把功能完善下,加上計分等。
上述代碼有問題請各位大佬們指出,謝謝啦。若是以爲有意思的麻煩點個贊哦。