效果图如下:
首先要在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>