美文网首页
JavaScript打飞机小游戏

JavaScript打飞机小游戏

作者: 终身成长人格 | 来源:发表于2019-10-09 10:23 被阅读0次

    又到了每日分享时间了,今天分享的内容为:JavaScript打飞机小游戏

    效果图:

    20191009101114.jpg

    实现逻辑:

    第一步:实现页面的排版、布局

    1.1 准备打飞机游戏需要使用到的图片

    1.2 开始游戏界面

    1.3 进入游戏的界面

    1.3.1 己方飞机

    1.3.2 敌方飞机

    1.3.3 己方飞机发射的子弹

    第二步:开始游戏

    2.1 点击开始游戏按钮,进入到游戏界面

    2.2 摁下空格键,实现己方飞机跟随鼠标的移动==》游戏的开始

    2.3 第二次摁下空格键时,实现己方飞机的暂停移动==》游戏的暂停

    2.4 以此类推,实现开始和暂停的交换

    第三步:开始游戏之后的发射子弹

    3.1 定时创建子弹:

    3.1.1 单位时间内创建子弹的数量

    3.1.2 开始游戏和暂停游戏时:暂停游戏后,不能再创建子弹;再次开始游戏时,不能存在多个创建子弹的定时器==》把上一次创建子弹的定时器给清除或者不再开启定时器

    3.2 制造子弹

    3.2.1 制造子弹时,确定子弹的位置

    3.2.2 根据当前己方飞机的位置

    3.2.3 把子弹追加到文档中去

    3.3 子弹的运动

    3.3.1 子弹的top值是-子弹的高度时,删除子弹,清除定时器

    3.4 子弹消失

    3.4.1 子弹飞出游戏界面

    3.4.2 清除子弹==》每一颗飞出到游戏界面之外的子弹,肯定是第一个创建的子弹(当前子弹所在父元素下的第一个子元素)

    第四步:开始游戏之后的创建敌机

    4.1 定时创建敌机

    4.1.1 单位时间内创建敌机的数量

    4.1.2 暂停之后不能重复性的开启创建敌机的定时器

    4.1.3 敌机的概率出现:大、中、小三种敌机

    ===》小:75% 中:20% 大:5%

    4.2 制造敌机

    4.3 敌机的运动

    4.4 敌机的消失

    第五步:实现游戏的暂停

    5.1 敌机运动速度的控制

    5.2 实现游戏的暂停

    5.2.1 清除己方飞机的移动

    5.2.2 清除创建敌机

    5.2.3 清除创建子弹

    5.2.4 清除每颗子弹上的运动

    5.2.5 清除每架敌机上的运动

    第六步:实现开始游戏之后的背景图的运动

    6.1 改变的是背景图的background-position-y的值

    6.2 游戏界面的高度568,每运动568px是一个循环

    第七步:检测子弹和敌机的碰撞

    7.1 每一个敌机都是运动的,每一颗子弹也是运动的==》在每一架敌机运动时,检测和所有游戏界面内存在的子弹的碰撞

    7.2 创建全局变量:把当前游戏界面内存在的所有的子弹放入到该变量里

    7.3 敌机运动的过程中,检测和每一颗子弹的碰撞

    7.4 子弹和敌机发生碰撞时,子弹消失

    7.4.1 把该子弹元素删除掉

    7.4.2 把该子弹元素从全局变量集合里删除

    7.5 敌机和子弹发生碰撞时,敌机血量减少==》每一颗子弹消耗的血量100

    7.6 敌机的血量为0时,删除敌机元素???

    第八步:实现敌机的爆炸效果

    8.1 替换爆炸图片

    8.2 区分存活的敌机和死亡敌机(爆炸过程中的敌机)==》标记每一架敌机的存活状态

    8.3 延时删除敌机元素==》显示爆炸效果

    8.4 在创建敌机时,删除敌机集合中的死亡敌机

    第九步:实现游戏的得分

    第十步:检测己方飞机和敌机的碰撞

    10.1 一对多的关系:敌机运动,己方飞机运动

    10.2 在每一架敌机运动的过程中检测

    10.3 碰撞的原理

    第十一步:游戏结束

    11.1 清除掉当前页面上的所有的定时器

    11.2 清除掉所有子弹上的定时器以及删除所有的子弹元素

    11.3 清除掉素有敌机上的定时器以及删除所有的敌机元素

    11.4 清空子弹和敌机的集合

    11.5 删除己方飞机上的移动事件

    11.6 回到游戏开始界面

    一、html代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>javascript 原生打飞机游戏</title>
        <link rel="stylesheet" href="style.css">
        <script src="plane.js"></script>
    </head>
    <body>
        <div id="game">
            <div id="gameStart">
                <span>开始游戏</span>
            </div>
            <div id="gameEnter">
                <div id="myPlane">
                    <img src="image/my.gif" alt="">
                </div>
                <div id="bullets">
                </div>
                <div id="enemys"></div>
                <div id="scores">
                    <p>得分:<span>0</span> 分</p>
                </div>
            </div>
        </div>
    </body>
    </html>
    

    二、css代码

    *{
        margin: 0;
        padding: 0;
    }
    #game{
        width: 320px;
        height: 568px;
        margin: auto;
        overflow: hidden;
    }
    #gameStart{
        width: 100%;
        height: 100%;
        background: url(image/ks.png);
        position: relative;
        /*display: none;*/
    }
    #gameStart span{
        width: 160px;
        height: 40px;
        display: block;
        background: rgba(196,201,202);
        border: 4px solid #666;
        box-sizing: border-box;
        text-align: center;
        line-height: 32px;
        font-size: 24px;
        font-weight: bolder;
        position: absolute;
        left: 80px;
        bottom: 200px;
        cursor: pointer;
    }
    #gameStart span:hover{
        color: #fff;
    }
    #gameEnter{
        width: 100%;
        height: 100%;
        background: url(image/background_1.png);
        position: relative;
        display: none;
    }
    #myPlane{
        width: 66px;
        height: 80px;
        position: absolute;
        left: 127px;
        bottom: 0;
        cursor: pointer;
    }
    #myPlane{
        width: 66px;
        height: 80px;
    }
    #myPlane img{
        cursor: move;
    }
    #bullets,#enemys{
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
    }
    .b{
        width: 6px;
        height: 14px;
        position: absolute;
    }
    .e{
        position: absolute;
    }
    #scores{
        width: 100%;
        height: 40px;
        line-height: 40px;
        font-size: 24px;
        font-weight: bolder;
        padding: 0 20px;
    }
    #scores p{
        text-align: right;
        width: 80%;
    }
    

    三、js代码

    ;window.onload = function(){
        // 获取标签元素的方法
        function $(idName){
            return document.getElementById(idName);
        }
        // 获取样式使用最终值的函数
        function getStyle(ele,attr){
            var res = null;
            if(ele.currentStyle){
                res = ele.currentStyle[attr];
            }else{
                res = window.getComputedStyle(ele,null)[attr];
            }
            return parseFloat(res);
        }
        // 获取需要使用到的标签元素
        var game = $("game")
        // 游戏开始的界面
        ,   gameStart = $("gameStart")
        // 进入游戏的界面
        ,   gameEnter = $("gameEnter")
        ,   myPlane = $("myPlane")
        ,   bulletsP = $("bullets")
        ,   enemysP = $("enemys")
        ,   s = $("scores").firstElementChild.firstElementChild;
        // 获取需要使用到的元素样式
        // 1、获取游戏界面的宽高
        var gameW = getStyle(game,"width")
        ,   gameH = getStyle(game,"height");
        // 2、游戏界面的左上外边距
        var gameML = getStyle(game,"marginLeft")
        ,   gameMT = getStyle(game,"marginTop");
        // 3、获取己方飞机的宽高
        var myPlaneW = getStyle(myPlane,"width")
        ,   myPlaneH = getStyle(myPlane,"height");
        // 4、子弹的宽高
        var bulletW = 6
        ,   bulletH = 14;
    
        // 声明需要使用到的全局变量
        var gameStatus = false // 当前的游戏状态
        ,   a = null // 创建子弹的定时器
        ,   b = null // 创建敌机的定时器
        ,   c = null // 背景图运动的定时器
        ,   backgroundPY = 0 // 背景图y轴的值
        ,   bullets = [] // 所有子弹元素的集合
        ,   enemys = [] // 所有敌机元素的集合
        ,   scores = 0 // 得分
        ;
    
    
        // 开始游戏
        gameStart.firstElementChild.onclick = function(){
            gameStart.style.display = "none";
            gameEnter.style.display = "block";
            // 给当前的文档添加键盘事件
            document.onkeyup = function(evt){
                var e = evt || window.event;
                // 获取到键盘的键值
                var keyVal = e.keyCode;
                if(keyVal == 32){
                    if(!gameStatus){
                        // 初始化得分
                        scores = 0;
                        // 开始游戏
                        this.onmousemove = myPlaneMove;
                        // 实现开始游戏之后背景图的运动
                        bgMove();
                        // 实现射击
                        shot();
                        // 出现敌机
                        appearEnemy();
                        // 暂停游戏之后的开始游戏
                        // 子弹的继续运动
                        if(bullets.length != 0) reStart(bullets,1);
                        // 敌机的继续运动
                        if(enemys.length != 0) reStart(enemys);
                    }else{
                        // 暂停游戏
                        this.onmousemove = null;
                        // 清除创建敌机和创建子弹的定时器
                        clearInterval(a);
                        clearInterval(b);
                        clearInterval(c);
                        a = null;
                        b = null;
                        c = null;
                        // 清除所有子弹和所有敌机上的运动定时器
                        clear(bullets);
                        clear(enemys);
                    }
                    gameStatus = !gameStatus;
                }
            }
        }
        // 己方飞机的移动
        function myPlaneMove(evt){
            var e = evt || window.event;
            // 获取鼠标移动时的位置
            var mouse_x = e.x || e.pageX
            ,   mouse_y = e.y || e.pageY;
    
            // 计算得到鼠标移动时己方飞机的左上边距
            var last_myPlane_left = mouse_x - gameML - myPlaneW/2
            ,   last_myPlane_top = mouse_y - gameMT - myPlaneH/2;
            // 控制飞机不能脱离当前的游戏界面
            if(last_myPlane_left <= 0){
                last_myPlane_left = 0;
            }else if(last_myPlane_left >= gameW - myPlaneW){
                last_myPlane_left = gameW - myPlaneW;
            }
            if(last_myPlane_top <= 0){
                last_myPlane_top = 0;
            }else if(last_myPlane_top >= gameH - myPlaneH){
                last_myPlane_top = gameH - myPlaneH;
            }
            myPlane.style.left = last_myPlane_left + "px";
            myPlane.style.top = last_myPlane_top + "px";
        }
        // 单位时间内创建子弹
        function shot(){
            if(a) return ;
            a = setInterval(function(){
                // 创建子弹
                createBullet();
            },100);
        }
        // 制造子弹
        function createBullet(){
            var bullet = new Image();
            bullet.src = "image/bullet1.png";
            bullet.className = "b";
            // 创建每一颗子弹都需要确定己方飞机的位置:
            var myPlaneL = getStyle(myPlane,"left")
            ,   myPlaneT = getStyle(myPlane,"top");
            // 确定创建子弹的位置
            var bulletL = myPlaneL + myPlaneW/2 - bulletW/2
            ,   bulletT = myPlaneT - bulletH;
    
            bullet.style.left = bulletL + "px";
            bullet.style.top = bulletT + "px";
            bulletsP.appendChild(bullet);
            bullets.push(bullet);
            move(bullet,"top");
        }
        // 子弹的运动:运动函数(匀速运动)
        function move(ele,attr){
            var speed = -8;
            ele.timer = setInterval(function(){
                var moveVal = getStyle(ele,attr);
                // 子弹运动出游戏界面:清除子弹的定时器,删除子弹元素
                if(moveVal <= -bulletH){
                    clearInterval(ele.timer);
                    ele.parentNode.removeChild(ele);
                    bullets.splice(0,1);
                }else{
                    ele.style[attr] = moveVal + speed + "px";
                }
            },10);
        }
        // 创建敌机数据对象
        var enemysObj = {
            enemy1: {
                width: 34,
                height: 24,
                score: 100,
                hp: 100
            },
            enemy2: {
                width: 46,
                height: 60,
                score: 500,
                hp: 800
            },
            enemy3: {
                width: 110,
                height: 164,
                score: 1000,
                hp: 2000
            }
        }
        // 创建敌机的定时器
        function appearEnemy(){
            if(b) return ;
            b = setInterval(function(){
                // 制造敌机
                createEnemy();
                // 删除死亡敌机
                delEnemy();
            },1000);
        }
        // 制造敌机的函数
        function createEnemy(){
            // 敌机出现概率的数据
            var percentData = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3];
            // 敌机的类型
            var enemyType = percentData[Math.floor(Math.random()*percentData.length)];
            // 得到当前随机敌机的数据
            var enemyData = enemysObj["enemy" + enemyType];
            // 创建敌机所在的元素
            var enemy = new Image(enemyData.width,enemyData.height);
            enemy.src = "image/enemy" + enemyType + ".png";
            enemy.t = enemyType;
            enemy.score = enemyData.score;
            enemy.hp = enemyData.hp;
            enemy.className = "e";
            enemy.dead = false; // 敌机存活
            // 确定当前敌机出现时的位置
            var enemyL = Math.floor(Math.random()*(gameW - enemyData.width + 1))
            ,   enemyT = -enemyData.height;
            enemy.style.left = enemyL + "px";
            enemy.style.top = enemyT + "px";
            enemysP.appendChild(enemy);
            enemys.push(enemy);
            enemyMove(enemy,"top");
        }
        // 敌机的运动
        function enemyMove(ele,attr){
            var speed = null;
            if(ele.t == 1){
                speed = 1.5;
            }else if(ele.t == 2){
                speed = 1;
            }else if(ele.t == 3){
                speed = 0.5;
            }
            ele.timer = setInterval(function(){
                var moveVal = getStyle(ele,attr);
                if(moveVal >= gameH){
                    clearInterval(ele.timer);
                    enemysP.removeChild(ele);
                    enemys.splice(0,1);
                }else{
                    ele.style[attr] = moveVal + speed + "px";
                    // 每一架敌机运动时,检测和每一颗子弹的碰撞
                    danger(ele);
                    // 检测碰撞
                    gameOver();
                }
            },10);
        }
        // 清除所有敌机和所有子弹上的运动定时器
        function clear(childs){
            for(var i=0;i<childs.length;i++){
                clearInterval(childs[i].timer);
            }
        }
        // 暂停游戏之后的开始游戏
        function reStart(childs,type){
            for(var i=0;i<childs.length;i++){
                type == 1 ? move(childs[i],"top") : enemyMove(childs[i],"top");
            }
        }
        // 开始游戏之后的背景图的运动
        function bgMove(){
            c = setInterval(function(){
                backgroundPY += 0.5;
                if(backgroundPY >= gameH){
                    backgroundPY = 0;
                }
                gameEnter.style.backgroundPositionY = backgroundPY + "px";
            },10);
        }
        // 检测子弹和敌机的碰撞
        function danger(enemy){
            for(var i=0;i<bullets.length;i++){
                // 得到子弹的左上边距
                var bulletL = getStyle(bullets[i],"left")
                ,   bulletT = getStyle(bullets[i],"top");
                // 得到敌机的左上边距
                var enemyL = getStyle(enemy,"left")
                ,   enemyT = getStyle(enemy,"top");
                // 得到敌机的宽高
                var enemyW = getStyle(enemy,"width")
                ,   enemyH = getStyle(enemy,"height");
                var condition = bulletL + bulletW >= enemyL && bulletL <= enemyL + enemyW && bulletT <= enemyT + enemyH && bulletT + bulletH >= enemyT;
                if(condition){
                    //子弹和敌机的碰撞:删除子弹
                    // 1、先清除碰撞子弹的定时器
                    clearInterval(bullets[i].timer);
                    // 2、删除元素
                    bulletsP.removeChild(bullets[i]);
                    // 3、从集合中删除子弹
                    bullets.splice(i,1);
                    // 4、子弹和敌机发生碰撞后,敌机血量减少,血量为0时,删除敌机
                    enemy.hp -= 100;
                    if(enemy.hp == 0){
                        // 删除敌机
                        clearInterval(enemy.timer);
                        // 替换爆炸图片 
                        enemy.src = "image/bz" + enemy.t + ".gif";
                        // 标记死亡敌机
                        enemy.dead = true;
                        // 计算得分
                        scores += enemy.score;
                        s.innerHTML = scores;
                    }
                }
            }
        }
        // 在创建敌机时,延时删除掉集合和文档中的死亡敌机
        function delEnemy(){
            for(var i=enemys.length - 1;i>=0;i--){
                if(enemys[i].dead){
                    (function(index){
                        // 从文档中删除死亡敌机元素
                        enemysP.removeChild(enemys[index]);
                        // 从集合中删除死亡敌机元素
                        enemys.splice(index,1);
                    })(i)
                }
            }
        }
        // 飞机碰撞,游戏结束
        function gameOver(){
            for(var i=0;i<enemys.length;i++){
                if(!enemys[i].dead){ // 游戏机界面内存活的敌机
                    // 检测碰撞
                    // 1、获取敌机的左上边距
                    var enemyL = getStyle(enemys[i],"left")
                    ,   enemyT = getStyle(enemys[i],"top");;
                    // 2、获取敌机的宽高
                    var enemyW = getStyle(enemys[i],"width")
                    ,   enemyH = getStyle(enemys[i],"height");
                    // 3、获取己方飞机的左上边距
                    var myPlaneL = getStyle(myPlane,"left")
                    ,   myPlaneT = getStyle(myPlane,"top");
                    var condition = myPlaneL + myPlaneW >= enemyL && myPlaneL <= enemyL + enemyW && myPlaneT <= enemyT + enemyH && myPlaneT + myPlaneH >= enemyT;
                    if(condition){ // 己方飞机和敌机的碰撞
                        // console.log("碰撞了...");
                        // 清除定时器:创建子弹的定时器、创建飞机的定时器、游戏背景图的定时器
                        clearInterval(a);
                        clearInterval(b);
                        clearInterval(c);
                        a = null;
                        b = null;
                        c = null;
                        // 删除子弹和敌机元素
                        remove(bullets);
                        remove(enemys);
                        // 集合清空
                        bullets = [];
                        enemys = [];
                        // 清除己方飞机的移动事件
                        document.onmousemove = null;
                        // 提示得分:
                        alert("Game over: " + scores + "分");
                        // 回到游戏开始界面
                        gameStart.style.display = "block";
                        gameEnter.style.display = "none";
                        myPlane.style.left = "127px";
                        myPlane.style.top = gameH - myPlaneH + "px";
                    }
                }
            }
        }
        // 删除元素
        function remove(childs){
            for(var i = childs.length - 1;i>=0;i--){
                clearInterval(childs[i].timer);
                childs[i].parentNode.removeChild(childs[i]);
            }
        }
    }
    

    老规矩,附带教学视频:https://www.3mooc.com/front/couinfo/214

    相关文章

      网友评论

          本文标题:JavaScript打飞机小游戏

          本文链接:https://www.haomeiwen.com/subject/ekmwpctx.html