<style> .container { width: 500px; height: 600px; margin: 50px auto; position: relative; display: flex; justify-content: center; overflow: hidden; background: #000; } .plane { width: 100px; height: 60px; background: url(./plane.png) no-repeat center / 100% 100%; position: absolute; bottom: 10px; } .enemy { width: 60px; height: 40px; background: url(./plane.png) no-repeat center / 100% 100%; position: absolute; top: 0px; } .bullet { width: 6px; height: 20px; border-radius: 5px 5px 0 0; box-shadow: 0 4px 5px orangered; background: gold; position: absolute; } #score{ color: #ffffff; } </style> </head> <body> <div class="container"> <h1 id="score">0</h1> <div class="plane"></div> </div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script> <script src="./simba.jq.js"></script> <script> let score = 0 $(window).keydown(function (e) { // 监控键盘事件 let top = $(‘.plane‘).position().top // 改变飞机的左和高 let left = $(‘.plane‘).position().left switch (e.keyCode) { // 获取键盘的按键数值 case 87: top -= 10 break case 83: top += 10 break case 65: left -= 10 break case 68: left += 10 break case 74: attack() break } let maxLeft = $(‘.container‘).innerWidth() - $(‘.plane‘).innerWidth() // 一整个外壳的边距宽度 飞机模型的宽度 let maxTop = $(‘.container‘).innerHeight() - $(‘.plane‘).innerHeight() let result = $.filterLeftAndTop(left, top, maxLeft, maxTop) // 调用封装的方法 如果保证飞机模型不会超出边框 $(‘.plane‘).css(‘top‘, result.top).css(‘left‘, result.left) }) //节流 let endTime = new Date() function attack() { if (new Date() - endTime < 500) return console.log(‘ i am busy ‘); // 限制飞机的攻击速度 保证攻速间隔至少为0.5s 这里要注意下书写顺序 let bullet = $(‘<div/>‘).addClass(‘bullet‘) // 为攻击提供模型样式 $(‘.container‘).append(bullet) bullet.css(‘top‘, $(‘.plane‘).position().top - 10) // 为模型添加样式 确保攻击是高于飞机模型10px的地方 bullet.css(‘left‘, $(‘.plane‘).position().left + $(‘.plane‘).innerWidth() / 2 - bullet.innerWidth() / 2) // 为模型添加样式 确保不管飞机左右移动 都在飞机的正中间 第一次/飞机模型的一半 第二次/攻击模型的一半 endTime = new Date() // 每次攻击都刷新一次时间 如果补添加那么 飞机的攻击间隔将是0s } let timer1 = setInterval(() => { $(‘.bullet‘).each(function () { $(this).css(‘top‘, $(this).position().top - 10) // 保障攻击不断的 -10px 的方式往上移动 if ($(this).position().top < 0) $(this).remove() //如果top值为0,意思是超出屏幕 那就没有村咋的必要 }) }, 10); // 这里是改变飞机攻击模型的飞行速度 let timer2 = setInterval(() => { $(‘.enemy‘).each(function () { $(this).css(‘top‘, $(this).position().top + 5) // 敌方飞机不断的 +5px 的方式朝下移动 if ($(this).position().top > $(‘.container‘).innerHeight()) $(this).remove() // 同样的 如果top超出了 当前跨国家的最大高度 那么就没有生命存在的必要 }) }, 50); // 设定敌机接近的速度 let timer3 = setInterval(() => { let enemy = $(‘<div/>‘).addClass(‘enemy‘) // 为敌机设定样式 $(‘.container‘).append(enemy) // 将敌机添加进入游戏框架中 enemy.css(‘left‘, Math.round(Math.random() * ($(‘.container‘).innerWidth() - enemy.innerWidth()))) // 随机敌机的出现的位置 同样的要以最大宽度减去敌机模型的宽度 }, 2000); // 敌机刷新的速度 function gettrbl(obj) { return { t: obj.offsetTop, r: obj.offsetLeft + obj.offsetWidth, b: obj.offsetTop + obj.offsetHeight, l: obj.offsetLeft } // 定义左右上下的简化写法 } function calcCollistion(a, b) { a = gettrbl(a) b = gettrbl(b) // 调用简化 if (a.l > b.l && a.l < b.r && a.t > b.t && a.t < b.b) return true if (a.r > b.l && a.r < 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 // 判断两者的相撞 以两者的左右上下进行对比 return false // 如果上面判断都不成功就是fales正常运行 } // 检查碰撞 let timer4 = setInterval(() => { $(‘.enemy‘).each(function (i, enemy) { $(‘.bullet‘).each(function (j, bullet) { if (calcCollistion(enemy, bullet) || calcCollistion(bullet, enemy)) { $(enemy).remove() $(bullet).remove() // 删除 有碰撞接触的两个div score += 10 $(‘#score‘).text(score) } }) if (calcCollistion(enemy, $(‘.plane‘).get(0)) || calcCollistion($(‘.plane‘).get(0), enemy)) { // 飞机本性和敌机进行相互判断 console.log(‘good game!‘); clearInterval(timer1) clearInterval(timer2) clearInterval(timer3) clearInterval(timer4) } }) }, 30) // 时间一定要小于所有 </script>
<script src="./simba.jq.js"></script>
$.extend({ mosaic(str) { return str.replace(str.substr(3, 4), ‘****‘) }, filterLeftAndTop(left, top, maxLeft, maxTop, minLeft = 0, minTop = 0) { if (left < minLeft) left = minLeft if (top < minTop) top = minTop if (left > maxLeft) left = maxLeft if (top > maxTop) top = maxTop return { left, top }