用JS实现飞机大战小游戏


Posted in Javascript onJune 09, 2021

本文实例为大家分享了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 = "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 = "img/start.png";
            // 游戏加载过程的4张图片存入一个数组中
            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,
            };
            // 构造函数
            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 = "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
            };
            // 我方飞机的构造函数
            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 = "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; // 设计速度初始为0
                this.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 = "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 = "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 = []; //大飞机
            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";
            // 初始化数据
            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 = "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)
        })()

这个也就是飞机大战的全部源码了,仅供参考。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript原型链继承用法实例分析
Jan 28 Javascript
浅析javascript中的DOM
Mar 01 Javascript
JS实现为排序好的字符串找出重复行的方法
Mar 02 Javascript
JavaScript模拟鼠标右键菜单效果
Dec 08 Javascript
jQuery leonaScroll 1.1 自定义滚动条插件(推荐)
Sep 17 Javascript
JS实现最简单的冒泡排序算法
Feb 15 Javascript
node.js实现回调的方法示例
Mar 01 Javascript
解决JavaScript layui 下拉框不显示的问题
Aug 14 Javascript
React+Antd+Redux实现待办事件的方法
Mar 14 Javascript
详解nvm管理多版本node踩坑
Jul 26 Javascript
vue 实现LED数字时钟效果(开箱即用)
Dec 08 Javascript
Ant Design Pro 之 ProTable使用操作
Oct 31 Javascript
原生JS实现飞机大战小游戏
解决Vue+SpringBoot+Shiro跨域问题
Jun 09 #Vue.js
JavaScript如何优化逻辑判断代码详解
Jun 08 #Javascript
浅谈react useEffect闭包的坑
Vue中插槽slot的使用方法与应用场景详析
vue+elementui 实现新增和修改共用一个弹框的完整代码
解决vue $http的get和post请求跨域问题
You might like
超级好用的一个php上传图片类(随机名,缩略图,加水印)
2010/06/30 PHP
php从右向左/从左向右截取字符串的实现方法
2011/11/28 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
javascript中的作用域scope介绍
2010/12/28 Javascript
jQuery表格行换色的三种实现方法
2011/06/27 Javascript
Javascript和HTML5利用canvas构建Web五子棋游戏实现算法
2013/07/17 Javascript
JavaScript中创建类/对象的几种方法总结
2013/11/29 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
2014/02/19 Javascript
Nodejs全栈框架StrongLoop推荐
2014/11/09 NodeJs
jQuery类选择器用法实例
2014/12/23 Javascript
JS长整型精度问题实例分析
2015/01/13 Javascript
BootStrap 附加导航组件
2016/07/22 Javascript
jquery 动态合并单元格的实现方法
2016/08/26 Javascript
node.js中路由,中间件,ge请求和post请求的参数详解
2017/12/26 Javascript
微信小程序动态增加按钮组件
2018/09/14 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
使用ThinkJs搭建微信中控服务的实现方法
2019/08/08 Javascript
用Node写一条配置环境的指令
2019/11/14 Javascript
ESLint 是如何检查 .vue 文件的
2020/11/30 Vue.js
vue组件中节流函数的失效的原因和解决方法
2020/12/02 Vue.js
Python发送以整个文件夹的内容为附件的邮件的教程
2015/05/06 Python
python从sqlite读取并显示数据的方法
2015/05/08 Python
对python3.4 字符串转16进制的实例详解
2019/06/12 Python
Python Pandas对缺失值的处理方法
2019/09/27 Python
python解析命令行参数的三种方法详解
2019/11/29 Python
Python Tkinter实例——模拟掷骰子
2020/10/24 Python
利于python脚本编写可视化nmap和masscan的方法
2020/12/29 Python
Opodo英国旅游网站:预订廉价航班、酒店和汽车租赁
2018/07/14 全球购物
MIKI HOUSE美国官方网上商店:日本领先的婴儿和儿童高级时装品牌
2020/06/21 全球购物
应届生财务会计求职信
2013/11/05 职场文书
青春演讲稿范文
2014/05/08 职场文书
贫困证明书格式及范文
2014/10/15 职场文书
2014收银员工作总结范文
2014/12/16 职场文书
教师岗位职责范本
2015/04/02 职场文书
Win11 引入 Windows 365 云操作系统,适应疫情期间混合办公模式:启动时直接登录、模
2022/04/06 数码科技
详细介绍MySQL中limit和offset的用法
2022/05/06 MySQL