您好,登錄后才能下訂單哦!
小編給大家分享一下JS實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲的示例代碼,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
先制作好要做好的幾步以及背景樣式
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var start = 0; // 開始階段 var starting = 1; // 開始的加載階段 var running = 2; // 游戲階段 var pause = 3; // 暫停階段 var gameover = 4; // 結(jié)束階段 var state = start; // 目前狀態(tài) var width = canvas.width; // 獲取畫布的寬度 var height = canvas.height; // 獲取畫布的高度 var score = 0; // 分?jǐn)?shù) var life = 3; // 我放飛機(jī)生命值 var bg = new Image(); // 創(chuàng)建背景圖片 bg.src = "img/background.png"; var BG = { imgs: bg, width: 480, height: 852, }; // 創(chuàng)建生成背景圖片的構(gòu)造函數(shù) function Bg(config) { // 參數(shù)為BG對(duì)象 this.imgs = config.imgs; this.width = config.width; this.height = config.height; // 定義兩張背景圖片,用于動(dòng)畫 this.x1 = 0; this.y1 = 0; this.x2 = 0; //第二張背景圖的初始高度放在背景高度(固定)的上面 this.y2 = -this.height; // 背景圖片繪制方法 this.paint = function() { //分別繪制了兩張背景圖 ctx.drawImage(this.imgs, this.x1, this.y1); ctx.drawImage(this.imgs, this.x2, this.y2); }; // 背景圖片運(yùn)動(dòng)的方法 this.step = function() { //背景圖片位置向下移動(dòng)一個(gè),然后利用定時(shí)器讓背景圖動(dòng)起來 this.y1++; this.y2++; //判斷圖片高度的臨界點(diǎn), if (this.y1 == this.height) { this.y1 = -this.height; } if (this.y2 == this.height) { this.y2 = -this.height; } } }; // 創(chuàng)建背景圖片對(duì)象 var sky = new Bg(BG); // 生成游戲名文字 var logo = new Image(); logo.src = "img/start.png"; // 游戲加載過程的4張圖片存入一個(gè)數(shù)組中 var loadings = []; loadings[0] = new Image(); loadings[0].src = "img/game_loading1.png"; loadings[1] = new Image(); loadings[1].src = "img/game_loading2.png"; loadings[2] = new Image(); loadings[2].src = "img/game_loading3.png"; loadings[3] = new Image(); loadings[3].src = "img/game_loading4.png"; var LOADING = { imges: loadings, length: loadings.length, width: 186, height: 38, }; // 構(gòu)造函數(shù) function Loading(config) { this.imges = config.imges; this.length = config.length; this.width = config.width; this.height = config.height; this.startIndex = 0; // 用于判斷需要顯示的圖片是哪個(gè) // 繪制方法 this.paint = function() { ctx.drawImage(this.imges[this.startIndex], 0, height - this.height) }; this.time = 0; // 加載時(shí)圖片切換速度 // 圖片切換方法 this.step = function() { this.time++; if (this.time % 4 === 0) { this.startIndex++; } if (this.startIndex === this.length) { // 加載階段結(jié)束,進(jìn)入游戲階段 state = running; } } }; // 創(chuàng)建加載階段的對(duì)象 var loading = new Loading(LOADING);
在制作我方飛機(jī)
// 我方飛機(jī) var heros = []; heros[0] = new Image(); heros[0].src = "img/hero1.png"; heros[1] = new Image(); heros[1].src = "img/hero2.png"; heros[2] = new Image(); heros[2].src = "img/hero_blowup_n1.png"; heros[3] = new Image(); heros[3].src = "img/hero_blowup_n2.png"; heros[4] = new Image(); heros[4].src = "img/hero_blowup_n3.png"; heros[5] = new Image(); heros[5].src = "img/hero_blowup_n4.png"; var HEROS = { imgs: heros, length: heros.length, width: 99, height: 124, frame: 2 }; // 我方飛機(jī)的構(gòu)造函數(shù) 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; // 用于判斷我方飛機(jī)當(dāng)前狀態(tài) // 定義我方飛機(jī)的位置 this.x = width / 2 - this.width / 2; this.y = height - this.height; // 定義飛機(jī)撞擊的標(biāo)志,表示飛機(jī)沒有被撞擊 this.down = false; // 定義飛機(jī)是否爆破完成,表示飛機(jī)還沒有完全爆炸 this.candel = false; // 繪制方法 this.paint = function() { ctx.drawImage(this.imgs[this.startIndex], this.x, this.y) }; // 我方飛機(jī)運(yùn)動(dòng)方法 this.step = function() { if (!this.down) { // 飛機(jī)正常狀態(tài) if (this.startIndex === 0) { this.startIndex = 1; } else { this.startIndex = 0 } } else { // 爆炸狀態(tài) this.startIndex++; if (this.startIndex === this.length) { // 判斷是否炸完了 // 炸完了,命-1 life--; if (life === 0) { // 判斷是否掛了 state = gameover; this.startIndex = this.length - 1; } else { // 重新開始新生命 hero = new Hero(HEROS) } } } }; // 我方飛機(jī)碰撞 this.bang = function() { this.down = true; };
繪制子彈狀態(tài)
var bullet = new Image(); bullet.src = "img/bullet1.png"; // 初始化 var BULLETS = { imgs: bullet, width: 9, height: 21, }; // 創(chuàng)建子彈的構(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() { ctx.drawImage(this.imgs, this.x, this.y) }; // 運(yùn)動(dòng)方法 this.step = function() { this.y -= 10; }; this.candel = false; // 用于判斷子彈是否碰撞 // 子彈碰撞方法 this.bang = function() { this.candel = true; } }; // 所有new的子彈對(duì)象放到一個(gè)數(shù)組 var bullets = []; // 遍歷繪制子彈 function bulletdPaint() { for (var i = 0; i < bullets.length; i++) { bullets[i].paint(); } }; // 遍歷調(diào)用子彈的運(yùn)動(dòng); function bulletdStep() { for (var i = 0; i < bullets.length; i++) { bullets[i].step(); } }; // 子彈的刪除函數(shù) function bulletDel() { // 碰撞的時(shí)候刪除子彈 // 超出畫布的高度,即負(fù)的子彈的高度 for (var i = 0; i < bullets.length; i++) { if (bullets[i].candel || bullets[i].y < -bullets[i].height) { bullets.splice(i, 1) } } };
子彈跟隨飛機(jī)的移動(dòng)而移動(dòng)
// 子彈發(fā)射 this.time = 0; // 設(shè)計(jì)速度初始為0 this.shoot = function() { this.time++; if (this.time % 2 === 0) { // 每2步移動(dòng)射擊一次 bullets.push(new Bullet(BULLETS)) } }; }; // 創(chuàng)建我方飛機(jī)的對(duì)象實(shí)例 var hero = new Hero(HEROS); // 鼠標(biāo)移動(dòng)事件 canvas.onmousemove = function(event) { // console.log("onmousemove"); var event = event || window.event; if (state == running) { //判斷當(dāng)前游戲狀態(tài) //把獲取到的頁面中的鼠標(biāo)橫坐標(biāo)的值賦給飛機(jī)的橫坐標(biāo)(位置) hero.x = event.offsetX - hero.width / 2; //把獲取到的頁面中的鼠標(biāo)縱坐標(biāo)的值賦給飛機(jī)的縱坐標(biāo)(位置) hero.y = event.offsetY - hero.height / 2; } };
繪制敵方飛機(jī)
// 敵方飛機(jī)的繪制 var enemy1 = []; //小飛機(jī) enemy1[0] = new Image(); enemy1[0].src = "img/enemy1.png"; enemy1[1] = new Image(); enemy1[1].src = 'img/enemy1_down1.png'; enemy1[2] = new Image(); enemy1[2].src = 'img/enemy1_down2.png'; enemy1[3] = new Image(); enemy1[3].src = 'img/enemy1_down3.png'; enemy1[4] = new Image(); enemy1[4].src = 'img/enemy1_down4.png'; var enemy2 = []; //中飛機(jī) enemy2[0] = new Image(); enemy2[0].src = "img/enemy2.png"; enemy2[1] = new Image(); enemy2[1].src = "img/enemy2_down1.png"; enemy2[2] = new Image(); enemy2[2].src = "img/enemy2_down2.png"; enemy2[3] = new Image(); enemy2[3].src = "img/enemy2_down3.png"; enemy2[4] = new Image(); enemy2[4].src = "img/enemy2_down4.png"; var enemy3 = []; //大飛機(jī) enemy3[0] = new Image(); enemy3[0].src = "img/enemy3_n1.png"; enemy3[1] = new Image(); enemy3[1].src = "img/enemy3_n2.png"; enemy3[2] = new Image(); enemy3[2].src = "img/enemy3_down1.png"; enemy3[3] = new Image(); enemy3[3].src = "img/enemy3_down2.png"; enemy3[4] = new Image(); enemy3[4].src = "img/enemy3_down3.png"; enemy3[5] = new Image(); enemy3[5].src = "img/enemy3_down4.png"; enemy3[6] = new Image(); enemy3[6].src = "img/enemy3_down5.png"; enemy3[7] = new Image(); enemy3[7].src = "img/enemy3_down6.png"; // 初始化數(shù)據(jù) var ENEMY1 = { imgs: enemy1, length: enemy1.length, width: 57, height: 51, type: 1, frame: 2, life: 1, score: 1, }; var ENEMY2 = { imgs: enemy2, length: enemy2.length, width: 69, height: 95, type: 2, frame: 2, life: 5, score: 5, }; var ENEMY3 = { imgs: enemy3, length: enemy3.length, width: 165, height: 261, type: 3, frame: 2, life: 15, score: 20, }; // 敵方飛機(jī)的構(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; // 敵方飛機(jī)的坐標(biāo) this.x = Math.random() * (width - this.width); this.y = -this.height; this.startIndex = 0; // 用于判斷的下標(biāo) this.down = false; // 用于判斷是否碰撞 this.candel = false; // 用于判斷是否爆炸完成 //繪制方法 this.paint = function() { ctx.drawImage(this.imgs[this.startIndex], this.x, this.y); }; //運(yùn)動(dòng)方法 this.step = function() { if (!this.down) { // 敵方飛機(jī)處于正常狀態(tài) // 小飛機(jī),中飛機(jī)的下標(biāo)始終都是0 // 大飛機(jī)的下標(biāo)是在0和1之間進(jìn)行切換 this.startIndex++; this.startIndex = this.startIndex % this.frame; // 飛機(jī)向下的動(dòng)畫 this.y += 2; } else { //飛機(jī)發(fā)生碰撞以后 this.startIndex++; if (this.startIndex == this.length) { this.candel = true; this.startIndex = this.length - 1; } } }; // 判斷是否被碰撞 this.checkHit = function(wo) { //判斷四個(gè)邊 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; }; //敵方飛機(jī)碰撞后 this.bang = function() { this.life--; if (this.life === 0) { this.down = true; score += this.score; } } }; // 數(shù)組存放敵方飛機(jī) var enemise = []; // 往敵方飛機(jī)數(shù)組中添加數(shù)據(jù) function enterEnemise() { var rand = Math.floor(Math.random() * 100) if (rand < 10) { // 添加小飛機(jī) enemise.push(new Enemy(ENEMY1)); } else if (rand < 55 && rand > 50) { // 添加中飛機(jī) enemise.push(new Enemy(ENEMY2)); } else if (rand === 88) { // 添加大飛機(jī) if (enemise[0].type !== 3 && enemise.length > 0) { enemise.splice(0, 0, new Enemy(ENEMY3)); } } }; // 繪制敵方飛機(jī)函數(shù) function enemyPaint() { for (var i = 0; i < enemise.length; i++) { enemise[i].paint(); } }; // 敵方飛機(jī)的運(yùn)動(dòng)函數(shù) function enemyStep() { for (var i = 0; i < enemise.length; i++) { enemise[i].step(); } }; // 刪除敵方飛機(jī)函數(shù) function delenemy() { for (var i = 0; i < enemise.length; i++) { // console.log(enemise[i].candel) if (enemise[i].y > height || enemise[i].candel) { enemise.splice(i, 1) } } }; // 碰撞以后的函數(shù) function hitEnemise() { for (var i = 0; i < enemise.length; i++) { // 如果我放飛機(jī)撞到了敵方飛機(jī)以后 if (enemise[i].checkHit(hero)) { // 敵方飛機(jī)碰撞后,碰撞狀態(tài)改變 enemise[i].bang(); // 我方飛機(jī)碰撞后,碰撞狀態(tài)改變 hero.bang(); }; // 子彈碰到敵方飛機(jī) for (var j = 0; j < bullets.length; j++) { if (enemise[i].checkHit(bullets[j])) { enemise[i].bang(); // 子彈的碰撞后,碰撞狀態(tài)改變 bullets[j].bang(); } } } };
最后的收尾階段
// 繪制分?jǐn)?shù)和生命值 function scoreText() { ctx.font = "30px bold" ctx.fillText("score:" + score, 10, 30); ctx.fillText("life:" + life, 300, 30); }; // 游戲暫停的階段 canvas.onmouseout = function() { if (state === running) { state = pause; } }; // 調(diào)用畫布的鼠標(biāo)移入事件 canvas.onmouseover = function() { if (state === pause) { state = running; } }; // 暫停圖片 var pause = new Image() pause.src = "img/game_pause_nor.png"; // 游戲結(jié)束 function gameoverfn() { ctx.font = "50px bold" ctx.fillText("GAME OVER !!!", 80, 300); ctx.fillText("ONCE MORE !!!", 80, 400); }; // 畫布點(diǎn)擊事件 canvas.addEventListener("click", function(e) { p = getEventPosition(e); // 點(diǎn)擊畫布時(shí),判斷游戲是否開始 if (state === start) { state = starting; } console.log(123); // 重新開始游戲有問題??? if (state === gameover) { if (p.y >= 350 && p.y < 450) { console.log('你點(diǎn)擊了ONCE MORE !!!'); state = running; } } }); function getEventPosition(e) { var x, y; if (e.layerX || ev.layerX === 0) { x = e.layerX; y = e.layerY; } else if (e.offsetX || ev.offsetX === 0) { x = e.offsetX; y = e.offsetY; } return { x: x, y: y }; };
后面就是基本的每個(gè)階段的調(diào)用問題叻
setInterval(function() { //背景圖片無論在哪個(gè)狀態(tài)都有背景圖片以及它的動(dòng)態(tài)效果 sky.paint(); // 繪制背景 sky.step(); // 背景動(dòng)畫 if (state === start) { // 第一階段 ctx.drawImage(logo, 35, 0) } else if (state === starting) { // 第二階段 loading.paint(); // 繪制背景 loading.step(); // 背景動(dòng)畫 } else if (state === running) { // 第三狀態(tài) // 繪制我放飛機(jī) hero.paint(); // 我方飛機(jī)的運(yùn)動(dòng) hero.step(); // 我方飛機(jī)的射擊方法 hero.shoot(); // 子彈的繪制 bulletdPaint(); // 子彈的運(yùn)動(dòng) bulletdStep(); // 子彈的刪除 bulletDel(); // 創(chuàng)建敵方飛機(jī) enterEnemise(); // 繪制敵方飛機(jī) enemyPaint(); // 繪制敵方飛機(jī)的運(yùn)動(dòng) enemyStep(); // 刪除敵方飛機(jī) delenemy(); // 判斷是否撞擊 hitEnemise(); // 繪制分?jǐn)?shù)和生命值 scoreText() } else if (state === pause) { // 第四狀態(tài) sky.paint(); // 繪制背景 sky.step(); // 背景動(dòng)畫 // 繪制我放飛機(jī) hero.paint(); // 子彈的繪制 bulletdPaint(); // 繪制敵方飛機(jī) enemyPaint(); // 繪制分?jǐn)?shù)和生命值 scoreText(); ctx.drawImage(pause, 220, 300) } else if (state === gameover) { // 第五狀態(tài) sky.paint(); // 繪制背景 sky.step(); // 背景動(dòng)畫 hero.paint(); // 子彈的繪制 bulletdPaint(); // 繪制敵方飛機(jī) enemyPaint(); // 繪制分?jǐn)?shù)和生命值 scoreText(); // 游戲結(jié)束 gameoverfn(); } }, 10) })()
看完了這篇文章,相信你對(duì)“JS實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲的示例代碼”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。