用JS实现飞机大战小游戏

2021-06-09 32 joyouscola

本文实例为大家分享了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文章

js 数值转换为3位逗号分隔的示例代码
Feb 19 16
javascript学习笔记之函数定义
Jun 25 18
jquery mobile移动端幻灯片滑动切换效果
Apr 15 17
JS把字符串格式的时间转换成几秒前、几分钟前、几小时前、几天前等格式
Jul 10 35
Element Alert警告的具体使用方法
Jul 27 22
vue中template的三种写法示例
Oct 21 15
vue实现轮播图帧率播放
Jan 26 38
手机访问当前页面