用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 相关文章推荐
为radio类型的INPUT添加客户端脚本(附加实现JS来禁用onClick事件思路代码)
Nov 11 Javascript
Google的跟踪代码 动态加载js代码方法应用
Nov 12 Javascript
js使用eval解析json实例与注意事项分享
Jan 18 Javascript
判断某个字符在一个字符串中是否存在的js代码
Feb 28 Javascript
javascript小数精度丢失的完美解决方法
May 31 Javascript
Bootstrap被封装的弹层
Jul 20 Javascript
重新理解JavaScript的六种继承方式
Mar 24 Javascript
jQuery实现点击下拉框中的值累加到文本框中的方法示例
Oct 28 jQuery
原生JS写Ajax的请求函数功能
Dec 22 Javascript
vue iview实现动态路由和权限验证功能
Apr 17 Javascript
小程序转发探索示例
Feb 19 Javascript
Node.js折腾记一:读指定文件夹,输出该文件夹的文件树详解
Apr 20 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
Search File Contents PHP 搜索目录文本内容的代码
2010/02/21 PHP
php利用cookie实现访问次数统计代码
2011/05/19 PHP
thinkphp 一个页面使用2次分页的实现方法
2013/07/15 PHP
ThinkPHP水印功能实现修复PNG透明水印并增加JPEG图片质量可调整
2014/11/05 PHP
PHP之认识(二)关于Traits的用法详解
2019/04/11 PHP
php使用Swoole实现毫秒级定时任务的方法
2020/09/04 PHP
传智播客学习之JavaScript基础篇
2009/11/13 Javascript
JavaScript高级程序设计 读书笔记之九 本地对象Array
2012/02/27 Javascript
一个简单的瀑布流效果(主体形式自写)
2013/05/27 Javascript
js获取页面及个元素高度、宽度的代码
2016/04/26 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
2016/07/25 Javascript
JavaScript中object和Object的区别(详解)
2017/02/27 Javascript
微信小程序上传图片到服务器实例代码
2017/11/07 Javascript
JS设计模式之观察者模式实现实时改变页面中金额数的方法
2018/02/05 Javascript
详解基于React.js和Node.js的SSR实现方案
2019/03/21 Javascript
对TypeScript库进行单元测试的方法
2019/07/18 Javascript
详解ES6新增字符串扩张方法includes()、startsWith()、endsWith()
2020/05/12 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
[02:25]DOTA2英雄基础教程 生死判决瘟疫法师
2013/12/06 DOTA
[10:18]2018DOTA2国际邀请赛寻真——找回自信的TNCPredator
2018/08/13 DOTA
Python的socket模块源码中的一些实现要点分析
2016/06/06 Python
Python基于回溯法子集树模板解决0-1背包问题实例
2017/09/02 Python
轻量级的Web框架Flask 中模块化应用的实现
2017/09/11 Python
Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解
2018/09/04 Python
基于python实现学生管理系统
2018/10/17 Python
PYTHON实现SIGN签名的过程解析
2019/10/28 Python
探秘TensorFlow 和 NumPy 的 Broadcasting 机制
2020/03/13 Python
入党申请书自我鉴定
2013/10/12 职场文书
会计电算一体化个人简历的自我评价
2013/10/15 职场文书
初婚未育证明
2014/01/15 职场文书
护士上岗前培训自我鉴定
2014/04/20 职场文书
合伙协议书
2014/04/23 职场文书
采购部长岗位职责
2014/06/13 职场文书
财务部会计岗位职责
2015/02/03 职场文书
爱牙日宣传活动总结
2015/02/05 职场文书
利用html+css实现菜单栏缓慢下拉效果的示例代码
2021/03/30 HTML / CSS