发布时间:2023-10-17 10:30
本文实例为大家分享了JavaScript实现飞机大战的具体代码,供大家参考,具体内容如下
游戏中,玩家驾驶飞机,在空中进行战斗。点击并移动自己的飞机,发射炮弹,打掉敌小型飞机、中型飞机和大型飞机,来获得分数和奖励,打掉一架小型飞机赢得3分,打掉一架中型飞机赢得5分,打掉一架大型飞机赢得10分,累加得分。撞到敌飞机命减1,当命数为0时,则游戏结束。
初始界面如图-1所示:
玩家在如图-1所示的界面的任意位置,按下鼠标左键,开始游戏。
图-1
默认分数为0,默认5条命,请看如图-2所示具体介绍:
图-2
在游戏进行过程中,鼠标离开游戏界面,游戏将进入暂停状态,界面效果如图-3所示:
图-3
当鼠标再次移入界面时,游戏将继续进行。
画布样式:
设置画布,定义初始状态,准备阶段:
// 画布 var canvas = document.getElementById(\'canvas\') var ctx = canvas.getContext(\'2d\'); // 存储画布宽高 var width = canvas.width; var height = canvas.height; var height = 852; // 准备初始化 var ready = 0; var loading = 1; var running = 2; var pause = 3; var over = 4; var life = 3; var score = 0; // 定义初始状态 var state = ready; // 一. 准备阶段,在画布上以图片的形式画出背景图片 var bg = new Image(); bg.src = \'img/background.png\'; // 1. 创建一个对象,用来存储当前图片绘制的等信息 var bgParam = { bg: bg, //对象里的第一个参数为构建的image对象,.src属性存储了图片的信息 x: 0, y: 0, width: 480, height: 852 } // 2 .创建构造函数,调用函数时绘制这张图,将图片绘制的信息传递给这个函数时,根据传递的信息绘制出图片 function bgPaint(param) { this.bg = param.bg; this.x = param.x; this.y = param.y; this.width = param.width; this.height = param.height; // 两张图片交替绘制,实现滚动效果 this.y1 = -this.height; // 绘制图片 this.draw = function () { ctx.drawImage(this.bg, this.x, this.y, this.width, this.height) ctx.drawImage(this.bg, this.x, this.y1, this.width, this.height) } // 让图片不断下移,实现动态滚动效果 this.scroll = function () { this.y += 7; this.y1 += 7; // 每张图片到达底部后重新回到上面 if (this.y >= this.height) { this.y = -this.height } if (this.y1 >= this.height) { this.y1 = -this.height } } } // 创建背景图片对象 var bgObj = new bgPaint(bgParam);
绘制游戏开始前:
// 二. 绘制游戏开始前logo var logo = new Image(); logo.src = \'img/start.png\' var logoParam = { logo: logo, x: 0, y: 0, width: 480, height: 852 } function logoPaint(param) { this.logo = param.logo; this.x = param.x; this.y = param.y; this.width = param.width; this.height = param.height; this.draw = function () { ctx.drawImage(this.logo, this.x, this.y, this.width, this.height) } } var logoObj = new logoPaint(logoParam); // 点击后改变游戏状态 canvas.addEventListener(\'click\',function () { if (state == ready) { state = loading; }else if (state == loading){ state = pause; }else if (state == running){ state = pause; }else if (state == pause){ if(state != over){ state = running; console.log(22); } } }) canvas.addEventListener(\'mouseleave\',function(){ if(state == loading){ state = pause; }else if (state == running){ state = pause; } })
游戏加载阶段:
// 三. 游戏加载阶段 // 定义数组存放图片的信息 var imgArr = [\'img/game_loading1.png\', \'img/game_loading2.png\', \'img/game_loading3.png\', \'img/game_loading4.png\'] var loadingImg = []; for (var i = 0; i < imgArr.length; i++) { loadingImg[i] = new Image(); loadingImg[i].src = imgArr[i] } var loadingParam = { loadingImg: loadingImg, //第一个参数为一个数组,数组里存放了一系列new Image()所new出来的图片对象,图片对象.src为地址 width: 186, height: 38 } function loadingPaint(param) { this.loadingImg = param.loadingImg; this.width = param.width; this.height = param.height; this.x = 0; this.y = height - param.height; // 定义绘制的下标 this.index = 0; this.times = 0; // 绘制图片 this.draw = function () { ctx.drawImage(this.loadingImg[this.index], this.x, this.y, this.width, this.height) } // 每隔一段时间通过改变下标来改变图片以使图片动起来 this.sport = function () { // 定时器累计一定次数后才改变下一张图片,避免加载图片更换太快 this.times++; if (this.times % 2 == 0) { this.index++; if (this.index == this.loadingImg.length) { // 绘制完加载图片后,改变游戏状态 state = running; } } } } // 在绘制完加载图片后自动更换了游戏运行状态 var loadingObj = new loadingPaint(loadingParam);
游戏进行阶段:
// 四. 游戏进行阶段 // 绘制我方飞机 var heroArr = [\'img/hero1.png\', \'img/hero2.png\', \'img/hero_blowup_n1.png\', \'img/hero_blowup_n2.png\', \'img/hero_blowup_n3.png\', \'img/hero_blowup_n4.png\' ] var heroPlane = []; for (var i = 0; i < heroArr.length; i++) { heroPlane[i] = new Image(); heroPlane[i].src = heroArr[i] } // 定义飞机的图像信息 var heroParam = { heroPlane: heroPlane, width: 99, height: 124, life:5 } var flag = true; function heroPaint(param) { this.heroPlane = param.heroPlane; this.width = param.width; this.height = param.height; this.life = param.life; flag = false; this.x = width / 2 - this.width / 2; this.y = height - this.height; // 存储切换图片的下标 this.index = 0; // 判断是否被撞击 this.down = false; // 切换频率 this.times = 0; // 绘制hero函数 this.draw = function () { ctx.drawImage(this.heroPlane[this.index], this.x, this.y, this.width, this.height) } // 判断飞机是否被撞击以及被撞击后的状态改变 this.sport = function () { // 没有被撞击时飞机的状态只会在hero1和hero2之间切换 if (!this.down) { if (this.index == 0) { this.index = 1; } else { this.index = 0; } } else { // 被撞击后状态的改变加上爆炸的样子 this.index++; if (this.index == this.heroPlane.length) { // 游戏结束后飞机停留在冒烟状态 this.index = this.heroPlane.length - 1; heroParam.life--; if (heroParam.life <= 0) { state = over; } else { // 还有生命值时重新开始游戏 heroObj = new heroPaint(heroParam) } } } } this.shoot = function () { this.times++; if (this.times % 2 === 0) { // 飞机在就源源不断地补充子弹 bullets.push(new Bullet(bulletParam)); } } } var heroObj = new heroPaint(heroParam); // 让飞机跟着鼠标动 canvas.onmousemove = function (e) { if(state === pause){ state = running; } if (state === running) { // 获取鼠标移动后的位置 heroObj.x = e.offsetX - heroObj.width / 2; heroObj.y = e.offsetY - heroObj.height / 2; } }
设置子弹和敌机状态:
// 子弹 var bullet = new Image(); bullet.src = \'img/bullet1.png\'; var bulletParam = { bullet: bullet, width: 9, height: 21 } function Bullet(param) { this.bullet = param.bullet; this.width = param.width; this.height = param.height; this.x = heroObj.x + heroObj.width / 2 - this.width / 2; this.y = heroObj.y - this.height - 10; // 判断是否被撞击的标志 this.down = false; this.draw = function () { ctx.drawImage(this.bullet, this.x, this.y, this.width, this.height); } // 运动 this.sport = function () { this.y -= 25; } } var bullets = []; // 绘制子弹 function bulletsPaint() { for (var i = 0; i < bullets.length; i++) { bullets[i].draw(); } } function bulletsSport() { for (var i = 0; i < bullets.length; i++) { bullets[i].sport(); } } // 删除子弹 // 1. 子弹飞出屏幕外面 // 2. 子弹敌机碰撞了 function bulletsDelete() { for (var i = 0; i < bullets.length; i++) { if (bullets[i].y < -bullets[i].height || bullets[i].down) { bullets.splice(i, 1); } } } // 绘制敌机 // 敌方小号飞机 var enemy1Arr = [\'img/enemy1.png\', \'img/enemy1_down1.png\', \'img/enemy1_down2.png\', \'img/enemy1_down3.png\', \'img/enemy1_down4.png\' ]; var enemy1Plane = []; for (var i = 0; i < enemy1Arr.length; i++) { enemy1Plane[i] = new Image(); enemy1Plane[i].src = enemy1Arr[i]; } // 小号飞机信息 var enemy1 = { enemyPlane: enemy1Plane, width: 57, height: 51, life: 3 } // 敌方中号飞机 var enemy2Arr = [\'img/enemy2.png\', \'img/enemy2_down1.png\', \'img/enemy2_down2.png\', \'img/enemy2_down3.png\', \'img/enemy2_down4.png\' ]; var enemy2Plane = []; for (var i = 0; i < enemy2Arr.length; i++) { enemy2Plane[i] = new Image(); enemy2Plane[i].src = enemy2Arr[i]; } // 中号飞机信息 var enemy2 = { enemyPlane: enemy2Plane, width: 69, height: 95, life: 5 } // 敌方大号飞机 var enemy3Arr = [\'img/enemy3_n1.png\', \'img/enemy3_n2.png\', \'img/enemy3_hit.png\', \'img/enemy3_down1.png\', \'img/enemy3_down2.png\', \'img/enemy3_down3.png\', \'img/enemy3_down4.png\', \'img/enemy3_down5.png\', \'img/enemy3_down6.png\' ]; var enemy3Plane = []; for (var i = 0; i < enemy3Arr.length; i++) { enemy3Plane[i] = new Image(); enemy3Plane[i].src = enemy3Arr[i]; } // 大号飞机信息 var enemy3 = { enemyPlane: enemy3Plane, width: 169, height: 258, life: 10 } // 敌机的构造函数 function Enemy(param) { this.enemyPlane = param.enemyPlane; this.width = param.width; this.height = param.height; this.life = param.life; this.x = Math.random() * (width - this.width); this.y = -this.height; this.index = 0; // 判断敌机是否发生碰撞 this.down = false; // 是否爆照完成 this.bang = false; this.paint = function () { ctx.drawImage(this.enemyPlane[this.index], this.x, this.y, this.width, this.height); } this.sport = function () { if (!this.down) { // 当前敌机未被碰撞时 this.y += 5; } else { this.index++; if (this.index === this.enemyPlane.length) { this.index = this.enemyPlane.length - 1; this.bang = true; } } } // 判断是否被碰撞 this.hit = function (obj) { return obj.x + obj.width >= this.x && obj.x <= this.x + this.width && obj.y <= this.y + this.height && obj.y + obj.height >= this.y; } } var enemies = []; var times = 0 function pushEnemy() { times++; if (times % 10 == 0) { var random = Math.random(); if (random < 0.5) { enemies.push(new Enemy(enemy1)); } else if (random < 0.8) { // 中号飞机 enemies.push(new Enemy(enemy2)); } else { // 大号飞机 enemies.push(new Enemy(enemy3)); } } } // 绘制、运动飞机对象 function enemyPaint() { for (var i = 0; i < enemies.length; i++) { enemies[i].paint(); } } function enemySport() { for (var i = 0; i < enemies.length; i++) { enemies[i].sport(); } } function enemyDelete() { for (var i = 0; i < enemies.length; i++) { if (enemies[i].y >= height || enemies[i].bang) { enemies.splice(i, 1); } } } // 如何检测每一个敌机是否被(每一个子弹 hero)碰撞 function checkHit() { for (var i = 0; i < enemies.length; i++) { // 子弹和敌机撞击 for (var j = 0; j < bullets.length; j++) { if (enemies[i].hit(bullets[j])) { bullets[j].down = true; enemies[i].life--; if (enemies[i].life == 0) { enemies[i].down = true; if(enemies[i].width == 169){ score += 10; }else if(enemies[i].width == 69){ score += 5; }else{ score += 3; } } } } // 敌机和hero if (enemies[i].hit(heroObj)) { enemies[i].life -= heroObj.life; heroObj.down = true; if(enemies[i].life <= 0){ enemies[i].down = true; if(enemies[i].width == 169){ score += 10; }else if(enemies[i].width == 69){ score += 5; }else{ score += 3; } } } } }
设置游戏暂停和生命值、分数:
// 游戏暂停画面信息 var pauseImg = new Image(); pauseImg.src = \'img/game_pause_nor.png\'; function gameoverfn() { ctx.font = \"50px bold\" ctx.fillText(\"GAME OVER !!!\", 80, 300); ctx.fillText(\"ONCE MORE !!!\", 80, 400); }; // 分数和生命值 var score = 0; // 绘制分数和生命值 function scoreText() { ctx.font = \"30px bold\" ctx.strokeText(`Score:${score}`, 10, 30) ctx.fillText(\"life:\" + heroParam.life, 300, 30); }; // 在定时器中绘制每一帧的图像 var timer = setInterval(function () { // 调用背景图片绘制函数绘制 bgObj.draw() bgObj.scroll() // 判断游戏状态,state为ready时绘制logo图形 switch (state) { case ready: logoObj.draw(); break; case loading: loadingObj.draw(); loadingObj.sport(); break; case running: heroObj.draw(); heroObj.sport(); heroObj.shoot(); // 绘制子弹 bulletsPaint(); bulletsSport(); bulletsDelete(); // 绘制敌机 pushEnemy(); enemyPaint(); enemySport(); checkHit(); enemyDelete(); scoreText(); break; case pause: ctx.drawImage(pauseImg, 210, 376, 60, 45); heroObj.draw();0 heroObj.shoot(); // 绘制子弹 bulletsPaint(); bulletsDelete(); // 绘制敌机 enemyPaint(); scoreText() break; case over: heroObj.draw(); gameoverfn(); scoreText(); break; } }, 60)
整体代码:
Document
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。