前端案例:飞机大战( js+dom 操作,代码完整,附图片素材)
通过 js 逻辑与 dom 操作结合实现了简易的飞机大战小游戏,附带图片素材。
目录
一、案例效果
二、实现思路
- 创建游戏背景板;
- 创建我方战机,鼠标进入游戏面板后其随鼠标轨迹运动; onmousemove
- 创建子弹,让子弹周期性的在战机处发出并让其向 top 值减小的方向(向上)移动,top 小于 0 也就是子弹走出游戏面板时删除自身;
- 创建敌机,让敌机周期性的在游戏背景板左侧的随机距离的位置产生,并让其向 top 增加的方向(向下)移动;
- 定义函数,子弹和敌机相遇时消失。
条件:所有的元素都只在鼠标进入游戏背景区域时才触发运动。
三、完整代码+详细注释
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>飞机大战</title>
<style>
* {
margin: 0;
padding: 0;
}
/* 背景 */
#background {
width: 320px;
height: 580px;
background-image: url(./img/bg.jpg);
margin: auto;
}
/* 我方飞机 */
#my_fly {
width: 30px;
height: 30px;
position: absolute;
cursor: pointer;
}
</style>
</head>
<body>
<!-- 游戏面板 -->
<div id="background"></div>
</body>
<script>
//创建我方战机
var fly = document.createElement('div'); //创建一个div
fly.id = 'my_fly'; //为div添加id名
fly.innerHTML = '<img src ="./img/my_fly.png" width=30px height=30px>'; //在div中插入飞机的图片
document.body.appendChild(fly); //将刚创建的div追加到body中
//使飞机鼠标跟随
document.onmousemove = function (e) { //onmousemove 当鼠标移动时触发事件
var fly = document.getElementById('my_fly'); //获取我方战机
var bg = document.getElementById('background'); //获取背景
var fly_X = e.clientX - 20; //获取鼠标的坐标 -20是减去飞机宽高的一半,以达到飞机中心与鼠标对应
var fly_Y = e.clientY - 20;
//游戏背景的区域
var bgX = fly_X > bg.offsetLeft && fly_X < bg.offsetLeft + bg.offsetWidth - 30;
var bgY = fly_Y > bg.offsetTop && fly_Y < bg.offsetTop + bg.offsetHeight - 30;
if (bgX && bgY) { //只有在游戏背景区域内飞机才跟随鼠标移动
fly.style.top = fly_Y + 'px'; //将鼠标此时的坐标赋值给我方飞机
fly.style.left = fly_X + 'px';
//此时飞机跟随鼠标移动,我们为该行为定义一个属性
fly.follow = true; //今后follow为true则代表飞机可跟随鼠标移动,false则相反
}
}
//创建子弹
var objB = { //子弹相关变量
name: 'bullet', //名称
num: 1, //数量
arr: [], //子弹的属性['id|top|left']
width: 5, //子弹宽
height: 10, //子弹高
path: './img/bullet.png'
}
creatBullet(objB);
function creatBullet(obj) {
setInterval(function () {
var fly = document.getElementById('my_fly');
if (fly.follow) { //当飞机可跟随鼠标移动时可以发射子弹
var bull = document.createElement('div'); //创建div元素作为子弹
bull.id = obj.name + obj.num; //子弹的id名随创建数量不断变化(因为id值唯一)
var length = obj.arr.length;
if (length < 40) {
obj.arr[length] = bull.id + '|';
obj.num++;
bull.style.width = obj.width + 'px'; //子弹的相关属性
bull.style.height = obj.height + 'px';
bull.style.position = 'absolute';
bull.style.background = 'url(' + obj.path + ')';
bull.style.top = parseInt(fly.style.top) + 'px'; //子弹发出的位置
obj.arr[length] = obj.arr[length] + bull.style.top + '|';
bull.style.left = parseInt(fly.style.left) + 12 + 'px';
obj.arr[length] = obj.arr[length] + bull.style.left;
}
document.body.appendChild(bull); //将子弹添加到body
}
}, 700)
}
//让子弹运动起来
function moveBullet() {
var fly = document.getElementById('my_fly');
if (fly.follow) {
for (var i = 0; i < objB.arr.length; i++) { //遍历子弹的对象
var newArr = objB.arr[i].split('|'); //将数组arr中的元素切割出来放入新数组
var eleB = document.getElementById(newArr[0]);
//切割后第0项为id 第一项为top 第二项为left
newArr[1] = parseInt(newArr[1]) - 1; //数组第一项为top,不断减1则子弹便会向上运动
eleB.style.top = newArr[1] + 'px';
objB.arr[i] = newArr[0] + '|' + newArr[1] + '|' + newArr[2];
if (newArr[1] < 0) { //第一项为top,当top小于0 也就是子弹走出游戏面板时删除该子弹
objB.arr.splice(i, 1);
var delEle = document.getElementById(newArr[0]); //获取走出面板的子弹
delEle.parentNode.removeChild(delEle); //删除自身
}
}
}
}
//创建敌机(与创建子弹类似)
var objF = { //敌机相关变量
name: 'foe', //名称
num: 1, //数量
arr: [], //敌机的属性['id|top|left']
width: 34, //敌机宽
height: 24, //敌机高
path: './img/he_fly.png'
}
creatFoe(objF);
function creatFoe(obj) {
setInterval(function () {
var fly = document.getElementById('my_fly');
var bg = document.getElementById('background'); //获取背景
if (fly.follow) { //当飞机可跟随鼠标移动时出现敌机
var bull = document.createElement('div'); //创建div元素作为敌机
bull.id = obj.name + obj.num; //子弹的id名随创建数量不断变化(因为id值唯一)
var length = obj.arr.length;
if (length < 40) {
obj.arr[length] = bull.id + '|';
obj.num++;
bull.style.width = obj.width + 'px';
bull.style.height = obj.height + 'px';
bull.style.position = 'absolute';
bull.style.background = 'url(' + obj.path + ')';
bull.style.top = 0; //敌机的顶部初始位置为0
obj.arr[length] = obj.arr[length] + bull.style.top + '|';
bull.style.left = bg.offsetLeft + 290 * Math.random() + 'px'; //敌机的左侧初始位置为随机
obj.arr[length] = obj.arr[length] + bull.style.left;
}
document.body.appendChild(bull); //将敌机添加到body
}
}, 1000)
}
//让敌机运动起来
function moveFoe() {
var fly = document.getElementById('my_fly');
var bg = document.getElementById('background'); //获取背景
if (fly.follow) {
for (var i = 0; i < objF.arr.length; i++) { //遍历敌机的对象
var newArr = objF.arr[i].split('|'); //将数组arr中的元素切割出来放入新数组
var eleB = document.getElementById(newArr[0]);
//切割后第0项为id 第一项为top 第二项为left
newArr[1] = parseInt(newArr[1]) + 1; //数组第一项为top,不断加1则飞机便会向下运动
eleB.style.top = newArr[1] + 'px';
objF.arr[i] = newArr[0] + '|' + newArr[1] + '|' + newArr[2];
if (newArr[1] > bg.offsetLeft - 30) {
objF.arr.splice(i, 1);
var delEle = document.getElementById(newArr[0]);
delEle.parentNode.removeChild(delEle);
}
}
}
}
//调用运动函数
setInterval(function () {
moveBullet(); //子弹运动
moveFoe(); //敌机运动
//子弹和敌机相遇时消失
for (var i = 0; i < objF.arr.length; i++) {
var newArr = objF.arr[i].split('|');
var eleF = document.getElementById(newArr[0]);
var xFS = parseInt(newArr[2]);
var xFE = parseInt(newArr[2]) + 34;
var yFS = parseInt(newArr[1]);
var yFE = parseInt(newArr[1]) + 24;
for (var j = 0; j < objB.arr.length; j++) {
var newArr1 = objB.arr[j].split('|');
var eleB = document.getElementById(newArr1[0]);
var xB = parseInt(newArr1[2]);
var yB = parseInt(newArr1[1]);
var xCheck = xB > xFS && xB < xFE;
var yCheck = yB > yFS && yB < yFE;
if (xCheck && yCheck) {
objF.arr.splice(i, 1);
eleF.parentNode.removeChild(eleF);
objB.arr.splice(j, 1);
eleB.parentNode.removeChild(eleB);
}
}
}
}, 10)
</script>
</html>
四、涉及要点
鼠标进入游戏界面时触发元素运动
dom 事件 onmousemove 当指针在元素上方移动时,发生此事件。
创建战机、子弹
document.createElement(element)
创建 HTML 元素,可以 element.id、element.style、element.innerHTML 等为其设置相关属性;
//创建我方战机 var fly = document.createElement('div'); //创建一个div fly.id = 'my_fly'; //为div添加id名
删除战机、子弹
document.removeChild(element)
删除 HTML 元素,可以结合父元素 parentNode 使用,如我们删除走出游戏面板的子弹,先找到子弹,再删除该子弹自身,其实就是删除该元素的父元素的子元素;
var delEle = document.getElementById(newArr[0]); //获取走出面板的子弹 delEle.parentNode.removeChild(delEle); //删除自身
将创建的 dom 元素追加到页面
document.appendChild(element)
添加 HTML 元素, 每一个创建完的 dom 元素都需要添加后才能显示,如我们将创建的我方战机添加到 body 中;
document.body.appendChild(fly); //将刚创建的div追加到body中
五、代码释义
这段代码是一个简单的HTML5游戏框架,模拟了一个飞机大战游戏的基本功能。它包括了游戏背景、我方飞机、子弹和敌机的创建与移动,以及子弹与敌机相遇时的处理。下面是详细的解释:
HTML部分
<div id="background"></div>
:这是游戏的主要背景,用于显示游戏画面。
CSS部分
- 初始化所有元素的
margin
和padding
为0。 #background
设置了游戏背景的宽度、高度和背景图片。#my_fly
设置了我方飞机的样式,包括大小、绝对定位和鼠标指针样式。
JavaScript部分
创建我方飞机
- 使用
document.createElement('div')
创建一个div
元素,并设置其id
为my_fly
。 - 在
div
中插入飞机的图片,并将其添加到body
中。
飞机鼠标跟随
- 监听
document
的onmousemove
事件,获取鼠标位置。 - 计算飞机应该移动到的位置(鼠标位置减去飞机宽高的一半),确保飞机在游戏背景区域内时才移动。
创建子弹
- 定义一个对象
objB
来存储子弹的相关信息(如名称、数量、数组、宽高、图片路径)。 - 使用
setInterval
函数周期性创建子弹,并将其添加到body
中。 - 子弹的初始位置设为我方飞机的位置,并向右偏移一定距离。
子弹运动
- 定义一个
moveBullet
函数,用于移动所有子弹。 - 遍历子弹数组,更新每个子弹的
top
样式,使其向上移动。 - 如果子弹移出游戏区域,则从数组中删除并移除DOM元素。
创建敌机
- 定义一个对象
objF
来存储敌机的相关信息。 - 使用
setInterval
函数周期性创建敌机,敌机的初始位置在背景区域内随机生成。
敌机运动
- 定义一个
moveFoe
函数,用于移动所有敌机。 - 遍历敌机数组,更新每个敌机的
top
样式,使其向下移动。 - 如果敌机移出游戏区域,则从数组中删除并移除DOM元素。
子弹与敌机碰撞检测
- 在
setInterval
中,除了移动子弹和敌机外,还进行碰撞检测。 - 遍历所有敌机和子弹,检查它们的位置是否重叠。
- 如果检测到碰撞,则从数组中删除相应的敌机和子弹,并从DOM中移除它们。
注意事项
- 代码中使用了
setInterval
来周期性执行函数,这可能会导致性能问题,特别是在创建大量子弹和敌机时。 - 碰撞检测是简单的矩形碰撞,没有考虑图像的实际形状。
- 代码中
objB.arr
和objF.arr
用于存储子弹和敌机的信息,但它们的存储方式(使用字符串拼接)并不高效,且易于出错。可以考虑使用对象数组来存储更丰富的信息。 - 游戏逻辑和样式都直接写在HTML文件中,这在实际项目中通常不是最佳实践。可以考虑将JavaScript和CSS代码分离到单独的文件中。
六、案例素材
背景 bg.jpg
己方飞机 my_fly.png
敌方飞机 he_fly.png
子弹 bullet.png
这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!
更多推荐
所有评论(0)