前端案例:飞机大战( js+dom 操作,代码完整,附图片素材)

简介: 前端案例:飞机大战( js+dom 操作,代码完整,附图片素材)

一、案例效果

1.gif


二、实现思路

创建游戏背景板;

创建我方战机,鼠标进入游戏面板后其随鼠标轨迹运动; 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中

五、案例素材

背景 bg.jpg

image.png

己方飞机 my_fly.png

image.png



敌方飞机 he_fly.png

image.png



子弹 bullet.png

image.png

相关文章
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
388 57
|
1月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
上下文选择器(迭代选择器):基于祖先或同胞元素选择一个元素 ID和类选择器:基于id#和class的属性值进行选择元素。 属性选择器:基于属性的有无和特征进行选择。 ①上下文选择器: 上下文选择器的语法格式:标签1 标签2{属性:值;} //注意:组合选择器和上下文选择器的区别,组合选择器以逗号隔开, 上下文选择器以空格隔开 ②特殊的上下文选择器 子选择器> : 语法格式:标签1>标签2 解释说明:标签1和标签2
206 1
|
9月前
|
JavaScript 前端开发 索引
40个JS常用使用技巧案例
大家好,我是V哥。在日常开发中,JS是解决页面交互的利器。V哥总结了40个实用的JS小技巧,涵盖数组操作、对象处理、函数使用等,并附带案例代码和解释。从数组去重到异步函数,这些技巧能显著提升开发效率。先赞再看后评论,腰缠万贯财进门。关注威哥爱编程,全栈开发就你行!
287 16
|
8月前
|
JavaScript 前端开发 Java
深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
Array.find() 是 JavaScript 数组方法中一个非常实用和强大的工具。它不仅提供了简洁的查找操作,还具有性能上的独特优势:返回的引用能够直接影响原数组的数据内容,使得数据更新更加高效。通过各种场景的展示,我们可以看到 Array.find() 在更新、条件查找和嵌套结构查找等场景中的广泛应用。 在实际开发中,掌握 Array.find() 的特性和使用技巧,可以让代码更加简洁高效,特别是在需要直接修改原数据内容的情形。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
8月前
|
监控 JavaScript 前端开发
MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例
MutationObserver 是一个非常强大的 API,提供了一种高效、灵活的方式来监听和响应 DOM 变化。它解决了传统 DOM 事件监听器的诸多局限性,通过异步、批量的方式处理 DOM 变化,大大提高了性能和效率。在实际开发中,合理使用 MutationObserver 可以帮助我们更好地控制 DOM 操作,提高代码的健壮性和可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
JavaScript 前端开发 开发者
.js的dom元素操作
【10月更文挑战第29天】通过灵活运用这些 DOM 元素操作方法,JavaScript 可以实现丰富的网页交互效果,如动态更新页面内容、响应用户操作、创建和删除页面元素等。在实际开发中,开发者可以根据具体的需求和场景,选择合适的 DOM 元素操作方法来实现所需的功能,为用户提供更加流畅和动态的网页体验。
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
1019 14
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
326 0
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
456 6

热门文章

最新文章

下一篇
oss云网关配置