JavaScript - 简单飞机大战

325 阅读1分钟

效果图如下:

首先要在HTML中创建两个div容器

<div class="container">
    <div class="plane"></div>
</div>

编写容器的css样式

<style>
    * {
        margin: 0;
        padding: 0;
    }

    .container {
        width: 600px; 
        height: 80vh;
        background-color: #000;
        margin: 10vh auto;
        position: relative;
    }

    .plane {
        width: 150px;
        height: 80px;
        position: absolute;
        left: calc(50% - 75px);
        bottom: 10px;
        background: url(./plane.png) 0 / 100% 100%;
    }

    .bullet {
        background: gold;
        width: 8px;
        height: 20px;
        border-radius: 4px 4px 0 0;
        box-shadow: 0 4px 5px #fff;
        position: absolute;
    }

    .enemy {
        width: 80px;
        height: 50px;
        position: absolute;
        background: url(./plane.png) 0 / 100% 100%;
    }
</style>

引入jQuery库

<script src='https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js'></script>

详细代码如下

 <script>
    $(() => {
        //声明变量,方便在后面使用,以免重复声明
        let plane = $('.plane')
        let container = $('.container')
        //飞机距离左边最大的距离
        let maxLeft = container.innerWidth() - plane.innerWidth()
        //飞机距离上边最大的距离
        let maxTop = container.innerHeight() - plane.innerHeight()
        
        //让飞机在容器中移动且不会移出容器的范围
        $(window).keydown(({ keyCode }) => {
            console.log(keyCode);
            let top = plane.position().top
            let left = plane.position().left
            switch (keyCode) {
                case 87:
                    top -= 10
                    break;
                case 83:
                    top += 10
                    break;
                case 65:
                    left -= 10
                    break;
                case 68:
                    left += 10
                    break;
                case 74:
                    shoot()
                    break;

                default:
                    break;
            }
            if (top < 0) top = 0
            if (left < 0) left = 0
            if (top > maxTop) top = maxTop
            if (left > maxLeft) left = maxLeft
            plane.css({ top, left })
        })

        //在飞机正中心生成子弹
        let endTime = new Date()
        function shoot() {
            if (new Date() - endTime < 500) return
            let bullet = $('<div/>').addClass('bullet')
            container.append(bullet)
            bullet.css({
                top: plane.position().top - bullet.innerHeight(),
                left: plane.position().left + plane.innerWidth() / 2 - bullet.innerWidth() / 2
            })
            endTime = new Date()
        }
        
        setInterval(() => {
            //开启定时器,不停地将所有子弹往上飞
            $('.bullet').each(function () {
                let bullet = $(this)
                bullet.css({
                    top: bullet.position().top - 20
                })
                //子弹的位置超出容器顶部,子弹消失
                if (bullet.position().top < 0)
                    bullet.remove()
            })
            //开启定时器,敌机从上向下移动
            $('.enemy').each(function () {
                let enemy = $(this)
                enemy.css({
                    top: enemy.position().top + 20,
                })
                //敌机的位置超出容器底部,敌机消失
                if (enemy.position().top > container.innerHeight())
                    enemy.remove()
            })
        }, 100);

        //不间从顶部断生成敌机
        setInterval(() => {
            let enemy = $('<div/>').addClass('enemy')
            container.append(enemy)
            enemy.css({
                top: 0,
                left: Math.random() * (container.innerWidth() - enemy.innerWidth())
            })
        }, 2000);

        //飞机上下左右的距离
        function getPostion(node) {
            return {
                l: node.offsetLeft,
                t: node.offsetTop,
                r: node.offsetLeft + node.offsetWidth,
                b: node.offsetTop + node.offsetHeight
            }
        }
        //计算是否发生碰撞  *核心代码
        function calcCollision(a, b) {
            a = getPostion(a)
            b = getPostion(b)
            if (a.l > b.l && a.l < b.r && a.t > b.t && a.t < b.b) return true
            if (a.l > b.l && a.l < b.r && a.b > b.t && a.b < b.b) return true
            if (a.r > b.l && a.r < b.r && a.b > b.t && a.b < b.b) return true
            if (a.r > b.l && a.r < b.r && a.t > b.t && a.t < b.b) return true
            return false
        }

        //不间断检测碰撞
        setInterval(() => {
            let me = plane.get(0)
            $('.enemy').each(function (i, enemy) {
                //敌机与飞机发生碰撞,游戏重新开始
                if (calcCollision(me, enemy) || calcCollision(enemy, me)) {
                    alert("GG")
                    location.reload()
                }
                $('.bullet').each(function (j, bullet) {
                    //子弹和敌机发生碰撞,两者都消失
                    if (calcCollision(bullet, enemy) || calcCollision(enemy, bullet)) {
                        bullet.remove()
                        enemy.remove()
                    }
                })
            })
        }, 50);

    })
</script>