用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 相关文章推荐
jQuery实现鼠标滑过点击事件音效试听
Aug 31 Javascript
jQuery学习心得总结(必看篇)
Jun 10 Javascript
JavaScript解八皇后问题的方法总结
Jun 12 Javascript
利用vue写todolist单页应用
Dec 15 Javascript
完美解决input[type=number]无法显示非数字字符的问题
Feb 28 Javascript
php简单数据库操作类的封装
Jun 08 Javascript
深入浅析Node.js单线程模型
Jul 10 Javascript
浅谈AngularJs 双向绑定原理(数据绑定机制)
Dec 07 Javascript
JS对象与json字符串相互转换实现方法示例
Jun 14 Javascript
layui 给数据表格加序号的方法
Aug 20 Javascript
详解JavaScript匿名函数和闭包
Jul 10 Javascript
vue打开其他项目页面并传入数据详解
Nov 25 Vue.js
原生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 面向对象实现代码
2009/11/11 PHP
PHP闭包实例解析
2014/09/08 PHP
Yii2单元测试用法示例
2016/11/12 PHP
PHP 根据key 给二维数组分组
2016/12/09 PHP
微信公众平台开发教程②微信端分享功能图文详解
2019/04/10 PHP
JavaScript入门教程 Cookies
2009/01/31 Javascript
jquery1.5.1中根据元素ID获取元素对象的代码
2011/04/02 Javascript
js中document.write使用过程中的一点疑问解答
2014/03/20 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
2015/03/16 Javascript
JS模式之单例模式基本用法
2015/06/30 Javascript
jQuery设置Cookie及删除Cookie实例分析
2016/04/15 Javascript
JS 在数组指定位置插入/删除数据的方法
2017/01/12 Javascript
微信小程序实现给循环列表添加点击样式实例
2017/04/26 Javascript
angular+webpack2实战例子
2017/05/23 Javascript
vue--点击当前增加class,其他删除class的方法
2018/09/15 Javascript
node.js的Express服务器基本使用教程
2019/01/09 Javascript
js的新生代垃圾回收知识点总结
2019/08/22 Javascript
Javascript ParentNode和ChildNode接口原理解析
2020/03/16 Javascript
JavaScript实现拖动对话框效果的实现代码
2020/10/12 Javascript
python使用PIL实现多张图片垂直合并
2019/01/15 Python
python itchat实现调用微信接口的第三方模块方法
2019/06/11 Python
Ubuntu16安装Python3.9的实现步骤
2020/12/15 Python
Python实现给PDF添加水印的方法
2021/01/25 Python
衰败城市英国官网:Urban Decay英国
2020/04/29 全球购物
为什么在使用动态 SQL 语句时必须为低层数据库对象授予权限
2012/12/13 面试题
一道写SQL的面试题和答案
2013/11/19 面试题
计算机本科生自荐信
2013/10/15 职场文书
主管职责范文
2013/11/09 职场文书
《愚公移山》教学反思
2014/02/20 职场文书
财务总监岗位职责
2014/03/07 职场文书
网吧七夕活动策划方案
2014/08/31 职场文书
Nginx如何配置Http、Https、WS、WSS的方法步骤
2021/05/11 Servers
mysql连接查询中and与where的区别浅析
2021/07/01 MySQL
mysql数据库实现设置字段长度
2022/06/10 MySQL
ConditionalOnProperty配置swagger不生效问题及解决
2022/06/14 Java/Android
MySQL数据库实验实现简单数据库应用系统设计
2022/06/21 MySQL