1. 程式人生 > >基於原生JS的坦克大戰遊戲

基於原生JS的坦克大戰遊戲

主要含有以下功能:

1、玩家採用等級機制,共5級;

2、補充裝備有子彈、金星、炸彈、導彈、手槍、戰艦,分值各不相同;

3、打掉障礙可加分;

4、用滑鼠控制子彈射擊,左鍵為單發射擊、右鍵為雙發射擊,遮蔽滑鼠右鍵預設的選單;

5、空格鍵控制導彈射擊,遮蔽其他鍵的使用;

6、沒有戰艦的情況下無法過河,子彈不能擊打鋼鐵,坦克可以穿梭于于樹林之中,坦克經過雪地速度會打滑速度變快;

7、坦克碰到障礙不能前進;

8、導彈可以摧毀一切,可謂是寸草不生;

9、坦克可以進行上下左右掉頭,坦克碰到障礙物掉頭、轉彎是本案例的難點;

10、子彈打到螢幕邊界、鋼鐵有子彈效果;

11、障礙物有的1槍則可以摧毀,有的需要多槍才可以完全摧毀;

12、吃到裝備有分值提示效果;

13、吃了手槍可以打鐵。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>坦克大戰</title>
    <link rel="icon" type="image/x-icon" href="tank.jpg">
    <style>
        *{
            padding: 0;
            margin: 0;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            -o-user-select: none;
            user-select: none;
        }
        body{
            background: #222;
            opacity: 0.9;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        #target{
            position: absolute;
            z-index: 2;
        }
        .bullet{
            width: 10px;
            height: 10px;
            background: #fff;
            position: relative;
            border-radius: 5px;
        }
        .missile{
            background: #fff;
            position: relative;
            border-radius: 12px;
        }
        #tip{
            min-height: 10px;
            z-index: 1001;
            position: absolute;
            display: inline;
            /*margin-left: -55px;*/
            padding: 5px;
            visibility:hidden;
            opacity: 0;
            margin-top: -12px;
            background: #ffffff;
            font-size:1em;
            
            /* Setting the border-radius property for all Browsers */
            -moz-border-radius: 5px; /* Firefox */
            -webkit-border-radius: 5px; /* Safari and Chrome */
            border-radius: 5px; /* Browsers that Support it like Opera */
            
            /* Setting the box-shadow property for all Browsers */
            -moz-box-shadow: 0 0 8px gray; /* Firefox */
            -webkit-box-shadow: 0 0 8px gray; /* Safari and Chrome */
            filter: progid:DXImageTransform.Microsoft.Shadow(color='#272229', Direction=135, Strength=3); /* IE */
            box-shadow: 0 0 8px gray; /* Browsers that Support it like Opera */


            /* Setting the transition property for all Browsers */
            -moz-transition: all 0.5s ease-in-out; /* Firefox */
            -webkit-transition: all 0.5s ease-in-out; /* Safari and Chrome */
            -o-transition: all 0.5s ease-in-out; /* Opera */
            transition: all 0.5s ease-in-out; /* Browsers that Support it */
        }


        #score_list{
            background: #fff;
            bottom: 0;
            right: 0;
            position: absolute;
            width: 270px;
            height: 365px;
            z-index: 999;
            opacity: 0.5;
            color:#222;
            padding: 3px;
            border-radius: 3px;
        }
        #list-name{
            text-align: center;
            font-size: 18px;
        }
        #score_list div{
            margin: 3px;
        }
        #time{
            width: 670px;
            height: 513px;
            position: absolute;
            top: 50%;   
            left: 50%;   
            -webkit-transform: translate(-50%, -50%);   
            -moz-transform: translate(-50%, -50%);   
            -ms-transform: translate(-50%, -50%);   
            -o-transform: translate(-50%, -50%);   
            transform: translate(-50%, -50%);
            z-index: 1000;
            display: none;
        }
        #demo1,#demo2{
            position: absolute;
        }
        #demo1{
            top:302px;
            left:220px;
            width: 20px;
            height: 40px;
            background: #000;
        }
        #demo2{
            top:225px;
            left:225px;
            width: 80px;
            height: 80px;
            background: #111;
        }
    </style>
</head>
<body>
    <img id="target" src="tank1.jpg" width="60" height="60" alt="">
    <img id="time" src="time.jpg" height="641" width="837" alt="" />
    <div id="score_list">
        <div id="list-name"><strong >英雄榜</strong></div>
        <div>玩家名字:<strong id="player_name">sensus森森</strong></div>
        <div>玩家等級:<strong id="player_level">小米加步槍</strong></div>
        <div>剩餘時間:<strong id="remaining_time">0</strong></div>
        <div>當前時間:<strong id="current_time"></strong></div>
        <div>開始時間:<strong id="start_time"></strong></div>
        <div>子彈:<strong id="bullet_total_nums">100</strong></div>
        <div>導彈:<strong id="missile_num">0</strong></div>
        <div>手槍:<strong id="gun_number">0</strong></div>
        <div>五角星:<strong id="star_number">0</strong></div>
        <div>炸彈:<strong id="bomb_number">0</strong></div>
        <div>戰艦:<strong id="warship_number">0</strong></div>
        <div>障礙:<strong id="exterminate_obstacles_nums">0</strong></div>
        <div>總分數:<strong id="total_scores">0</strong></div>
        <div>本機IP:<strong id="localhost">0</strong></div>
    </div>
    <!-- 使用的搜狐介面、JS獲取客戶端IP地址 -->
    <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> 
    <script>        
        document.oncontextmenu = new Function("event.returnValue=false;");//禁用網頁右鍵選單
    
        var direction = 'right',
            oImg = document.getElementById('target'),
            obstacles= document.getElementsByName('obstacle'),//獲得所有的障礙物
            img_width = oImg.clientWidth,
            img_height = oImg.clientHeight,
            screen_width = window.innerWidth,//document.documentElement.clientWidth/Height 和 window.innerWidth/Height 的寬高始終相等
            screen_height = window.innerHeight;
            makeTankObstacle();//生成坦克障礙
            equipmentScore = makeTankEquipment();
            tankAndObstaclesCountObj = Object;//使用指標
            bulletAndObstaclesCountObj = tankAndObstaclesCountObj;
            tankAndObstaclesCountObj.obstaclesCount = obstacles.length;//障礙物數量
            localStorage.clear();//清空所有的localStorage儲存物件的全部資料
        
        //鍵盤繫結事件
        document.onkeydown = function(e){
            var tank_left = left = intReplacePx(oImg.style.left),
                tank_top = top = intReplacePx(oImg.style.top),
                tank_width = img_width,
                tank_height = img_height,
                angle = 0,
                step = 1,//坦克步速,值越大速度越快
                oEquipmentImg = document.getElementById('equipment'),//獲取坦克裝備
                transform_val = oImg.style.transform,
                res = transform_val.match(/\((.*)deg\)/),
                e = e ? e : window.event;
            if(!oEquipmentImg){//當鍵盤操作過頻繁,裝備還沒來得及生成時,返回false
                console.log('操作過於頻繁!');
                return false;
            }    
            equipment_top = intReplacePx(oEquipmentImg.style.top);
            equipment_left = intReplacePx(oEquipmentImg.style.left);
            equipment_width = oEquipmentImg.clientWidth;
            equipment_height = oEquipmentImg.clientHeight;


            switch(e.keyCode){
                case 37://左
                    angle = 180;
                    direction = 'left';
                    break;
                case 38://上
                    angle = 270;
                    direction = 'top';
                    break;
                case 39://右
                    angle = 0;
                    direction = 'right';
                    break;
                case 40://下
                    angle = 90;
                    direction = 'bottom';
                    break;
                default:
                    if(e.keyCode != 32) return false;//除了上下左右空格鍵外,其餘的鍵無效
            }


            if(e.keyCode == 32){//空格鍵
                makeTankMissile(direction,oImg,img_width,img_height);//發射導彈
                missile_step = 1;
                setInterval(function(){
                    missiles = document.getElementsByName('missile');//獲得所有的導彈
                    var missilesCount = missiles.length;
                    for (var i = 0; i < missilesCount; i++) {
                        if(missiles[i]){
                            missile_direction = missiles[i].getAttribute("direction");
                            missile_offset_left = missiles[i].offsetLeft;//獲得每顆導彈離瀏覽器左邊框的距離
                            missile_offset_top = missiles[i].offsetTop;//獲得每顆導彈離瀏覽器上邊框的距離
                            missile_width = missiles[i].clientWidth;//導彈寬度
                            missile_height = missiles[i].clientHeight;//導彈高度
                            for (var k = 0; k < bulletAndObstaclesCountObj.obstaclesCount; k++) {
                                if(obstacles[k]){
                                    obstacle_offset_left = obstacles[k].offsetLeft;
                                    obstacle_offset_top = obstacles[k].offsetTop;
                                    obstacle_width = obstacles[k].clientWidth;
                                    obstacle_height = obstacles[k].clientHeight;
                                    if(!((missile_offset_top + missile_height < obstacle_offset_top) || (missile_offset_top > obstacle_offset_top + obstacle_height) || (missile_offset_left + missile_width < obstacle_offset_left) || (missile_offset_left > obstacle_offset_left + obstacle_width))){//導彈打到障礙物,凡是被導彈打到的障礙物,一槍斃命
                                        exterminate_obstacles_nums = document.getElementById('exterminate_obstacles_nums').innerHTML;
                                        document.getElementById('exterminate_obstacles_nums').innerHTML = parseInt(exterminate_obstacles_nums) + 1;//消滅障礙總數量加一
                                        obstacles[k].parentNode.removeChild(obstacles[k]);//障礙物消失
                                        bulletAndObstaclesCountObj.obstaclesCount--;//障礙物數量減一
                                    }
                                }
                            };
                            missile_step++;
                            if(missile_direction == 'left' && missile_offset_left >= missile_step){
                                missiles[i].style.left = (missile_offset_left - missile_step) + 'px';
                            }else if(missile_direction == 'right' && missile_offset_left < screen_width - missile_step){
                                missiles[i].style.left = (missile_offset_left + missile_step) + 'px';
                            }else if(missile_direction == 'top' && missile_offset_top >= missile_step){
                                missiles[i].style.top = (missile_offset_top - missile_step) + 'px';
                            }else if(missile_direction == 'bottom' && missile_offset_top < screen_height - missile_step){
                                missiles[i].style.top = (missile_offset_top + missile_step) + 'px';
                            }else{
                                missiles[i].parentNode.removeChild(missiles[i]);
                            }                            
                        }
                    };
                },1);
            }else{
                oImg.style.transform = 'rotate('+ angle +'deg)';//坦克掉頭
                switch(direction){
                    case 'left':
                        tankBarrelX = tank_left;
                        tankBarrelY = tank_top + tank_height / 2;
                        oneX = tank_left;
                        oneY = tank_top;
                        twoX = tank_left;
                        twoY = tank_top + tank_height;
                        break;
                    case 'top':
                        tankBarrelX = tank_left + tank_width / 2;
                        tankBarrelY = tank_top;
                        oneX = tank_left;
                        oneY = tank_top;
                        twoX = tank_left + tank_width;
                        twoY = tank_top;
                        break;
                    case 'right':
                        tankBarrelX = tank_left + tank_width;
                        tankBarrelY = tank_top + tank_height / 2;
                        oneX = tank_left + tank_width;
                        oneY = tank_top;
                        twoX = tank_left + tank_width;
                        twoY = tank_top + tank_height;
                        break;
                    case 'bottom':
                        tankBarrelX = tank_left + tank_width / 2;
                        tankBarrelY = tank_top + tank_height;
                        oneX = tank_left;
                        oneY = tank_top + tank_height;
                        twoX = tank_left + tank_width;
                        twoY = tank_top + tank_height;
                        break;
                }
                if(!((tank_top + tank_height < equipment_top) || (tank_top > equipment_top + equipment_height) || (tank_left + tank_width < equipment_left) || (tank_left > equipment_left + equipment_width))){//坦克吃到裝備
                    var scoreNode = document.getElementById('tip'); //獲取分數提示框節點
                    scoreNode.style.visibility = 'visible';
                    scoreNode.style.opacity = 1;
                    scoreNode.style.marginTop = intReplacePx(scoreNode.style.marginTop) - 20 + 'px';
                    scoreNode.style.transition = 'all 0.6s ease-in-out';
                    setTimeout(function(){
                        type = oEquipmentImg.getAttribute('data-type');
                        switch(type){
                            case '0'://手槍
                                document.getElementById('gun_number').innerHTML = parseInt(document.getElementById('gun_number').innerHTML) + 1;
                                break;
                            case '1'://炸彈
                                document.getElementById('bomb_number').innerHTML = parseInt(document.getElementById('bomb_number').innerHTML) + 1;
                                break;
                            case '2'://星星
                                document.getElementById('star_number').innerHTML = parseInt(document.getElementById('star_number').innerHTML) + 1;
                                break;
                            case '3'://戰艦
                                document.getElementById('warship_number').innerHTML = parseInt(document.getElementById('warship_number').innerHTML) + 1;
                                equipmentScore = 5;//吃到戰艦加5分
                                oImg.setAttribute('data-ship', true);
                                oImg.width = '58';
                                oImg.height = '58';
                                oImg.style.border = '1px solid #fff';
                                break;
                            case '4'://子彈
                                document.getElementById('bullet_total_nums').innerHTML = parseInt(document.getElementById('bullet_total_nums').innerHTML) + parseInt(equipmentScore);
                                equipmentScore = 10;//吃到子彈加10分
                                break;
                            case '5'://導彈
                                document.getElementById('missile_num').innerHTML = parseInt(document.getElementById('missile_num').innerHTML) + 1;
                                equipmentScore = 50;//吃到導彈加50分
                                break;
                        }
                        total_scores = document.getElementById('total_scores').innerHTML;
                        total_scores = parseInt(total_scores) + parseInt(equipmentScore);
                        document.getElementById('total_scores').innerHTML = total_scores;//更新總分數
                        switch(true){//玩家等級,坦克圖片發生相應變化
                            case total_scores > 0 && total_scores <= 10:
                                player_level = '輕型坦克';
                                break;
                            case total_scores > 10 && total_scores <= 100:
                                oImg.src = 'tank2.jpg';
                                player_level = '中型坦克';
                                break;
                            case total_scores > 100 && total_scores <= 200:
                                oImg.src = 'tank3.jpg';
                                player_level = '重型坦克';
                                break;
                            case total_scores > 200 && total_scores <= 500:
                                oImg.src = 'tank4.jpg';
                                player_level = '坦克殲擊車';
                                break;
                            default:
                                oImg.src = 'tank5.jpg';
                                player_level = '自行火炮';
                        }
                        document.getElementById('player_level').innerHTML = player_level;
                        scoreNode.parentNode && scoreNode.parentNode.removeChild(scoreNode);//被吃到的裝備消失
                        equipmentScore = makeTankEquipment();//製作新的坦克裝備
                    }, 500);
                    oEquipmentImg.parentNode && oEquipmentImg.parentNode.removeChild(oEquipmentImg);
                }
                
                data_ship = oImg.getAttribute('data-ship') || '';//坦克是否擁有戰艦


                for (var s = 0; s < tankAndObstaclesCountObj.obstaclesCount; s++) {
                    obstacle_offset_left = obstacles[s].offsetLeft;
                    obstacle_offset_top = obstacles[s].offsetTop;
                    obstacle_width = obstacles[s].clientWidth;
                    obstacle_height = obstacles[s].clientHeight;
                    obstacle_direction = localStorage.getItem('obstacle_direction_' + s) || '',
                    if_condition1 = !(tankBarrelX < obstacle_offset_left || tankBarrelX > obstacle_offset_left + obstacle_width || tankBarrelY < obstacle_offset_top || tankBarrelY > obstacle_offset_top + obstacle_height);//先判斷坦克發射筒是否觸及障礙物
                    if_condition2 = !(oneX < obstacle_offset_left || oneX > obstacle_offset_left + obstacle_width || oneY < obstacle_offset_top || oneY > obstacle_offset_top + obstacle_height) || !(twoX < obstacle_offset_left || twoX > obstacle_offset_left + obstacle_width || twoY < obstacle_offset_top || twoY > obstacle_offset_top + obstacle_height);//再判斷坦克發射筒的兩個邊界點是否觸及障礙物
                    if_condition4 = !((tank_top + tank_height < obstacle_offset_top) || (tank_top > obstacle_offset_top + obstacle_height) || (tank_left + tank_width < obstacle_offset_left) || (tank_left > obstacle_offset_left + obstacle_width));//判斷坦克是否觸及到障礙物
                    data_forward = obstacles[s].getAttribute('data-forward');//判斷坦克是否可以前進
                    data_alias = obstacles[s].getAttribute('data-alias');//如果是河,則判斷是不是可以過河
                    data_accelerate = obstacles[s].getAttribute('data-accelerate');//過雪地坦克速度增加


                    if(obstacle_direction){
                        var result;
                        switch(obstacle_direction){
                            case 'left'://原來受阻方向為左
                                switch(direction){
                                    case 'top'://現掉頭往上
                                    case 'bottom'://現掉頭往下
                                        result = isCollisionByPoint(twoX,twoY,s,direction);
                                        if(!result){ return result;}                                                        
                                        break;
                                    default:
                                        result = isCollisionByDataAttr(if_condition2,data_forward,data_alias,data_ship,s,direction);
                                        if(!result){ return result;}                                                        
                                }
                                break;
                            case 'top'://原來受阻方向為上
                                switch(direction){
                                    case 'left'://現掉頭往左
                                    case 'right'://現掉頭往右
                                        result = isCollisionByPoint(twoX,twoY,s,direction);
                                        if(!result){ return result;}                                            
                                        break;
                                    default:
                                        result = isCollisionByDataAttr(if_condition2,data_forward,data_alias,data_ship,s,direction);
                                        if(!result){ return result;}     
                                }
                                break;
                            case 'right'://原來受阻方向為右
                                switch(direction){
                                    case 'top'://現掉頭往上
                                    case 'bottom'://現掉頭往下
                                        result = isCollisionByPoint(oneX,oneY,s,direction);
                                        if(!result){ return result;}                                          
                                        break;
                                    default:
                                        result = isCollisionByDataAttr(if_condition2,data_forward,data_alias,data_ship,s,direction);
                                        if(!result){ return result;}    
                                }
                                break;
                            case 'bottom'://原來受阻方向為下
                                switch(direction){
                                    case 'left'://現掉頭往左
                                    case 'right'://現掉頭往右
                                        result = isCollisionByPoint(oneX,oneY,s,direction);
                                        if(!result){ return result;}                                         
                                        break;
                                    default:
                                        result = isCollisionByDataAttr(if_condition2,data_forward,data_alias,data_ship,s,direction);
                                        if(!result){ return result;}     
                                }
                                break;
                        }
                    }else if(if_condition2 && (data_forward == 'false' || data_alias == 'river' && data_ship == '')){//坦克碰到障礙物                        
                        console.log('坦克碰到障礙物不能前進!');
                        localStorage.setItem('obstacle_direction_' + s,direction);
                        return false;
                    }else if(if_condition4 && data_accelerate == 'true'){
                        step = 5;
                    }
                };


                switch(direction){
                    case 'left':
                        if(res && res[1] == angle && left >= step){//如果角度一樣代表長按,且距離應大於等於步進值,防止出界
                            oImg.style.left = (left - step) + 'px';
                        }
                        break;
                    case 'top':
                        if(res && res[1] == angle && tank_top >= step){//代表長按
                            oImg.style.top = (tank_top - step) + 'px';
                        }  
                        break;
                    case 'right':
                        if(res && res[1] == angle && screen_width - left - img_width >= step){//代表長按
                            oImg.style.left = (left + step) + 'px';
                        }
                        break;
                    case 'bottom':
                        if(res && res[1] == angle && screen_height - tank_top - img_height >= step){//代表長按
                            oImg.style.top = (tank_top + step) + 'px';
                        }
                        break;
                }
                
            }     
        }
        //滑鼠繫結事件
        document.onmousedown = function(e){
            var bullet_total_nums = e.button ? 2 : 1;//每發子彈個數,左擊單發子彈,右擊雙發子彈
                bullet_speed = e.button ? 1 : 2;//子彈速度,定時器時間值
                bullet_step = e.button ? 1 : 1;//子彈進度,畫素值
            var bullets,bullet_offset_left,bullet_offset_top;
            clearInterval(interval);
            
            makeTankBullet(bullet_total_nums,direction,oImg,img_width,img_height);//一槍打bullet_total_nums顆子彈


            var interval = setInterval(function(){
                bullets = document.getElementsByName('bullet');//獲得所有的子彈
                missiles = document.getElementsByName('missile');//獲得所有的導彈
                var bulletsCount = bullets.length;
                var missilesCount = missiles.length;
                for (var i = 0; i < bulletsCount; i++) {
                    if(bullets[i]){
                        bullet_direction = bullets[i].getAttribute("direction");
                        bullet_offset_left = bullets[i].offsetLeft;//獲得每顆子彈離瀏覽器左邊框的距離
                        bullet_offset_top = bullets[i].offsetTop;//獲得每顆子彈離瀏覽器上邊框的距離
                        bullet_width = bullets[i].clientWidth;//子彈寬度
                        bullet_height = bullets[i].clientHeight;//子彈高度
                        for (var gun_number,data_alias,k = 0; k < bulletAndObstaclesCountObj.obstaclesCount; k++) {
                            if(obstacles[k]){
                                obstacle_offset_left = obstacles[k].offsetLeft;
                                obstacle_offset_top = obstacles[k].offsetTop;
                                obstacle_width = obstacles[k].clientWidth;
                                obstacle_height = obstacles[k].clientHeight;
                                if(!((bullet_offset_top + bullet_height < obstacle_offset_top) || (bullet_offset_top > obstacle_offset_top + obstacle_height) || (bullet_offset_left + bullet_width < obstacle_offset_left) || (bullet_offset_left > obstacle_offset_left + obstacle_width))){//子彈打到障礙物
                                    needBulletNums = obstacles[k].getAttribute('data-nums');//獲取每個障礙物的所需子彈數
                                    isOver = obstacles[k].getAttribute('data-over');//表示子彈打到障礙物後,是否可以繼續前進
                                    gun_number = document.getElementById('gun_number').innerHTML;
                                    console.log(gun_number);
                                    data_alias = obstacles[k].getAttribute('data-alias');
                                    if(needBulletNums == '+∞'){//表示障礙物的所需子彈數不限制
                                        if(gun_number > 0 && data_alias == 'steel'){//擁有手槍,可以打鐵
                                            obstacles[k].parentNode.removeChild(obstacles[k]);//障礙物消失
                                            bulletAndObstaclesCountObj.obstaclesCount--;//障礙物數量減一
                                        }else if(isOver == 'true'){//表示子彈不可以繼續前進
                                            bullets[i].parentNode.removeChild(bullets[i]);//子彈消失
                                            var bImg = document.createElement('img');
                                            bImg.src = 'bombing.jpg';
                                            bImg.style.position = 'absolute';
                                            bImg.style.left = parseInt(bullet_offset_left - bullet_width/2) + 'px';
                                            bImg.style.top = parseInt(bullet_offset_top - bullet_height/2) + 'px';
                                            document.body.appendChild(bImg);//增加子彈擊中效果
                                            setTimeout(function(){
                                                bImg.parentNode.removeChild(bImg);//子彈擊中效果消失
                                            }, 200);
                                            return;
                                        }
                                    }else if(needBulletNums <= 1){//如果只需一槍,則障礙物消失
                                        exterminate_obstacles_nums = document.getElementById('exterminate_obstacles_nums').innerHTML;
                                        document.getElementById('exterminate_obstacles_nums').innerHTML = parseInt(exterminate_obstacles_nums) + 1;//消滅障礙總數量加一
                                        obstacles[k].parentNode.removeChild(obstacles[k]);//障礙物消失
                                        bullets[i].parentNode.removeChild(bullets[i]);//子彈消失
                                        bulletAndObstaclesCountObj.obstaclesCount--;//障礙物數量減一
                                    }else{//否則所需子彈數減一
                                        needBulletNums--;
                                        obstacles[k].setAttribute('data-nums',needBulletNums);//重新設定每個障礙物的所需子彈數
                                    }
                                }
                            }
                        };
                        bullet_step++;
                        if(bullet_direction == 'left' && bullet_offset_left >= bullet_step){
                            bullets[i].style.left = (bullet_offset_left - bullet_step) + 'px';
                        }else if(bullet_direction == 'right' && bullet_offset_left < screen_width - bullet_step){
                            bullets[i].style.left = (bullet_offset_left + bullet_step) + 'px';
                        }else if(bullet_direction == 'top' && bullet_offset_top >= bullet_step){
                            bullets[i].style.top = (bullet_offset_top - bullet_step) + 'px';
                        }else if(bullet_direction == 'bottom' && bullet_offset_top < screen_height - bullet_step){
                            bullets[i].style.top = (bullet_offset_top + bullet_step) + 'px';
                        }else{
                            var bImg = document.createElement('img');
                            bImg.src = 'bombing.jpg';
                            bImg.style.position = 'absolute';
                            bImg.style.left = parseInt(bullet_offset_left - bullet_width/2) + 'px';
                            bImg.style.top = parseInt(bullet_offset_top - bullet_height/2) + 'px';
                            document.body.appendChild(bImg);//增加子彈擊中效果
                            setTimeout(function(){
                                bImg.parentNode.removeChild(bImg);//子彈擊中效果消失
                            }, 200);
                            bullets[i].parentNode.removeChild(bullets[i]);//子彈消失
                        }                           
                    }
                };
            }, bullet_speed);
        }


        //製造導彈
        function makeTankMissile(direction,oImg,img_width,img_height){
            var missile_nums = document.getElementById('missile_num').innerHTML;
            if(missile_nums <= 0){
                document.getElementById('missile_num').innerHTML = 0;
                return false;
            }else{
                missile_nums--;//每次發射導彈,其對應的數量也減少
                document.getElementById('missile_num').innerHTML = missile_nums;
            }
            var bullet_direction = direction;
            var oDiv = document.createElement('div');
            var oDiv_style_top = intReplacePx(oImg.style.top);
            var oDiv_style_left = intReplacePx(oImg.style.left);
            switch(bullet_direction){
                case 'left':
                    oDiv.style.width = '80px';
                    oDiv.style.height = '10px';
                    oDiv.style.top = oDiv_style_top + 18 + 'px';
                    oDiv.style.left = oDiv_style_left - img_width / 2 - 50 + 'px';
                    oDiv.style.display = 'inline-table';
                    oDiv.setAttribute("direction", "left");
                    break;
                case 'top':
                    oDiv.style.width = '10px';
                    oDiv.style.height = '80px';
                    oDiv.style.top = oDiv_style_top - 80 + 'px';
                    oDiv.style.left = oDiv_style_left + 25 + 'px';
                    oDiv.setAttribute("direction", "top");
                    break;
                case 'right':
                    oDiv.style.width = '80px';
                    oDiv.style.height = '10px';
                    oDiv.style.top = oDiv_style_top + 18 + 'px';
                    oDiv.style.left = oDiv_style_left + img_width + 'px';
                    oDiv.style.display = 'inline-table';
                    oDiv.setAttribute("direction", "right");
                    break;
                case 'bottom':
                    oDiv.style.height = '80px';  
                    oDiv.style.width = '10px';
                    oDiv.style.top = oDiv_style_top + img_height + 'px';
                    oDiv.style.left = oDiv_style_left + 24 + 'px';
                    oDiv.setAttribute("direction", "bottom");
                    break;
            }
            oDiv.setAttribute("class", "missile");
            oDiv.setAttribute("name", "missile");
            document.body.appendChild(oDiv);//造導彈
        }


        //製造坦克子彈
        function makeTankBullet(bullet_total_nums,direction,oImg,img_width,img_height){
            var bullet_nums = document.getElementById('bullet_total_nums').innerHTML;
            bullet_nums -= bullet_total_nums;//每次發射子彈,其對應的數量也減少
            if(bullet_nums <= 0){
                document.getElementById('bullet_total_nums').innerHTML = 0;
                return false;
            }else{
                document.getElementById('bullet_total_nums').innerHTML = bullet_nums;
            }
            for (var j = 0; j < bullet_total_nums; j++) {
                var bullet_direction = direction;
                var oDiv = document.createElement('div');
                var oDiv_style_top = intReplacePx(oImg.style.top);
                var oDiv_style_left = intReplacePx(oImg.style.left);
                switch(bullet_direction){
                    case 'left':
                        oDiv.style.top = oDiv_style_top + 18 + 'px';
                        oDiv.style.left = oDiv_style_left - img_width / 2 + 'px';
                        oDiv.style.display = 'inline-table';
                        oDiv.setAttribute("direction", "left");
                        break;
                    case 'top':
                        oDiv.style.top = oDiv_style_top - 30 + 'px';
                        oDiv.style.left = oDiv_style_left + 25 + 'px';
                        oDiv.setAttribute("direction", "top");
                        break;
                    case 'right':
                        oDiv.style.top = oDiv_style_top + 18 + 'px';
                        oDiv.style.left = oDiv_style_left + img_width + 'px';
                        oDiv.style.display = 'inline-table';
                        oDiv.setAttribute("direction", "right");
                        break;
                    case 'bottom':
                        oDiv.style.top = oDiv_style_top + img_height + 'px';
                        oDiv.style.left = oDiv_style_left + 25 + 'px';
                        oDiv.setAttribute("direction", "bottom");
                        break;
                }
                oDiv.setAttribute("class", "bullet");
                oDiv.setAttribute("name", "bullet");
                document.body.appendChild(oDiv);//造子彈
            };
        }


        //製造坦克裝備
        function makeTankEquipment(){
            var oEquipmentImg = document.createElement('img'),
                scoreNode = document.createElement("div"), //建立分數提示框節點
                oEquipmentImgLeng = 30,//邊長
                oEquipmentImgArr = ['gun.jpg','bomb.jpg','star.jpg','warship.jpg','bullet.jpg','missile.jpg'],
                oEquipmentImgScoreArr = ['+3','-1','+1','+10','+50','+100'],
                rand_index = Math.floor(Math.random()*oEquipmentImgArr.length);
                oEquipmentImg.setAttribute('id', 'equipment');
                oEquipmentImg.setAttribute('src', oEquipmentImgArr[rand_index]);//返回是一個隨機陣列中的一個數。主要用的就是random的方法。random方法,是返回(0,1] 的數,但取不到1,所以用Math.floor向下取整。
                oEquipmentImg.setAttribute('height', oEquipmentImgLeng);
                oEquipmentImg.setAttribute('width', oEquipmentImgLeng);
                oEquipmentImg.setAttribute('data-type', rand_index);
                oEquipmentImg.style.position = 'absolute';
                oEquipmentImg.style.top = Math.round(Math.random() * screen_height) - oEquipmentImgLeng + 'px';
                oEquipmentImg.style.left = Math.round(Math.random() * screen_width) - oEquipmentImgLeng + 'px';
                document.body.appendChild(oEquipmentImg);//造裝置
                scoreNode.innerHTML = oEquipmentImgScoreArr[rand_index];//分數值
                scoreNode.setAttribute('id', 'tip');
                scoreNode.style.marginTop = oEquipmentImg.style.top;
                scoreNode.style.marginLeft = oEquipmentImg.style.left;
                scoreNode.style.transition = 'all 0.6s ease-in-out'; /* Browsers that Support it */
                document.body.appendChild(scoreNode);
                return oEquipmentImgScoreArr[rand_index];
        }


        //製造障礙物
        function makeTankObstacle(num = 66){
            var obstacle_arr = ['river.jpg','grass.jpg','brick.jpg','snow.jpg','steel.jpg'];
            for (var o = 0; o < num; o++) {
                rand_index = Math.floor(Math.random()*obstacle_arr.length);
                var obstacle = document.createElement("div"),
                    obstacleWidthValue = 30 + Math.round(Math.random() * 150),
                    obstacleHeightValue = 30 + Math.round(Math.random() * 150);
                    obstacle.setAttribute('data-index', o);//障礙物編號
                switch(obstacle_arr[rand_index]){
                    case obstacle_arr[0]:
                        obstacle.setAttribute('data-alias', 'river');//設定別名
                        obstacle.setAttribute('data-nums', '+∞');//需要被打幾槍才能斃命
                        obstacle.setAttribute('data-over', false);//子彈是否可以前進
                        obstacle.setAttribute('data-forward', true);//當有船時,坦克能否繼續前進
                        obstacle.setAttribute('data-accelerate', false);//坦克是否加速
                        break;
                    case obstacle_arr[1]:
                        obstacle.setAttribute('data-nums', '+∞');//需要被打幾槍才能斃命
                        obstacle.setAttribute('data-over', false);//子彈是否可以前進
                        obstacle.setAttribute('data-forward', true);//坦克能否繼續前進
                        obstacle.setAttribute('data-accelerate', false);//坦克是否加速
                        obstacle.style.zIndex = 100;
                        obstacle.style.opacity = '0.8';
                        break;
                    case obstacle_arr[2]:
                        obstacle.setAttribute('data-nums', Math.ceil(Math.random()*3));//需要被打幾槍才能斃命
                        obstacle.setAttribute('data-over', true);//子彈是否可以前進
                        obstacle.setAttribute('data-forward', false);//坦克能否繼續前進
                        obstacle.setAttribute('data-accelerate', false);//坦克是否加速
                        break;
                    case obstacle_arr[3]:
                        obstacle.setAttribute('data-nums', '+∞');//需要被打幾槍才能斃命
                        obstacle.setAttribute('data-over', false);//子彈是否可以前進
                        obstacle.setAttribute('data-forward', true);//坦克能否繼續前進
                        obstacle.setAttribute('data-accelerate', true);//坦克是否加速
                        break;
                    case obstacle_arr[4]:
                        obstacle.setAttribute('data-alias', 'steel');//設定別名
                        obstacle.setAttribute('data-nums', '+∞');//需要被打幾槍才能斃命
                        obstacle.setAttribute('data-over', true);//子彈是否可以前進
                        obstacle.setAttribute('data-forward', false);//坦克能否繼續前進
                        obstacle.setAttribute('data-accelerate', false);//坦克是否加速
                        break;
                }
                obstacle.setAttribute('name', 'obstacle');
                obstacle.setAttribute('class', 'obstacle');
                obstacle.style.position = 'absolute';
                obstacle.style.background = 'url('+ obstacle_arr[rand_index] +')';//生成背景隨機圖片
                obstacle.style.width = obstacleWidthValue + 'px';
                obstacle.style.height = obstacleHeightValue + 'px';
                obstacle.style.top =  Math.round(Math.random() * screen_height) - obstacleHeightValue + 'px';
                obstacle.style.left =  Math.round(Math.random() * screen_width) - obstacleWidthValue + 'px';
                obstacle.style.color = '#fff';
                document.body.appendChild(obstacle);
            };
        }


        //現在時間
        function currentTime(callback) {
            var flag = true;
            setInterval(function () {
                var now = new Date();
                var year = now.getFullYear();
                var month = ((now.getMonth()+1).toString().length == 1 ? '0' : '') + (now.getMonth() + 1);
                var date = now.getDate();
                var hour = (now.getHours().toString().length == 1 ? '0' : '') + now.getHours();
                var minutes = (now.getMinutes().toString().length == 1 ? '0' : '') + now.getMinutes();
                var second = (now.getSeconds().toString().length == 1 ? '0' : '') + now.getSeconds();
                var time = year + "-" + month + "-" + date + " " + hour + ":" + minutes + ":" + second;
                document.getElementById("current_time").innerHTML = time;
                flag && callback(time);//使用匿名函式,返回setInterval裡的值,我們這裡只需要第一次返回
                flag = false;
            }, 1000);
        };


        //分鐘和秒形式倒計時
        function resetTime(time){
            var timer = null;
            var t = time;
            var m = 0;
            var s = 0;
            m = Math.floor(t/60%60);
            m<10&&(m='0'+m);
            s = Math.floor(t%60);
            function countDown(){
                s--;
                s<10&&(s='0'+s);
                if(s.length>=3){
                    s = 59;
                    m = m<10 ? "0"+(Number(m)-1) : (Number(m)-1);
                }
                if(m.length>=3){
                    m = '00';
                    s = '00';
                    document.getElementById("time").style.display = 'block';
                    document.onmousedown = null;//時間到,禁用滑鼠
                    document.onkeydown = null;//時間到,禁用鍵盤
                    clearInterval(timer);
                }
                document.getElementById("remaining_time").innerHTML =  m + ":" + s; 
            }
            timer = setInterval(countDown,1000);
        }


        resetTime(500);//獲取倒計時間,預設5分鐘


        //獲取本機IP
        document.getElementById("localhost").innerHTML = returnCitySN["cip"] + ' ' + returnCitySN["cname"];


        currentTime(function (time) {//再巢狀一個匿名函式,直接在其中呼叫函式並將返回值賦給其他變數。
            document.getElementById("start_time").innerHTML = time;
        });


        //物件屬性的獲取
        function intReplacePx(objAttr){
            return parseInt(objAttr.replace('px', '')) || 0;
        }


        function isCollisionByPoint(pointX,pointY,index,direction){
            if_condition = !(pointX < obstacle_offset_left || pointX > obstacle_offset_left + obstacle_width || pointY < obstacle_offset_top || pointY > obstacle_offset_top + obstacle_height);
            if(if_condition){
                localStorage.setItem('obstacle_direction_' + index,direction);
                console.log('坦克碰到障礙物不能前進!');
                return false;
            }else{
                return true;
            }
        }


        function isCollisionByDataAttr(if_condition2,data_forward,data_alias,data_ship,index,direction){
            console.log(arguments);
            if(if_condition2 && (data_forward == 'false' || data_alias == 'river' && data_ship == '')){//坦克碰到障礙物
                console.log('坦克碰到障礙物不能前進!');
                localStorage.setItem('obstacle_direction_' + index,direction);
                return false;
            }else{
                return true;
            }
        }
    </script>
</body>
</html>

遊戲截圖: