js實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲
本文實(shí)例為大家分享了js實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲的具體代碼,供大家參考,具體內(nèi)容如下
CSS部分的代碼:
<style> * { margin: 0px; padding: 0px; } canvas{ border: 1px solid #000; display: block; margin: auto; } </style>
JavaScript代碼:
<!-- 先創(chuàng)建一個(gè)畫(huà)布 --> <canvas id="canvas" width="480" height="640"></canvas> <script> var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); // 0游戲初始化 // 0.1定義游戲開(kāi)始的五個(gè)階段 var START = 0; var STARTING = 1; var RUNNING = 2; var PAUSE = 3; var GAMEOVER = 4; // 0.2 定義一個(gè)自己的狀態(tài),時(shí)刻去和上面的五個(gè)狀態(tài)作比較 // 0.3 頁(yè)面加載時(shí) var state = START; // 0.4 背景圖片的寬和高 var WIDTH = 480; var HEIGHT = 640; // 0.5 定義分?jǐn)?shù) var score = 0; // 0.6 定義生命條數(shù) var life = 3; // 1 游戲開(kāi)始前 // 1.1 加載背景圖片 // 1.1.1 背景圖片的對(duì)象 var bg = new Image();// 創(chuàng)建一個(gè)背景圖片 bg.src = "images/background.png"; // 1.1.2 背景圖片的數(shù)據(jù) var BG = { imgs: bg, width: 480, height: 852 } // 1.1.3 背景圖片的構(gòu)造函數(shù) function Bg(config) { this.imgs = config.imgs; this.width = config.width; this.height = config.height; // 繪制圖片的坐標(biāo)(兩張背景圖片進(jìn)行輪流滑動(dòng)) this.x1 = 0; this.y1 = 0; this.x2 = 0; this.y2 = -this.height; // 背景圖片繪制 this.paint = function () { context.drawImage(this.imgs, this.x1, this.y1); context.drawImage(this.imgs, this.x2, this.y2); } // 圖片的運(yùn)動(dòng) this.step = function () { this.y1++; this.y2++; // 判斷圖片的臨界點(diǎn) if (this.y1 == this.height) { this.y1 = -this.height; } if (this.y2 == this.height) { this.y2 = -this.height; } } } // 1.1.4創(chuàng)建對(duì)象 var sky = new Bg(BG); // console.log(sky); // 1.2 創(chuàng)建頁(yè)面加載時(shí)的飛機(jī)大戰(zhàn)圖片 var logo = new Image(); logo.src = "images/start.png"; // 2.游戲開(kāi)始前 // 2.1 開(kāi)始前動(dòng)畫(huà)的對(duì)象 var loadings = []; loadings[0] = new Image(); loadings[0].src = "images/game_loading1.png"; loadings[1] = new Image(); loadings[1].src = "images/game_loading2.png"; loadings[2] = new Image(); loadings[2].src = "images/game_loading3.png"; loadings[3] = new Image(); loadings[3].src = "images/game_loading4.png"; // 2.2 開(kāi)始前加載的動(dòng)畫(huà)圖片的數(shù)據(jù) var LOADINGS = { imgs: loadings, length: loadings.length, width: 186, height: 38 } // 2.3 開(kāi)始前動(dòng)畫(huà)的構(gòu)造函數(shù) function Loading(config) { this.imgs = config.imgs; this.length = config.length; this.width = config.width; this.height = config.height; // 定義一個(gè)索引 this.startIndex = 0; // 繪制 this.paint = function () { context.drawImage(this.imgs[this.startIndex], 0, HEIGHT - this.height); } // 定義一個(gè)速度 this.time = 0; this.step = function () { this.time++; if (this.time % 3 == 0) { // 頁(yè)面加載時(shí)下面小飛機(jī)運(yùn)行的速度 this.startIndex++; } // 當(dāng)動(dòng)畫(huà)運(yùn)行完成進(jìn)入下一個(gè)階段 if (this.startIndex == this.length) { state = RUNNING; } } } // 2.4創(chuàng)建對(duì)象 var loading = new Loading(LOADINGS); // 2.5綁定時(shí)間 canvas.onclick = function () { if (state == START) { state = STARTING; } } // 3.1.1游戲開(kāi)始時(shí)的圖片 var heros = []; heros[0] = new Image(); heros[0].src = "images/hero1.png"; heros[1] = new Image(); heros[1].src = "images/hero2.png"; heros[2] = new Image(); heros[2].src = "images/hero_blowup_n1.png"; heros[3] = new Image(); heros[3].src = "images/hero_blowup_n2.png"; heros[4] = new Image(); heros[4].src = "images/hero_blowup_n3.png"; heros[5] = new Image(); heros[5].src = "images/hero_blowup_n4.png"; // 3.1.2游戲開(kāi)始時(shí)加載數(shù)據(jù) var HEROS = { imgs: heros, length: heros.length, width: 99, height: 124, // 我方飛機(jī)有兩種狀態(tài),增加標(biāo)識(shí) frame: 2 } // 3.1.3我方飛機(jī)的構(gòu)造器 function Hero(config) { this.imgs = config.imgs; this.length = config.length; this.width = config.width; this.height = config.height; this.frame = config.frame; // 定義索引 this.startIndex = 0; // 繪制坐標(biāo) this.x = WIDTH / 2 - this.width / 2; this.y = HEIGHT - 150; // 增加標(biāo)識(shí)符 this.down = false; //表示一直沒(méi)有撞擊 // 增加標(biāo)識(shí)符 this.candel = false; //表示撞擊以后的動(dòng)畫(huà)是否運(yùn)行完成,完成以后的恢復(fù)運(yùn)行的狀態(tài) // 定義繪制方法 this.paint = function () { context.drawImage(this.imgs[this.startIndex], this.x, this.y) } // 定義運(yùn)動(dòng)的方法 this.step = function () { // 兩個(gè)狀態(tài) // 1.正常運(yùn)動(dòng)狀態(tài) // 2.碰撞以后的狀態(tài) if (!this.down) {//正常運(yùn)動(dòng)狀態(tài) // 沒(méi)有發(fā)生撞擊的時(shí)候 一直在0和1之間切換 this.startIndex++; this.startIndex = this.startIndex % 2; } else {//撞擊以后的狀態(tài) // 腳標(biāo)就要不停的加1,模擬出從碰撞到爆炸完成的動(dòng)畫(huà) this.startIndex++; // 判斷是否完成撞擊 if (this.startIndex == this.length) { life--//爆炸一次生命值減1; if (life == 0) { state = GAMEOVER; // 如果死了,動(dòng)畫(huà)保存最后一張爆破的照片 this.startIndex = this.length - 1; } else { hero = new Hero(HEROS); } } } } // 我方飛機(jī)增加射擊方法 this.time = 0; this.shoot = function () { this.time++; if (this.time % 2 == 0) { bullets.push(new Bullet(BULLET)); } } // 撞擊以后觸發(fā) this.bang = function () { this.down = true; } } // 3.1.4我方飛機(jī)的對(duì)象 var hero = new Hero(HEROS); // 3.1.5綁定鼠標(biāo)移動(dòng)事件 canvas.onmousemove = function (e) { if (state == RUNNING) { var x = e.offsetX; var y = e.offsetY; hero.x = x - hero.width / 2; hero.y = y - hero.height / 2; } } // 3.2 繪制子彈 // 3.2.1 圖片 var bullet = new Image(); bullet.src = "images/bullet1.png"; // 3.2.2數(shù)據(jù) var BULLET = { imgs: bullet, width: 9, height: 21 } // 3.2.3 子彈的構(gòu)造函數(shù) function Bullet(config) { this.imgs = config.imgs; this.width = config.width; this.height = config.height; // 子彈坐標(biāo) this.x = hero.x + hero.width / 2 - this.width / 2; this.y = hero.y - this.height; // 繪制 this.paint = function () { context.drawImage(this.imgs, this.x, this.y); } // 運(yùn)動(dòng) 往上運(yùn)動(dòng) this.step = function () { this.y -= 10; } this.candel = false;//表示撞擊以后的動(dòng)畫(huà)是否運(yùn)行完成,完成以后的恢復(fù)運(yùn)行的狀態(tài) this.bang = function () { this.candel = true; } } // 3.2.4 存放所有子彈 var bullets = []; // 3.2.5 繪制所有子彈 function bulletsPaint() { for (var i = 0; i < bullets.length; i++) { bullets[i].paint(); } } // 3.2.6 繪制所有子彈的運(yùn)動(dòng) function bulletsStep() { for (var i = 0; i < bullets.length; i++) { bullets[i].step(); } } // 3.2.7 刪除子彈 function bulletsDel(){ for(var i = 0; i < bullets.length;i++){ if(bullets[i].y < -bullets[i].height || bullets[i].candel){ bullets.splice(i,1) } } // console.log(bullets) } // 3.3 敵方飛機(jī) // 3.3.1 敵方飛機(jī)的圖片(3種) // 小號(hào) var enemy1 = []; enemy1[0] = new Image(); enemy1[0].src = "images/enemy1.png"; enemy1[1] = new Image(); enemy1[1].src = "images/enemy1_down1.png"; enemy1[2] = new Image(); enemy1[2].src = "images/enemy1_down2.png"; enemy1[3] = new Image(); enemy1[3].src = "images/enemy1_down3.png"; enemy1[4] = new Image(); enemy1[4].src = "images/enemy1_down4.png"; // 中號(hào) var enemy2 = []; enemy2[0] = new Image(); enemy2[0].src = "images/enemy2.png"; enemy2[1] = new Image(); enemy2[1].src = "images/enemy2_down1.png"; enemy2[2] = new Image(); enemy2[2].src = "images/enemy2_down2.png"; enemy2[3] = new Image(); enemy2[3].src = "images/enemy2_down3.png"; enemy2[4] = new Image(); enemy2[4].src = "images/enemy2_down4.png"; // 大號(hào) var enemy3 = []; enemy3[0] = new Image(); enemy3[0].src = "images/enemy3_n1.png"; enemy3[1] = new Image(); enemy3[1].src = "images/enemy3_n2.png"; enemy3[2] = new Image(); enemy3[2].src = "images/enemy3_down1.png"; enemy3[3] = new Image(); enemy3[3].src = "images/enemy3_down2.png"; enemy3[4] = new Image(); enemy3[4].src = "images/enemy3_down3.png"; enemy3[5] = new Image(); enemy3[5].src = "images/enemy3_down4.png"; enemy3[6] = new Image(); enemy3[6].src = "images/enemy3_down5.png"; enemy3[7] = new Image(); enemy3[7].src = "images/enemy3_down6.png"; // 3.2.2 數(shù)據(jù) var ENEMY1 = { imgs: enemy1, length: enemy1.length, width: 57, height: 51, type: 1, //增加標(biāo)識(shí)符,區(qū)分飛機(jī)的種類。小號(hào)的設(shè)置成1 frame: 1, //增加標(biāo)識(shí)符,1種狀態(tài)就為1,2種狀態(tài)就為2 life: 1, //增加標(biāo)識(shí)符,被子彈打擊的次數(shù) score: 1 //打倒一只的得分 } var ENEMY2 = { imgs: enemy2, length: enemy2.length, width: 69, height: 95, type: 2, //增加標(biāo)識(shí)符,區(qū)分飛機(jī)的種類。中號(hào)的設(shè)置成2 frame: 1, //增加標(biāo)識(shí)符,1種狀態(tài)就為1,2種狀態(tài)就為2 life: 3, //增加標(biāo)識(shí)符,被子彈打擊的次數(shù) score: 5 //打倒一只的得分 } var ENEMY3 = { imgs: enemy3, length: enemy3.length, width: 169, height: 258, type: 3, //增加標(biāo)識(shí)符,區(qū)分飛機(jī)的種類。大號(hào)的設(shè)置成3 frame: 2, //增加標(biāo)識(shí)符,,1種狀態(tài)就為1,2種狀態(tài)就為2 life: 10, //增加標(biāo)識(shí)符,被子彈打擊的次數(shù) score: 15 //打倒一只的得分 } // 3.3.3 構(gòu)造函數(shù) function Enemy(config) { this.imgs = config.imgs; this.length = config.length; this.width = config.width; this.height = config.height; this.type = config.type; this.frame = config.frame; this.life = config.life; this.score = config.score; // 圖片的索引 this.startIndex = 0 this.down = false; //表示一直沒(méi)有撞擊 this.candel = false; //表示撞擊以后的動(dòng)畫(huà)是否運(yùn)行完成,完成以后的恢復(fù)運(yùn)行的狀態(tài) // 繪制坐標(biāo) this.x = Math.random() * (WIDTH - this.width); this.y = -this.height; // 繪制的方法 this.paint = function () { context.drawImage(this.imgs[this.startIndex], this.x, this.y); } // 運(yùn)動(dòng)方法 this.step = function(){ if(!this.down){ //正常 // 小號(hào)的,中號(hào) 角標(biāo)始終是0 // 大號(hào)的是在0和1之間切換 this.startIndex ++; this.startIndex = this.startIndex % this.frame; this.y += 2; }else { //爆炸 this.startIndex ++; if(this.startIndex == this.length){ this.candel = true; this.startIndex = this.length - 1; } } } // 爆炸的方法 this.bang = function(){ this.life -- ; if(this.life == 0){ this.down = true; score += this.score; } } // 檢測(cè)是否撞擊 this.checkHit = function(wo){ // 1.撞擊到子彈 // 2.撞擊到我方飛機(jī) return wo.y + wo.height > this.y && wo.x + wo.width > this.x && wo.y < this.y + this.height && wo.x < this.x + this.width; } } // 3.3.4 創(chuàng)建數(shù)組 存儲(chǔ)敵方飛機(jī) var enemies = []; // 3.3.5 創(chuàng)建飛機(jī) function enterEnemies() { var num = Math.random(); if (num < 0.1) { enemies.push(new Enemy(ENEMY1)) } else if (num < 0.15) { enemies.push(new Enemy(ENEMY2)) } else if (num < 0.16) { enemies.push(new Enemy(ENEMY3)) } } // 3.3.6 繪制 function paintEnemies() { for (var i = 0; i < enemies.length; i++) { enemies[i].paint(); } } // 3.3.7 運(yùn)動(dòng) function stepEnemies() { for (var i = 0; i < enemies.length; i++) { enemies[i].step(); } } // 3.3.8 刪除 function delEnemies(){ for(var i = 0;i < enemies.length;i++){ if(enemies[i].y > HEIGHT || enemies[i].candel){ enemies.splice(i,1) } } } // 3.4 檢測(cè)撞擊 function hitEnemies() { for (var i = 0; i < enemies.length; i++) { if (enemies[i].checkHit(hero)) { enemies[i].bang(); hero.bang(); } for (var j = 0; j < bullets.length; j++) { if (enemies[i].checkHit(bullets[j])) { enemies[i].bang(); bullets[j].bang(); } } } } // 3.5 我方飛機(jī)的生命和得分 function paintText(){ context.font = "bold 30px 微軟雅黑"; context.fillText("SCORE:" + score,10,30); context.fillText("LIFE:" + life,380,30) } // 4.暫停階段 canvas.onmouseover=function(){ if(state==PAUSE){ state=RUNNING; } } canvas.onmouseout=function(){ if(state==RUNNING){ state=PAUSE; } } var pause=new Image(); pause.src="images/game_pause_nor.png" function paintdown(){ context.drawImage(pause,220,300) } // 5.gameover階段 function paintOver(){ context.font="bold 50px 微軟雅黑"; context.fillText("GAME OVER",110,300); } // 定時(shí)器加載,使圖片緩慢往下面移動(dòng) setInterval(function () { sky.paint(); sky.step(); if (state == START) { context.drawImage(logo, 40, 0);//繪制在正中間 } else if (state == STARTING) { loading.paint(); loading.step(); } else if (state == RUNNING) { hero.paint(); hero.step(); hero.shoot(); bulletsPaint(); bulletsStep(); bulletsDel(); enterEnemies(); paintEnemies(); stepEnemies(); delEnemies(); hitEnemies(); paintText(); }else if(state==PAUSE){ hero.paint(); bulletsPaint(); paintEnemies(); paintText(); paintdown(); }else if(state==GAMEOVER){ hero.paint(); bulletsPaint(); paintEnemies(); paintText(); paintdown(); paintOver(); } }, 100) </script>
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- js+canvas實(shí)現(xiàn)飛機(jī)大戰(zhàn)
- JavaScript實(shí)現(xiàn)前端飛機(jī)大戰(zhàn)小游戲
- JavaScript編寫(xiě)實(shí)現(xiàn)飛機(jī)大戰(zhàn)
- JavaScript實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲
- 用JS實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲
- 原生JS實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲
- js實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲
- JS面向?qū)ο髮?shí)現(xiàn)飛機(jī)大戰(zhàn)
- JavaScript原生編寫(xiě)《飛機(jī)大戰(zhàn)坦克》游戲完整實(shí)例
- js+css實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲
相關(guān)文章
關(guān)于javascript document.createDocumentFragment()
documentFragment 是一個(gè)無(wú)父對(duì)象的document對(duì)象.2009-04-04淺析JavaScript中break、continue和return的區(qū)別
這篇文章主要介紹了JavaScript中break、continue和return的區(qū)別,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11解決echarts的多個(gè)折現(xiàn)數(shù)據(jù)出現(xiàn)坐標(biāo)和值對(duì)不上的問(wèn)題
這篇文章主要介紹了解決echarts的多個(gè)折現(xiàn)數(shù)據(jù)出現(xiàn)坐標(biāo)和值對(duì)不上的問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12JS根據(jù)Unix時(shí)間戳顯示發(fā)布時(shí)間是多久前【項(xiàng)目實(shí)測(cè)】
小編最近在實(shí)現(xiàn)這樣的需求類似微信朋友圈顯示發(fā)布時(shí)間為距離當(dāng)前時(shí)間多久之前這樣的功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2019-07-07Async Validator 異步驗(yàn)證使用說(shuō)明
async-validator 是一個(gè)異步驗(yàn)證的庫(kù),需要傳入要驗(yàn)證的數(shù)據(jù)和驗(yàn)證規(guī)則 ,下面通過(guò)本文給大家介紹Async Validator 異步驗(yàn)證使用說(shuō)明,需要的的朋友參考下吧2017-07-07uniapp使用uni-imei插件獲取手機(jī)的設(shè)備號(hào)
uniapp框架是一款開(kāi)發(fā)跨平臺(tái)應(yīng)用的工具,它支持iOS、Android以及Web等多個(gè)平臺(tái),在這些平臺(tái)中,uniapp可以訪問(wèn)某些設(shè)備的硬件信息,這篇文章主要給大家介紹了關(guān)于uniapp使用uni-imei插件獲取手機(jī)設(shè)備號(hào)的相關(guān)資料,需要的朋友可以參考下2024-01-01javascript前端埋點(diǎn)上報(bào)的幾種方式
本文將介紹前端埋點(diǎn)上報(bào)的幾種常見(jiàn)方式,并詳細(xì)闡述如何在項(xiàng)目中運(yùn)用這些方式進(jìn)行數(shù)據(jù)上報(bào),以幫助開(kāi)發(fā)者更好地進(jìn)行數(shù)據(jù)收集和分析,感興趣的可以了解一下2023-11-11