草庐IT

前端飞机大战小游戏

mochenxiya 2023-03-28 原文

一、案例效果

点击打开视频讲解更加详细

二、实现思路

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

若对您有帮助,请点击跳转到B站一键三连哦!感谢支持!!!

有关前端飞机大战小游戏的更多相关文章

  1. ruby - 我需要从 facebook 游戏中抓取数据——使用 ruby - 2

    修改(澄清问题)我已经花了几天时间试图弄清楚如何从Facebook游戏中抓取特定信息;但是,我遇到了一堵又一堵砖墙。据我所知,主要问题如下。我可以使用Chrome的检查元素工具手动查找我需要的html-它似乎位于iframe中。但是,当我尝试抓取该iframe时,它​​是空的(属性除外):如果我使用浏览器的“查看页面源代码”工具,这与我看到的输出相同。我不明白为什么我看不到iframe中的数据。答案不是它是由AJAX之后添加的。(我知道这既是因为“查看页面源代码”可以读取Ajax添加的数据,也是因为我有b/c我一直等到我可以看到数据页面之后才抓取它,但它仍然不存在)。发生这种情况是因为

  2. python - Ruby 或 Python 的 3d 游戏引擎? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion是否有适用于这些的3d游戏引擎?

  3. ruby-on-rails - 在 Rails 应用程序的前端获取实时日志 - 2

    在Rails3.x应用程序中,我正在使用net::ssh并向远程pc运行一些命令。我想向用户的浏览器显示实时日志。比如,如果两个命令在net中运行::ssh执行即echo"Hello",echo"Bye"被传递然后"Hello"应该在执行后立即显示在浏览器中。这是代码我在ruby​​onrails应用程序中使用ssh连接和运行命令Net::SSH.start(@servers['local'],@machine_name,:password=>@machine_pwd,:timeout=>30)do|ssh|ssh.open_channeldo|channel|channel.requ

  4. ruby - 如何在转换器插件中访问页面属性(YAML 前端) - 2

    我正在为Jekyll编写一个转换器插件,需要访问一些页眉(YAML前端)属性。只有内容被传递给主要的转换器方法,似乎无法访问上下文。例子:moduleJekyllclassUpcaseConverter关于如何在转换器插件中访问页眉数据有什么想法吗? 最佳答案 基于Jekyll源代码,无法在转换器中检索YAML前端内容。根据您的情况,我看到了两种可行的解决方案。您的文件扩展名可以具有足够的描述性,以提供您本应包含在前言中的信息。看起来Converter插件的设计就是这么基本的。如果修改Jekyll是一个选项,您可以更改Convert

  5. ruby - 使用 Ruby 编写 Unity 游戏 - 2

    所以我看到unity支持c#、JS和Boo。我可以学习其中一个,但我想制作一个“编译器”或类似的东西,让我可以编写ruby​​代码并输出JS代码或制作一个可以被Unity编译器读取的层。这有可能吗?我愿意在这方面投入很多时间并且有相当多的经验。 最佳答案 如果您的问题实际上是“我如何将Ruby编译为JavaScript”,那么这更容易回答:Opal:RubytoJavaScriptcompiler但是,学习其中一种受支持的语言会更好。当运行的是用另一种语言解释的代码时,很难调试“您的”代码。

  6. 【Unity游戏破解】外挂原理分析 - 2

    文章目录认识unity打包目录结构游戏逆向流程Unity游戏攻击面可被攻击原因mono的打包建议方案锁血飞天无限金币攻击力翻倍以上统称内存挂透视自瞄压枪瞬移内购破解Unity游戏防御开发时注意数据安全接入第三方反作弊系统外挂检测思路狠人自爆实战查看目录结构用il2cppdumper例子2-森林whoishe后记认识unity打包目录结构dll一般很大,因为里面是所有的游戏功能编译成的二进制码游戏逆向流程开发人员代码被编译打包到GameAssembly.dll中使用il2ppDumper工具,并借助游戏名_Data\il2cpp_data\Metadata\global-metadata.dat

  7. Unity游戏开发:背包系统的实现 - 2

    背包是游戏中经常使用的一个组件,它负责管理玩家在游戏中所获得的道具。一个完整的背包系统应当具有将物品放置进背包、对背包内物品进行管理和使用背包内物品等功能。而往往一个背包系统的逻辑关系较为复杂,如果把所有功能都放在一个脚本中实现会使代码显得十分冗杂且缺乏逻辑。所以在背包系统的设计过程中,我们常将其分解为数据、逻辑和UI三部分分别来进行完成。一、UI设计以CottonPuzzle中的背包设计为例,我们需要有物品展示栏、物品切换按键和物品提示信息等部分。在Canvas中创建ItemHolder,在ItemHolder中创建LeftButton和RightButton控制物品的左右切换、Slot来控

  8. 前端实现文件上传(点击+拖拽) - 2

    一、简介之前在Vue项目中使用过element的上传组件,实现了点击上传+拖拽上传的两种上传功能。然后我就在想是否可以通过原生的html+js来实现文件的点击上传和拖拽上传,说干就干。首先是点击获取上传文件自然没的说,只需要借助input标签即可,但原生的点击上传按钮,实在是过于简陋,所以我的想法是通过一个div,模拟成上传按钮,然后监听其点击事件,通过input.click()去模拟点击真正的上传元素。然后是拖拽获取上传文件,这个稍有难度,我的想法是通过HTML5新增的drag拖放API+dataTransfer来实现文件的拖拽获取,但是由于是html5新增的,所以可能在某些低版本IE浏览器

  9. 仍在积极维护的 Ruby 游戏框架? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭7年前。Improvethisquestion我发现很难调查使用Ruby进行游戏编程的选项。其他帖子和文章中提到的几个包装器和框架不再维护或使用。Gosu/Ruby似乎仍然活跃:官方论坛上的讨论一直很稳定。是否还有其他积极维护的ruby​​游戏框架?编辑:我发现使用MacRuby进行大量游戏开发。

  10. ruby - 基于 OOP 的文本游戏中的优雅命令解析 - 2

    我正在玩用Ruby编写MUD/文本冒险(请不要笑)。谁能给我任何关于解析输入文本的优雅的、基于oop的解决方案的建议?我们在这里谈论的只是“把魔杖放在table上”更复杂的事情。但是一切都需要柔软;我想稍后轻松地扩展命令集。我目前的想法,稍微简化一下:每个项目类别(盒子、table、房间、播放器)都知道如何识别“属于”它的命令。游戏类理解一种特定于领域的语言,涉及诸如“将对象X移入对象Y”、“显示对象X的描述”等Action。游戏类询问房间中的每个项目是否识别输入命令。先说是赢。然后它将控制传递给项目类中处理命令的方法。此方法重新表述DSL中的命令,将其传递回游戏对象以实现它。必须有一

随机推荐