用JS实现飞机大战小游戏
本文实例为大家分享了JS实现飞机大战小游戏的具体代码,供大家参考,具体内容如下
小的时候玩的飞机大战感觉还蛮神奇,今天自己就学着做了一个
先制作好要做好的几步以及背景样式
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; // 结束阶段 var state = start; // 目前状态 var width = canvas.width; // 获取画布的宽度 var height = canvas.height; // 获取画布的高度 var score = 0; // 分数 var life = 3; // 我放飞机生命值 var bg = new Image(); // 创建背景图片 bg.src = 'https://www.haobala.com/bcjs/img/background.png'; var BG = {imgs: bg,width: 480,height: 852, }; // 创建生成背景图片的构造函数 function Bg(config) { // 参数为BG对象this.imgs = config.imgs;this.width = config.width;this.height = config.height;// 定义两张背景图片,用于动画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);};// 背景图片运动的方法this.step = function() { //背景图片位置向下移动一个,然后利用定时器让背景图动起来 this.y1++; this.y2++; //判断图片高度的临界点, if (this.y1 == this.height) {this.y1 = -this.height; } if (this.y2 == this.height) {this.y2 = -this.height; }} }; // 创建背景图片对象 var sky = new Bg(BG); // 生成游戏名文字 var logo = new Image(); logo.src = 'https://www.haobala.com/bcjs/img/start.png'; // 游戏加载过程的4张图片存入一个数组中 var loadings = []; loadings[0] = new Image(); loadings[0].src = 'https://www.haobala.com/bcjs/img/game_loading1.png'; loadings[1] = new Image(); loadings[1].src = 'https://www.haobala.com/bcjs/img/game_loading2.png'; loadings[2] = new Image(); loadings[2].src = 'https://www.haobala.com/bcjs/img/game_loading3.png'; loadings[3] = new Image(); loadings[3].src = 'https://www.haobala.com/bcjs/img/game_loading4.png'; var LOADING = {imges: loadings,length: loadings.length,width: 186,height: 38, }; // 构造函数 function Loading(config) {this.imges = config.imges;this.length = config.length;this.width = config.width;this.height = config.height;this.startIndex = 0; // 用于判断需要显示的图片是哪个// 绘制方法this.paint = function() { ctx.drawImage(this.imges[this.startIndex], 0, height - this.height)};this.time = 0; // 加载时图片切换速度// 图片切换方法this.step = function() { this.time++; if (this.time % 4 === 0) {this.startIndex++; } if (this.startIndex === this.length) {// 加载阶段结束,进入游戏阶段state = running; }} }; // 创建加载阶段的对象var loading = new Loading(LOADING);
在制作我方飞机
// 我方飞机 var heros = []; heros[0] = new Image(); heros[0].src = 'https://www.haobala.com/bcjs/img/hero1.png'; heros[1] = new Image(); heros[1].src = 'https://www.haobala.com/bcjs/img/hero2.png'; heros[2] = new Image(); heros[2].src = 'https://www.haobala.com/bcjs/img/hero_blowup_n1.png'; heros[3] = new Image(); heros[3].src = 'https://www.haobala.com/bcjs/img/hero_blowup_n2.png'; heros[4] = new Image(); heros[4].src = 'https://www.haobala.com/bcjs/img/hero_blowup_n3.png'; heros[5] = new Image(); heros[5].src = 'https://www.haobala.com/bcjs/img/hero_blowup_n4.png'; var HEROS = {imgs: heros,length: heros.length,width: 99,height: 124,frame: 2 }; // 我方飞机的构造函数 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; // 用于判断我方飞机当前状态// 定义我方飞机的位置this.x = width / 2 - this.width / 2;this.y = height - this.height;// 定义飞机撞击的标志,表示飞机没有被撞击this.down = false;// 定义飞机是否爆破完成,表示飞机还没有完全爆炸this.candel = false;// 绘制方法this.paint = function() { ctx.drawImage(this.imgs[this.startIndex], this.x, this.y)};// 我方飞机运动方法this.step = function() { if (!this.down) { // 飞机正常状态if (this.startIndex === 0) { this.startIndex = 1;} else { this.startIndex = 0} } else { // 爆炸状态this.startIndex++;if (this.startIndex === this.length) { // 判断是否炸完了 // 炸完了,命-1 life--; if (life === 0) { // 判断是否挂了state = gameover;this.startIndex = this.length - 1; } else { // 重新开始新生命hero = new Hero(HEROS) }} }};// 我方飞机碰撞this.bang = function() { this.down = true;};
绘制子弹状态
var bullet = new Image(); bullet.src = 'https://www.haobala.com/bcjs/img/bullet1.png'; // 初始化 var BULLETS = {imgs: bullet,width: 9,height: 21, }; // 创建子弹的构造函数 function Bullet(config) {this.imgs = config.imgs;this.width = config.width;this.height = config.height;// 子弹坐标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)};// 运动方法this.step = function() { this.y -= 10;};this.candel = false; // 用于判断子弹是否碰撞// 子弹碰撞方法this.bang = function() { this.candel = true;} }; // 所有new的子弹对象放到一个数组 var bullets = []; // 遍历绘制子弹 function bulletdPaint() {for (var i = 0; i < bullets.length; i++) { bullets[i].paint();} }; // 遍历调用子弹的运动; function bulletdStep() {for (var i = 0; i < bullets.length; i++) { bullets[i].step();} }; // 子弹的删除函数 function bulletDel() {// 碰撞的时候删除子弹// 超出画布的高度,即负的子弹的高度for (var i = 0; i < bullets.length; i++) { if (bullets[i].candel || bullets[i].y < -bullets[i].height) {bullets.splice(i, 1) }} };
子弹跟随飞机的移动而移动
// 子弹发射this.time = 0; // 设计速度初始为0this.shoot = function() { this.time++; if (this.time % 2 === 0) { // 每2步移动射击一次bullets.push(new Bullet(BULLETS)) }}; }; // 创建我方飞机的对象实例 var hero = new Hero(HEROS); // 鼠标移动事件 canvas.onmousemove = function(event) {// console.log('onmousemove');var event = event || window.event;if (state == running) { //判断当前游戏状态 //把获取到的页面中的鼠标横坐标的值赋给飞机的横坐标(位置) hero.x = event.offsetX - hero.width / 2; //把获取到的页面中的鼠标纵坐标的值赋给飞机的纵坐标(位置) hero.y = event.offsetY - hero.height / 2;} };
绘制敌方飞机
// 敌方飞机的绘制 var enemy1 = []; //小飞机 enemy1[0] = new Image(); enemy1[0].src = 'https://www.haobala.com/bcjs/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 = []; //中飞机 enemy2[0] = new Image(); enemy2[0].src = 'https://www.haobala.com/bcjs/img/enemy2.png'; enemy2[1] = new Image(); enemy2[1].src = 'https://www.haobala.com/bcjs/img/enemy2_down1.png'; enemy2[2] = new Image(); enemy2[2].src = 'https://www.haobala.com/bcjs/img/enemy2_down2.png'; enemy2[3] = new Image(); enemy2[3].src = 'https://www.haobala.com/bcjs/img/enemy2_down3.png'; enemy2[4] = new Image(); enemy2[4].src = 'https://www.haobala.com/bcjs/img/enemy2_down4.png'; var enemy3 = []; //大飞机 enemy3[0] = new Image(); enemy3[0].src = 'https://www.haobala.com/bcjs/img/enemy3_n1.png'; enemy3[1] = new Image(); enemy3[1].src = 'https://www.haobala.com/bcjs/img/enemy3_n2.png'; enemy3[2] = new Image(); enemy3[2].src = 'https://www.haobala.com/bcjs/img/enemy3_down1.png'; enemy3[3] = new Image(); enemy3[3].src = 'https://www.haobala.com/bcjs/img/enemy3_down2.png'; enemy3[4] = new Image(); enemy3[4].src = 'https://www.haobala.com/bcjs/img/enemy3_down3.png'; enemy3[5] = new Image(); enemy3[5].src = 'https://www.haobala.com/bcjs/img/enemy3_down4.png'; enemy3[6] = new Image(); enemy3[6].src = 'https://www.haobala.com/bcjs/img/enemy3_down5.png'; enemy3[7] = new Image(); enemy3[7].src = 'https://www.haobala.com/bcjs/img/enemy3_down6.png'; // 初始化数据 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, }; // 敌方飞机的构造函数 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.x = Math.random() * (width - this.width);this.y = -this.height;this.startIndex = 0; // 用于判断的下标this.down = false; // 用于判断是否碰撞this.candel = false; // 用于判断是否爆炸完成//绘制方法this.paint = function() { ctx.drawImage(this.imgs[this.startIndex], this.x, this.y);};//运动方法this.step = function() { if (!this.down) { // 敌方飞机处于正常状态// 小飞机,中飞机的下标始终都是0// 大飞机的下标是在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.checkHit = function(wo) { //判断四个边 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;};//敌方飞机碰撞后this.bang = function() { this.life--; if (this.life === 0) {this.down = true;score += this.score; }} }; // 数组存放敌方飞机 var enemise = []; // 往敌方飞机数组中添加数据 function enterEnemise() {var rand = Math.floor(Math.random() * 100)if (rand < 10) { // 添加小飞机 enemise.push(new Enemy(ENEMY1));} else if (rand < 55 && rand > 50) { // 添加中飞机 enemise.push(new Enemy(ENEMY2));} else if (rand === 88) { // 添加大飞机 if (enemise[0].type !== 3 && enemise.length > 0) {enemise.splice(0, 0, new Enemy(ENEMY3)); }} }; // 绘制敌方飞机函数 function enemyPaint() {for (var i = 0; i < enemise.length; i++) { enemise[i].paint();} }; // 敌方飞机的运动函数 function enemyStep() {for (var i = 0; i < enemise.length; i++) { enemise[i].step();} }; // 删除敌方飞机函数 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) }} }; // 碰撞以后的函数 function hitEnemise() {for (var i = 0; i < enemise.length; i++) { // 如果我放飞机撞到了敌方飞机以后 if (enemise[i].checkHit(hero)) {// 敌方飞机碰撞后,碰撞状态改变enemise[i].bang();// 我方飞机碰撞后,碰撞状态改变hero.bang(); }; // 子弹碰到敌方飞机 for (var j = 0; j < bullets.length; j++) {if (enemise[i].checkHit(bullets[j])) { enemise[i].bang(); // 子弹的碰撞后,碰撞状态改变 bullets[j].bang();} }} };
最后的收尾阶段
// 绘制分数和生命值 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;} }; // 调用画布的鼠标移入事件 canvas.onmouseover = function() {if (state === pause) { state = running;} }; // 暂停图片 var pause = new Image() pause.src = 'https://www.haobala.com/bcjs/img/game_pause_nor.png'; // 游戏结束 function gameoverfn() {ctx.font = '50px bold'ctx.fillText('GAME OVER !!!', 80, 300);ctx.fillText('ONCE MORE !!!', 80, 400); }; // 画布点击事件 canvas.addEventListener('click', function(e) {p = getEventPosition(e);// 点击画布时,判断游戏是否开始if (state === start) { state = starting;}console.log(123);// 重新开始游戏有问题???if (state === gameover) { if (p.y >= 350 && p.y < 450) {console.log(’你点击了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}; };
后面就是基本的每个阶段的调用问题叻
setInterval(function() {//背景图片无论在哪个状态都有背景图片以及它的动态效果sky.paint(); // 绘制背景sky.step(); // 背景动画if (state === start) { // 第一阶段 ctx.drawImage(logo, 35, 0)} else if (state === starting) { // 第二阶段 loading.paint(); // 绘制背景 loading.step(); // 背景动画} else if (state === running) { // 第三状态 // 绘制我放飞机 hero.paint(); // 我方飞机的运动 hero.step(); // 我方飞机的射击方法 hero.shoot(); // 子弹的绘制 bulletdPaint(); // 子弹的运动 bulletdStep(); // 子弹的删除 bulletDel(); // 创建敌方飞机 enterEnemise(); // 绘制敌方飞机 enemyPaint(); // 绘制敌方飞机的运动 enemyStep(); // 删除敌方飞机 delenemy(); // 判断是否撞击 hitEnemise(); // 绘制分数和生命值 scoreText()} else if (state === pause) { // 第四状态 sky.paint(); // 绘制背景 sky.step(); // 背景动画 // 绘制我放飞机 hero.paint(); // 子弹的绘制 bulletdPaint(); // 绘制敌方飞机 enemyPaint(); // 绘制分数和生命值 scoreText(); ctx.drawImage(pause, 220, 300)} else if (state === gameover) { // 第五状态 sky.paint(); // 绘制背景 sky.step(); // 背景动画 hero.paint(); // 子弹的绘制 bulletdPaint(); // 绘制敌方飞机 enemyPaint(); // 绘制分数和生命值 scoreText(); // 游戏结束 gameoverfn();} }, 10)})()
这个也就是飞机大战的全部源码了,仅供参考。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持好吧啦网。
相关文章: