您好,登錄后才能下訂單哦!
小編給大家分享一下js如何實現坦克大戰游戲,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
具體內容如下
<!DOCTYPE html> <html> <head> <title>tank</title> <style type="text/css"> body { margin: 0px; padding: 0px; border: 0px; } .map { position: absolute; top: 30px; width: 390px; height: 390px; left: 50%; margin-left: -200px; border: 9px solid orange; background-color: #8B8989; } .mapchild { position: absolute; background-size: cover; } #ifo { position: absolute; top: 30px; width: 418px; height: 418px; left: 50%; margin-left: -200px; color: green; text-align: center; background-color: #FAEBD7; z-index: 10; } </style> </head> <body> <div id="ifo"> <h2 id="ifo_title"></h2> <h4>按鍵說明:</h4> T:開始游戲(游戲開始后無效)<br/> P:暫停游戲<br/> W、S、A、D:上、下、左、右<br/> ENTER:發射子彈<br/> </div> </body> <script type="text/javascript"> //常量及全局變量的定義-------------------------------------------- const TANK_W = 30; const TANK_H = 30; const MAP_W = TANK_W * 13; const MAP_H = TANK_H * 13; const BULLENT_W = 7.5; const BULLENT_H = 7.5; const WALL_W = 15; const WALL_H = 15; const BULLENT_FREQ = 30; const TANK_FREQ = 200; const TANK_STEP = 7.5; //當前文件同目錄 const IMG_PATH = "tankImage/"; const MUSIC_PATH = "tankMusic/"; // 87=W;83=S;65=A;68=D const KEYCODE_U = 87; const KEYCODE_D = 83; const KEYCODE_L = 65; const KEYCODE_R = 68; //坦克移動不響應時間 const NORESPONSEFIRETIME = 200; const NORESPONSETANKMOVETIME = TANK_FREQ + 100; //我方坦克開火、移動狀態 noresponseFire = false; noresponseTankMove = false; //游戲狀態 state = "READY"; //frequency頻率 //對象id var tank_id = 0; var bullent_id = 0; var wall_id = 0; //敵方坦克總數 var emTankNum = 20; var meTankNum = 3; //我方坦克對象 var mytank = null; var tankArray = new Array(); var bullentArray = new Array(); //因為功能性磚塊會與普通靜態磚塊重疊所以必須另外存儲 var functionWallArray = new Array(); //地圖width=390,地圖中最小的靜物wall寬度高度=15,所以數組的一維二維均為390/15=26 //先聲明一維 var noMoveArray = new Array(4); for (var i = 0; i < MAP_W / WALL_W; i++) { //一維長度 noMoveArray[i] = new Array(); //再聲明二維 for (var j = 0; j < MAP_H / WALL_H; j++) { //二維長度 noMoveArray[i][j] = null; } } //常量及全局變量完-------------------------------------------------------------------------------- //對象的定義------------------------------------------------------------------------------------- //坦克對象 tank = function(selfType, x, y, belongs, dir) { //共有屬性 this.id = "tank_" + tank_id++; this.type = "tank"; //selfType可取1、2、3表示一類坦克,二類坦克,三類坦克 this.selfType = selfType; this.x = x; this.y = y; this.belongs = belongs; this.dir = dir; this.width = TANK_W; this.height = TANK_H; this.life = this.selfType; //因為坦克的img與方向有關,每一次改變dir都會影響img,所以設置一個對象函數用于獲取 this.getImg = function() { return img = this.belongs + "Tank" + this.selfType + this.dir; } //敵方坦克的自移動函數的setInterval的值t this.t; createDOM(this.id, this.width, this.height, this.x, this.y, this.getImg(), 2); //把生成的坦克對象存入移動對象數組 tankArray.push(this); if (belongs == "me") { mytank = this; meTankNum--; } //敵方坦克調用自移動函數 if (this.belongs == "em") { emTankNum--; //檢測是否需要生成功能磚塊 createFunctionWall(); autoMove(this); } } //子彈對象 bullent = function(selfType, x, y, belongs, dir) { //播放發射子彈音樂 playMusic("fire"); //共有屬性 this.id = "bullent_" + bullent_id++; this.type = "bullent"; this.selfType = selfType; this.x = x; this.y = y; this.belongs = belongs; this.dir = dir; this.width = BULLENT_W; this.height = BULLENT_H; //為了與坦克的img保持一致,同樣設置一個對象函數用于獲取 this.getImg = function() { return img = this.type; } //子彈與敵方坦克特有屬性,自移動的定時器 this.t; createDOM(this.id, this.width, this.height, this.x, this.y, this.getImg(), 1); //把生成的子彈對象存入移動對象數組 bullentArray.push(this); autoMove(this); } //墻對象 wall = function(selfType, x, y, belongs) { //共有屬性 this.id = "wall_" + wall_id++; this.type = "wall"; //wall、steel、star、timer分別表示普通磚塊、子彈不可打破磚塊、我方老巢、定時器 this.selfType = selfType; this.x = x; this.y = y; //belongs取值home、ordinary、function分別表示老巢的磚塊、一般磚塊、功能性磚塊 this.belongs = belongs; this.width; this.height; if (this.selfType == "star") { //設置全局變量star star = this; this.width = TANK_W; this.height = TANK_H; } else if (this.selfType != "star") { this.width = WALL_W; this.height = WALL_H; } //為了與坦克的img保持一致,同樣設置一個對象函數用于獲取 this.getImg = function() { return img = this.selfType; } var zIndex = belongs == "function" ? 3 : 2; createDOM(this.id, this.width, this.height, this.x, this.y, this.getImg(), zIndex); // if(n==13)console.log(this) //地圖中所有的靜物都是wall類型的,分為長寬15的wall、steel和長寬30的star;我們只需要存儲15規格的,star只有一個不需要存儲 if (this.belongs != "function") { noMoveArray[x / 15][y / 15] = this; } else { functionWallArray.push(this); } } //對象的定義完------------------------------------------------------------------------------------ //DOM對象創建與顯示------------------------------------------------------------------------------- //總體說明:1、為了便于計算所有對象的width、height、x、y均不帶px單位 // 創建DOM對象函數 function createDOM(id, width, height, x, y, img, zIndex) { var map = document.getElementById("map"); var it = document.createElement("div"); it.id = id; it.style.zIndex = zIndex; map.appendChild(it); showDOM(id, width, height, x, y, img); } //刪除DOM對象函數 function delDOM(id) { var it = document.getElementById(id); map.removeChild(it); } //展示函數,根據obj的屬性刷新對應的DOM function showDOM(id, width, height, x, y, img) { var it = document.getElementById(id); it.className = "mapchild"; it.style.cssText = "width:" + width + "px;height:" + height + "px;left:" + x + "px;top:" + y + "px;background-image:url('" + IMG_PATH + img + ".gif');"; } //DOM對象創建與顯示完------------------------------------------------------------------------------- //對象的創建與銷毀函數群----------------------------------------------------------------------------- //創建坦克函數 //因為坦克出現有一個動畫,不能直接new tank生成 //new tank(3,15 * 8,15 * 24,"me","U") function createTank(selfType, belongs, x, y) { //先讓創建動畫顯示 var emTank_x1 = 0 , emTank_x2 = 180; emTank_x3 = 360; var emTank_y = 0; var meTank_x = 15 * 8; var meTank_y = 15 * 24; //因為創建動畫顯示3s+銷毀1s,所以需要在4s后創建坦克 //這里需要對出生的位置進行檢測,防止坦克重疊 if (belongs == "me" && meTankNum != 0) { animation("born", 15 * 8, 15 * 24); //我方坦克顯示位置固定 setTimeout(function() { var mytank = new tank(3,15 * 8,15 * 24,"me","U"); flickerObj(mytank.id); }, 4500); } if (belongs == "em" && emTankNum != 0) { animation("born", x, y); //我方坦克顯示位置固定 setTimeout(function() { var emtank = new tank(1,x,y,"em","U"); flickerObj(emtank.id); }, 4500); } //判斷指定位置是否有坦克 function isThereHaveTank(x, y) { if (tankArray.length == 0) { return false; } for (var i = 0; i < tankArray.length; i++) { return tankArray[i].x == x && tankArray[i].y == y; } } } //發射子彈函數 //根據發射子彈坦克位置和方向,生成一個子彈 function createBullent(obj) { var x, y; switch (obj.dir) { case "U": x = obj.x + 0.5 * obj.width - 0.5 * BULLENT_W; y = obj.y; break; case "D": x = obj.x + 0.5 * obj.width - 0.5 * BULLENT_W; y = obj.y + obj.height - BULLENT_H; break; case "L": x = obj.x; y = obj.y + 0.5 * obj.height - 0.5 * BULLENT_H; break; case "R": x = obj.x + obj.width - BULLENT_W; y = obj.y + 0.5 * obj.height - 0.5 * BULLENT_H; break; } new bullent("speed",x,y,obj.belongs,obj.dir); } //刪除對象函數 //在html中刪除元素,并將數組中的值賦值為null function delObj(obj) { if (obj.t != undefined) { clearInterval(obj.t); } switch (obj.type) { case "bullent": delDOM(obj.id); bullentArray.splice(bullentArray.indexOf(obj), 1); break; case "tank": if (--obj.life == 0) { switch (obj.belongs) { case "me": meTankNum == 0 ? gameOver() : createTank(3, null, null, "me", null); ;break; case "em": console.log("敵方坦克=" + emTankNum) if (emTankNum == 0) { console.log("victory"); } ;break; } //調用銷毀坦克動畫 animation("blast", obj.x, obj.y); delDOM(obj.id); delete tankArray[tankArray.indexOf(obj)]; if (obj.belongs == "me") { mytank = null; gameOver(); } //obj.life!=0 } else { obj.selfType = obj.life; showDOM(obj.id, obj.width, obj.height, obj.x, obj.y, obj.getImg()); } ;break; case "wall": if (obj.selfType == "star") { img = "destory"; showDOM(obj.id, obj.width, obj.height, obj.x, obj.y, img); gameOver(); } else if (obj.belongs == "function") { delDOM(obj.id); functionWallArray.splice(bullentArray.indexOf(obj), 1); } else { delDOM(obj.id); noMoveArray[obj.x / 15][obj.y / 15] = null; } ;break; } } //對象的創建與銷毀函數群完--------------------------------------------------------------------------- //碰撞檢測與處理------------------------------------------------------------------------------------ //獲取可能碰撞的靜態物體函數 //在存儲靜物的時候使用二維數組相當于將地圖畫成間距15的小格子,所有的靜物均在小格子中,所以給定一個物體就可以得到包圍它一圈的小格子; //這比遍歷整個noMoveArray來的快的多 function getPossibleCollisionObj(obj) { var PossibleCollisionObjArray = new Array(); var largeWidth = WALL_W; var largeHeight = WALL_H; var x_l = obj.x - largeWidth; var x_r = obj.x + largeWidth + obj.width; var y_u = obj.y - largeHeight; var y_d = obj.y + largeHeight + obj.height; //計算出的左側、右側、上下側均不能出地圖 if (x_l < 0) x_l = 0; if (x_r > MAP_W) x_r = MAP_W; if (y_u < 0) y_u = 0; if (y_d > MAP_H) y_d = MAP_H; for (var i = Math.floor(x_l / largeWidth); i < Math.floor(x_r / largeWidth); i++) { for (var j = Math.floor(y_u / largeHeight); j < Math.floor(y_d / largeHeight); j++) { if (noMoveArray[i][j] != null) { PossibleCollisionObjArray.push(noMoveArray[i][j]); } } } //console.log(PossibleCollisionObjArray); return PossibleCollisionObjArray; } //碰撞檢測及處理函數 function collision(obj) { //collresult有三個值,MOVE、DELETE、NOMOVE;move表示檢測后的處理結果是繼續移動(即使碰上了,有些也不需要處理),DELETE表示刪除自身 //因為碰撞檢測只存在與移動物體,而移動函數需要碰撞檢測給出是否移動的結果,所以不能在碰撞處理中直接刪除被檢測物體 var collresult = "MOVE"; //單獨檢測是否碰撞老巢 //collresult = isCollision(obj, star) ? gameOver():"MOVE"; //檢測功能性磚塊 for (var i = 0; i < functionWallArray.length; i++) { if (functionWallArray[i] != null && isCollision(obj, functionWallArray[i])) { collresult = delColl(obj, functionWallArray[i]); } } //檢測所有的靜物;采用的是遍歷所有靜物 // for (var i = 0; i < noMoveArray.length; i++) { // for (var j = 0; j < noMoveArray[i].length; j++) { // if (noMoveArray[i][j] != null && isCollision(obj, noMoveArray[i][j])) { // collresult = delColl(obj, noMoveArray[i][j]); // } // } // } //檢測所有的靜物;采用的是遍歷可能相撞的靜物 var PossibleCollisionObjArray = getPossibleCollisionObj(obj); for (var i = 0; i < PossibleCollisionObjArray.length; i++) { if (isCollision(obj, PossibleCollisionObjArray[i])) { collresult = delColl(obj, PossibleCollisionObjArray[i]); } } //檢測坦克 for (var i = 0; i < tankArray.length; i++) { //tankArray[i].id != obj.id 因為檢測的時候的對象是通過拷貝得到的,它與真正的坦克的id一樣 if (tankArray[i] != null && tankArray[i].id != obj.id && isCollision(obj, tankArray[i])) { collresult = delColl(obj, tankArray[i]); } } //檢測子彈 for (var i = 0; i < bullentArray.length; i++) { if (bullentArray[i].id != obj.id && isCollision(obj, bullentArray[i])) { collresult = delColl(obj, bullentArray[i]); } } return collresult; } //碰撞檢測 function isCollision(obj, obji) { var iscoll; //用x_l、x_r、y_u、y_d分別表示左右上下的值 var x_l = obj.x; var x_r = x_l + obj.width; var y_u = obj.y; var y_d = y_u + obj.height; var x_li = obji.x; var x_ri = x_li + obji.width; var y_ui = obji.y; var y_di = y_ui + obji.height; //分別不在被檢測物體的左右上下說明發生碰撞,開始處理(第一種檢測碰撞算法,考慮反面情況) if (!(x_r <= x_li | x_l >= x_ri | y_d <= y_ui | y_u >= y_di)) { //console.log(obj.id+"與"+obji.id+"相撞了") iscoll = true; } else { iscoll = false; } return iscoll; } //碰撞處理函數 function delColl(obj, obji) { var collresult; switch (obj.type) { case "bullent": switch (obji.type) { case "tank": switch (obj.belongs) { case "me": switch (obji.belongs) { case "me": collresult = "MOVE"; break; case "em": collresult = "DELETE"; playMusic("hit"); animation("blast", obji.x, obji.y); delObj(obji); break; } ;break; case "em": switch (obji.belongs) { case "me": collresult = "DELETE"; playMusic("hit"); delObj(obji); break; case "em": collresult = "MOVE"; break; } ;break; } break; case "wall": switch (obji.selfType) { case "steel": collresult = "DELETE"; playMusic("hit"); break; case "wall": collresult = "DELETE"; playMusic("hit"); delObj(obji); break; case "star": collresult = "DELETE"; playMusic("hit"); delObj(obji); break; } ;break; case "bullent": switch (obji.belongs) { default: collresult = "MOVE"; break; } ;break; } ;break; case "tank": switch (obji.type) { case "tank": collresult = "NOMOVE"; break; case "wall": switch (obji.selfType) { case "wall": case "steel": collresult = "NOMOVE"; break; case "timer": collresult = "MOVE"; timer(); delObj(obji); break; case "bomb": collresult = "MOVE"; bomb(); delObj(obji); break; case "stronghome": collresult = "MOVE"; delObj(obji); StrongHome(); break; } ;break; case "bullent": switch (obj.belongs) { case "me": switch (obji.belongs) { case "me": collresult = "MOVE"; break; case "em": collresult = "DELETE"; break; } ;break; case "em": switch (obji.belongs) { case "me": collresult = "DELETE"; delObj(obji); break; case "em": collresult = "MOVE"; break; } ;break; } ;break; } ;break; } //console.log(obj.id+"與"+obji.id+"相撞了 "+"結果="+collresult); return collresult; } //碰撞檢測與處理完------------------------------------------------------------------------------------ //坦克與子彈移動函數----------------------------------------------------------------------------------- //移動函數 function move(obj, newDir) { var oldDir = obj.dir; obj.dir = newDir; if (state != "RUN") { // if(obj.type!="bullent"){ // return; // } return; } //新的方向與坦克原來方向相同就前進,否則改變坦克方向 if (obj.dir != oldDir && obj.type == "tank") { showDOM(obj.id, obj.width, obj.height, obj.x, obj.y, obj.getImg()); return; } var x = 0 , y = 0; var step = TANK_STEP; switch (obj.dir) { case "L": x = -step; break; case "R": x = step; break; case "U": y = -step; break; case "D": y = step; break; } //粗糙的深拷貝 var objString = JSON.stringify(obj); var checkObj = JSON.parse(objString); checkObj.x += x; checkObj.y += y; var collresult = collision(checkObj); //出界檢測; if (checkObj.x < 0 || (checkObj.x + checkObj.width) > MAP_W || checkObj.y < 0 || (checkObj.y + checkObj.height) > MAP_H) { if (checkObj.type == "tank") { showDOM(obj.id, obj.width, obj.height, obj.x, obj.y, obj.getImg()); return; } if (checkObj.type == "bullent") { delObj(obj); return; } //調用碰撞檢測及處理函數給出移動結果 } else if (collresult == "MOVE") { // if(obj.type=="tank"){ // movingFrame(obj,checkObj.x,checkObj.y) movingFrame(obj, checkObj.x, checkObj.y); // } // console.log("目標y="+checkTank.y) obj.x = checkObj.x; obj.y = checkObj.y; // if(obj.type=="bullent"){ // showDOM(obj.id, obj.width, obj.height, obj.x, obj.y, obj.getImg()); // } // showDOM(obj.id, obj.width, obj.height, obj.x, obj.y, obj.getImg()); } else if (collresult == "DELETE") { delObj(obj); } else if (collresult == "NOMOVE") { showDOM(obj.id, obj.width, obj.height, obj.x, obj.y, obj.getImg()); //如果是敵方坦克就給他一個相反的方向,防止它撞墻不回頭 if (obj.belongs == "em" && obj.type == "tank") {} return; } } //反方向函數 //返回一個與輸入方向相反的方向 function negativeDir(dir) { switch (dir) { case "L": return "R"; break; case "R": return "L"; break; case "U": return "D"; break; case "D": return "U"; break; } } //自動移動函數 //子彈坦克所特有 function autoMove(obj) { // console.log("游戲狀態="+state) var itFreq = BULLENT_FREQ; var itType = obj.type; var itId = obj.id; var itDir = obj.dir; if (obj.type == "tank") { itFreq = TANK_FREQ; } obj.t = setInterval(function() { if (itType == "tank") { var itObj = obj; var turn = randState(); if (turn == "Fire") { //console.log(obj.id+" "+obj.t) createBullent(itObj); return; } else if (turn == "none") { itDir = itObj.dir; } else { itDir = turn; } } move(obj, itDir); }, itFreq); } //簡化版移動框架 //為了使坦克的移動更平滑;使用移動框架的前提:必須在t時間內屏蔽坦克的任何方向改變 //因為js浮點數的處理很復雜,這里僅僅滿足x,y為7.5的倍數,step為7.5 function movingFrame(obj, x, y) { var objDom = document.getElementById(obj.id); var t = TANK_FREQ; var x1 = obj.x; var y1 = obj.y; var step_x = div(sub(x, x1), t / 10); var step_y = div(sub(y, y1), t / 10); var aaa = 1; var times = 1; var tank_t = setInterval(function() { if (times == t / 10) { clearInterval(tank_t); } times++; x1 = add(x1, step_x); y1 = add(y1, step_y); objDom.style.left = x1 + "px"; objDom.style.top = y1 + "px"; }, 10); //浮點數的加減乘除 function add(a, b) { var c, d, e; try { c = a.toString().split(".")[1].length; } catch (f) { c = 0; } try { d = b.toString().split(".")[1].length; } catch (f) { d = 0; } return e = Math.pow(10, Math.max(c, d)), (mul(a, e) + mul(b, e)) / e; } function sub(a, b) { var c, d, e; try { c = a.toString().split(".")[1].length; } catch (f) { c = 0; } try { d = b.toString().split(".")[1].length; } catch (f) { d = 0; } return e = Math.pow(10, Math.max(c, d)), (mul(a, e) - mul(b, e)) / e; } function mul(a, b) { var c = 0 , d = a.toString() , e = b.toString(); try { c += d.split(".")[1].length; } catch (f) {} try { c += e.split(".")[1].length; } catch (f) {} return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c); } function div(a, b) { var c, d, e = 0, f = 0; try { e = a.toString().split(".")[1].length; } catch (g) {} try { f = b.toString().split(".")[1].length; } catch (g) {} return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), mul(c / d, Math.pow(10, f - e)); } } //tank自動移動定時器的清除與重建函數 //itState表示清除、建立定時器 function objTimer(itState) { for (var i = 0; i < tankArray.length; i++) { if (tankArray[i] != null && tankArray[i].type == "tank") { if (itState == "stop" && tankArray[i].t != undefined) { clearInterval(tankArray[i].t); } if (itState == "run" && tankArray[i].belongs == "em") { autoMove(tankArray[i]); } } } } //坦克隨機狀態函數 //為自動移動的敵方坦克,返回一個方向LRUD或者Fire或者none,分別表示轉向、開火和什么也不做(繼續前行) function randState() { var z; //敵方坦克隨機發射子彈的概率是1/7 z = randomNum(10); switch (z) { case 1: return "L"; break; case 2: return "R"; break; case 3: return "D"; break; case 4: return "L"; break; //5表示發射子彈 case 5: return "Fire"; break; default: //none表示按照原來方向前進 return "none"; break; } function randomNum(scope) { return parseInt(Math.random() * scope); } } //坦克與子彈移動函數完-------------------------------------------------------------------------- //游戲狀態及提示函數群-------------------------------------------------------------------------- //開始游戲 function runGame(mapName) { //生成地圖 var map = document.createElement("div"); map.id = "map"; map.className = "map"; document.body.appendChild(map); state = "RUN"; ifo(state); mapName(); playMusic("start"); createTank(3, "me"); createTank(1, "em", 0, 0); createTank(1, "em", 180, 0); createTank(1, "em", 330, 0); } //游戲暫停函數 function stopGame() { if (state == "RUN") { state = "STOP"; ifo("STOP"); objTimer("stop"); } else if (state == "STOP") { state = "RUN"; ifo(state); objTimer("run"); } } //游戲結束函數 function gameOver() { state = "OVER"; //暫停子彈的所有定時器 objTimer("stop"); //alert("GAME OVER"); createDOM("over", 120, 67.5, (MAP_W - 120) / 2, (MAP_H - 67.5) / 2, "over"); flickerObj("over"); } //更改地圖 //保留的第二關、第三關 function changeMap() { //清除所有定時器及地圖 objTimer("stop"); var mapChildrenNodes = map.childNodes; document.body.removeChild(map); //執行runGame //runGame(map2); } //提示信息函數 //根據游戲狀態提示信息 function ifo(state) { var ifo = document.getElementById("ifo"); var ifo_title = document.getElementById("ifo_title"); switch (state) { case "READY": ifo_title.innerHTML = "坦克大戰"; break; case "RUN": ifo.style.display = "none"; break; case "STOP": ifo.style.display = "block"; ifo_title.innerHTML = "暫停"; ifo.style.backgroundColor = "transparent"; break; } } //游戲狀態及提示函數群完--------------------------------------------------------------------------------- //功能磚塊函數----------------------------------------------------------------------------------------- //生成功能性磚塊 function createFunctionWall() { if (emTankNum != 9 || emTankNum != 13 || emTankNum != 17) { return; } var selfType, x, y; switch (emTankNum) { case 9: selfType == "timer"; x = 15 * 18; y = 15 * 6; break; case 13: selfType == "stronghome"; x = 15 * 2; y = 15 * 18; break; case 17: selfType == "bomb"; x = 15 * 22; y = 15 * 17; break; } var it = new wall(selfType,x,y,"function"); flickerObj(it.id); //11秒后刪除它 setTimeout(function() { //10秒后刪除前閃爍功能磚,如果已經被吃了就取消閃爍 if (functionWallArray.indexOf(it) != -1) { flickerObj(it.id); } }, 10000); setTimeout(function() { //如果11秒刪除時發現功能磚已經被吃了就取消刪除 if (functionWallArray.indexOf(it) != -1) { delObj(it); } }, 11000); } //老巢steel磚塊函數 function StrongHome() { function changeHome(selfType) { for (var i = 0; i < noMoveArray.length; i++) { for (var j = 0; j < noMoveArray[i].length; j++) { if (noMoveArray[i][j] != null && noMoveArray[i][j].belongs == "home" && noMoveArray[i][j].selfType != "star") { noMoveArray[i][j].selfType = selfType; noMoveArray[i][j].img = noMoveArray[i][j].selfType; var obj = noMoveArray[i][j]; showDOM(obj.id, obj.width, obj.height, obj.x, obj.y, obj.getImg()); } } } } changeHome("steel"); setTimeout(function() { changeHome("wall"); }, 5000); } //爆炸磚塊函數 function bomb() { for (var i = 0; i < tankArray.length; i++) { objTimer("stop"); if (tankArray[i] != null && tankArray[i].belongs == "em") { //console.log(moveArray[i]) delObj(tankArray[i]); } } } //定時器磚塊函數 function timer() { //暫停坦克的所有定時器 objTimer("stop"); setTimeout(function() { objTimer("run"); }, 2000); } //功能磚塊函數完--------------------------------------------------------------------------------------- //特效函數群------------------------------------------------------------------------------------------ //音樂函數 function playMusic(src) { var audio = document.createElement("audio"); //var audio=document.createElement("<video controls muted autoplay >"); audio.src = MUSIC_PATH + src + ".wav"; //路徑 audio.play(); } //閃爍函數 function flickerObj(id, interval) { var it = document.getElementById(id); for (let i = 1; i <= 3; i++) { setTimeout(function() { var display = i % 2 == 0 ? "none" : "block"; it.style.display = display; //it.style.display="none"; }, (interval / 3) * i); } } //創建坦克/坦克爆炸動畫函數 //animationType可取born、blast分別表示坦克出生以及子彈爆炸 function animation(animationType, x, y) { //這里給動畫所用原子設置一個隨機數id,防止兩幅動畫使用id一樣造成只有一幅動畫的情況 //這樣仍可能使用一副動畫,不過可能為4/1000 animationTypeid = Math.random() * 1000; var id = animationType + animationTypeid; //顯示次數 var times = animationType == "born" ? 3 : 1; //顯示頻率 var fre = animationType == "born" ? 1000 : 300; // var width = animationType == "born" ? TANK_W : BULLENT_W; // var height = animationType == "born" ? TANK_H : BULLENT_H; var width = TANK_W; var height = TANK_H; //創建動畫原子并閃爍 for (let i = 1; i <= times; i++) { setTimeout(function() { createDOM(id + i, width, height, x, y, animationType + i); flickerObj(id + i, fre / times); }, fre * i); } //閃爍完畢刪除閃爍原子 setTimeout(function() { for (let i = 1; i <= times; i++) { delDOM(id + i); } }, fre * (times + 1)); } //特效函數群完-------------------------------------------------------------------------------------- //坦克大戰主邏輯----------------------------------------------------------------------------------- ifo("READY"); //坦克大戰主邏輯完--------------------------------------------------------------------------------- //鍵盤監聽及觸發處理開始------------------------------------------------------------------------------ noresponseFire = false; noresponseTankMove = false; document.onkeydown = function(event) { //如果游戲狀態為結束就屏蔽所有按鍵 if (state == "OVER") { return; } var myTank = tankArray[0]; var newDir; // 87=W;83=S;65=A;68=D code = event.keyCode; //可以通過在此輸出code檢測鍵盤的鍵值碼 // console.log(code) if (code == 65 && state == "RUN" && mytank != null && noresponseTankMove == false) { setNOresponse("TankMove", NORESPONSEFIRETIME); newDir = "L"; } else if (code == 87 && state == "RUN" && mytank != null && noresponseTankMove == false) { console.log(noresponseTankMove) setNOresponse("TankMove", NORESPONSEFIRETIME); newDir = "U"; } else if (code == 68 && state == "RUN" && mytank != null && noresponseTankMove == false) { setNOresponse("TankMove", NORESPONSEFIRETIME); newDir = "R"; } else if (code == 83 && state == "RUN" && mytank != null && noresponseTankMove == false) { setNOresponse("TankMove", NORESPONSEFIRETIME); newDir = "D"; //T 84 開始游戲 } else if (code == 84 && state == "READY") { runGame(map1); return; //發射子彈 Enter 13 } else if (code == 13 && state == "RUN" && mytank != null && noresponseFire == false) { //按鍵屏蔽,一定時間內發射子彈無效 createBullent(myTank); noresponseFire = true; //屏蔽P鍵300ms setTimeout(function() { noresponseFire = false; }, NORESPONSEFIRETIME); return; //屏蔽其他無關按鍵 //P 80表示暫停 } else if (code == 80 && (state == "RUN" || state == "STOP")) { stopGame(); return; //屏蔽其他無關按鍵 } else { return; } move(myTank, newDir); } function setNOresponse(noresponseState, t) { if (noresponseState == "TankMove") { noresponseTankMove = true; //屏蔽P鍵300ms setTimeout(function() { noresponseTankMove = false; }, t); } } //鍵盤監聽及觸發處理完------------------------------------------------------------------------------ //地圖1------------------------------------------------------------------------------------------ var map1 = function() { //老巢 new wall("star",15 * 12,15 * 24,"home"); new wall("wall",15 * 11,15 * 25,"home"); new wall("wall",15 * 11,15 * 24,"home"); new wall("wall",15 * 11,15 * 23,"home"); new wall("wall",15 * 12,15 * 23,"home"); new wall("wall",15 * 13,15 * 23,"home"); new wall("wall",15 * 14,15 * 25,"home"); new wall("wall",15 * 14,15 * 24,"home"); new wall("wall",15 * 14,15 * 23,"home"); // 老巢完畢 //所有普通wall for (var i = 1; i <= 11; i += 2) { for (var j = 2; j < 24; j++) { if (j >= 10 && j < 14) { continue; } if (i == 5 || i == 7) { if (j > 8 && j <= 11) continue; if (j > 20) continue; } else { if (j >= 14 && j < 16) { continue; } } new wall("wall",15 * 2 * i,15 * j,"ordinary"); new wall("wall",15 * 2 * i + 15,15 * j,"ordinary"); } } for (var i = 0; i < 6; i++) { for (var j = 0; j < 2; j++) { new wall("wall",15 * i + 15 * 10,15 * 11 + 15 * j,"ordinary"); if (i > 3) continue; new wall("wall",15 * i + 15 * 4,15 * 12 + 15 * j,"ordinary"); new wall("wall",15 * i + 15 * 18,15 * 12 + 15 * j,"ordinary"); } } new wall("wall",15 * 12,15 * 15,"ordinary"); new wall("wall",15 * 12,15 * 16,"ordinary"); new wall("wall",15 * 13,15 * 15,"ordinary"); new wall("wall",15 * 13,15 * 16,"ordinary"); //steel new wall("steel",15 * 0,15 * 13,"ordinary"); new wall("steel",15 * 1,15 * 13,"ordinary"); new wall("steel",15 * 24,15 * 13,"ordinary"); new wall("steel",15 * 25,15 * 13,"ordinary"); new wall("steel",15 * 12,15 * 6,"ordinary"); new wall("steel",15 * 12,15 * 7,"ordinary"); new wall("steel",15 * 13,15 * 6,"ordinary"); new wall("steel",15 * 13,15 * 7,"ordinary"); } //地圖1完--------------------------------------------------------- </script> </html>
以上是“js如何實現坦克大戰游戲”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。