草庐IT

前端搭建砸地鼠游戏(内附源码)

几何心凉 2023-05-23 原文

The sand accumulates to form a pagoda


✨ 写在前面

上周我们实通过前端基础实现了打字通,当然很多伙伴再评论区提出了想法,后续我们会考虑实现的,今天还是继续按照我们原定的节奏来带领大家完成一个砸地鼠的小游戏,功能也比较简单简单,也是想借助这样一个简单的功能,然后来帮助大家了解我们JavaScript在前端中的作用, 在前面的文章当中我们也提及到我们在本系列的专栏是循序渐进从简单到复杂的过程,后续会带领大家用前端实现翻卡片、扫雷、贪吃蛇等有趣的小游戏,纯前端语言实现,都会陆续带给大家。欢迎大家订阅我们这份前端小游戏的专栏。


✨ 功能介绍

游戏开始后再几个鼠洞会随机出现老鼠,停留时间随机,我们需要点击老鼠分数加一,倒计时60秒会为我们计算分数,点击在玩一次可以重新开始游戏,大家可以根据自己的想法来设置游戏规则;如果大家可以跟上的话可以通过修改代码来提升难度,比如我们增加鼠洞或者我们减少老鼠存留的时长,很简单的功能大家可以尝试添加进去,如果遇到问题大家可以留言或者私信我,当然大家也可以将样式设置的非常漂亮,这里我们主要是针对前端的初学者来进行的讲解,对于样式的配置我们循序渐进。


✨ 页面搭建

创建文件

首先呢我们创建我们的HTML文件,这里我就直接命名为 砸地鼠.html 了,大家可以随意命名, 文件创建生成后我们通过编辑器打开,这里我用的是VScode, 然后初始化我们的代码结构,那在这里告诉大家一个快捷键,就是我们敲上我们英文的一个 ! 我们敲击回车直接就会给我们生成基础版本的前端代码结构。

文档声明和编码设置: 在HTML文档的头部,使用<!DOCTYPE>声明HTML文档类型,确保浏览器以正确的方式渲染网页内容。同时,设置UTF-8编码,以确保浏览器能够正确地解析和显示中文字符。下面我就开始搭建我们的DOM结构了!

DOM结构搭建

<h1>砸地鼠</h1>:这是一个标题标签,用于在页面中显示标题“砸地鼠”。<div class="bigBox">...</div>:这是一个包含游戏区域的div标签,其类名为“bigBox”。<div class="wam-container">...</div>:这是游戏区域的容器,其中包含了多个“地鼠洞”,每个洞都有一个地鼠元素。这个标签的类名为“wam-container”。<div class="wam-hole">...</div>:这是地鼠洞的标签,用于容纳地鼠。这个标签的类名为“wam-hole”。<div class="wam-mole">...</div>:这是地鼠的标签,用于显示出现的地鼠。这个标签的类名为“wam-mole”。<div class="wam-score">分数: 0</div>:这是显示游戏得分的标签,初始值为0。这个标签的类名为“wam-score”。<div class="wam-message">准备好了吗?点击我开始</div>:这是显示游戏提示信息的标签,用于引导用户开始游戏。这个标签的类名为“wam-message”。总的来说,这段代码包含了一个游戏区域、得分、提示信息等元素。在后续的JavaScript代码中,会通过控制CSS样式等方式实现具体的游戏功能。

<h1>砸地鼠</h1>
<div class="bigBox">
  <div class="wam-container">
    <div class="wam-hole">
      <div class="wam-mole">
      </div>
    </div>
    <div class="wam-hole">
      <div class="wam-mole">
      </div>
    </div>
    <div class="wam-hole">
      <div class="wam-mole">
      </div>
    </div>
    <div class="wam-hole">
      <div class="wam-mole">
      </div>
    </div>
    <div class="wam-hole">
      <div class="wam-mole">
      </div>
    </div>
  </div>
  <div class="wam-score">分数: 0</div>
  <div class="wam-message">准备好了吗?点击我开始</div>
</div>


✨ 样式设置

我们看到了上面的的DOM已经搭建好了,但是很显然样式比较随意了,我们简单的来配置一下样式吧,其实我们本专栏也是想带领大家掌握一些逻辑所以样式方面我们就一切从简;样式设置包括游戏界面的样式,主要涉及颜色、字体、边框、内边距等属性。bigBox:设置宽度为60%,高度为400px,居中显示,并设置黄色背景色。wam-container:使用flex布局,设置高度为260px,让子元素居中显示。wam-hole:设置相对定位,宽度为100px,高度为100px,设置橙色背景色。
wam-mole:设置绝对定位,左上角对齐父元素,宽度和高度为100%。设置背景图片,并设置显示方式为none。wam-mole–up:继承了.wam-mole的样式,并且增加了display: block;属性,用于设置显示为坐标状态。wam-score:设置字体大小为2rem,居中显示。wam-message:设置字体大小为1rem,居中显示,顶部外边距为20px,并设置鼠标指针为手形。

<style>
  * {
    box-sizing: border-box;
  }

  h1 {
    text-align: center;
    line-height: 30px;
  }

  .bigBox {
    width: 60%;
    height: 400px;
    margin: 20px auto;
    background-color: #cbbb3e;
  }

  .wam-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    height: 260px;
  }

  .wam-hole {
    position: relative;
    width: 100px;
    height: 100px;
    margin: 0 20px;
    background-color: #f5732d;
  }

  .wam-mole {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: url('https://img0.baidu.com/it/u=681824710,2035204775&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500');
    background-size: 100% 100%;
    display: none;
  }

  .wam-mole--up {
    display: block;
  }

  .wam-score {
    font-size: 2rem;
    text-align: center;
  }

  .wam-message {
    font-size: 1rem;
    text-align: center;
    margin-top: 20px;
    cursor: pointer;
  }
</style>


✨ 逻辑部分

点击出现在洞中的地鼠,以获得分数。它使用JavaScript控制游戏的逻辑和动画效果。下面是一些重要的JS函数和变量的解释:document.querySelector('.wam-container') 获取一个名为"wam-container"的类,该类是一个包含5个地鼠洞的容器。Array.from(container.querySelectorAll('.wam-hole')) 把5个地鼠洞存储在一个数组中,以便后面随机生成地鼠。

const container = document.querySelector('.wam-container');
const scoreBoard = document.querySelector('.wam-score');
const message = document.querySelector('.wam-message');
const moles = Array.from(container.querySelectorAll('.wam-hole'));

popUpMole() 用于生成地鼠。它会随机选择一个地鼠洞,并将其中一个div元素(具有名为"wam-mole"的类)向上移动,从而模拟地鼠出现的效果。它使用setTimeout()函数定时将地鼠下移,并在随机时间后再次调用自身来显示另一个地鼠。randomHole(holes) 用于随机选择一个地鼠洞。它会返回一个地鼠洞,但会避免与上一个洞重复出现。whackMole(e) 用于当你点击地鼠时获得分数。它使用e.target.matches('.wam-mole')来检查你是否真正地点击到了地鼠本身。

let lastHole;
let score = 0;
let isPlaying = false;
let timeUp = false;

// 随机时间生成地鼠
function popUpMole () {
  if (timeUp) return;
  const time = Math.random() * (1500 - 500) + 500;
  const hole = randomHole(moles);
  hole.querySelector('div').classList.add('wam-mole--up');
  setTimeout(() => {
    hole.querySelector('div').classList.remove('wam-mole--up');
    if (!timeUp) popUpMole();
  }, time);
}

// 随机选择一个地鼠洞
function randomHole (holes) {
  const idx = Math.floor(Math.random() * holes.length);
  const hole = holes[idx];
  if (hole === lastHole) return randomHole(holes);
  lastHole = hole;
  return hole;
}

// 点击地鼠
function whackMole (e) {
  if (!e.isTrusted) return; // 防止作弊
  if (!isPlaying) return;
  if (!e.target.matches('.wam-mole')) return;
  score++;
  scoreBoard.textContent = `分数: ${score}`;
  e.target.parentNode.querySelector('div').classList.remove('wam-mole--up');
}

startGame() 开始游戏。它会重置分数、将isPlaying和timeUp变量设置为true和false,并使用setTimeout()在一定时间后结束游戏。同时,它还会调用popUpMole()函数开始生成地鼠。moles.forEach(mole => mole.addEventListener('click', whackMole)); 添加一个监听器,当你点击地鼠时,调用whackMole()来获得分数。document.querySelector('.wam-message').addEventListener('click', startGame); 添加一个监听器,当你点击开始按钮时,调用startGame()函数来开始游戏。

// 开始游戏
function startGame () {
  score = 0;
  scoreBoard.textContent = '分数: 0';
  isPlaying = true;
  timeUp = false;
  message.textContent = '';
  popUpMole();
  setTimeout(() => {
    isPlaying = false;
    timeUp = true;
    message.textContent = `一分钟您的得分是: ${score};点我再来一次!`;
  }, 60000);
}

// 初始化地鼠洞 
moles.forEach(mole => mole.addEventListener('click', whackMole));
document.querySelector('.wam-message').addEventListener('click', startGame);


✨ 完整代码

到这里呢我们的本节的大概逻辑就基本实现了,如果大家可以跟上的话可以通过修改代码来提升难度,比如我们增加鼠洞或者我们减少老鼠存留的时长,很简单的功能大家可以尝试添加进去,如果遇到问题大家可以留言或者私信我,当然大家也可以将样式设置的非常漂亮,这里我们主要是针对前端的初学者来进行的讲解,对于样式的配置我们循序渐进,如果你有能力可以挑战更加漂亮的界面或者更有趣的功能哦,还是一样我们将源码放在下面:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>砸地鼠</title>
  <style>
    * {
      box-sizing: border-box;
    }

    h1 {
      text-align: center;
      line-height: 30px;
    }

    .bigBox {
      width: 60%;
      height: 400px;
      margin: 20px auto;
      background-color: #cbbb3e;
    }

    .wam-container {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      align-items: center;
      height: 260px;
    }

    .wam-hole {
      position: relative;
      width: 100px;
      height: 100px;
      margin: 0 20px;
      background-color: #f5732d;
    }

    .wam-mole {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-image: url('https://img0.baidu.com/it/u=681824710,2035204775&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500');
      background-size: 100% 100%;
      display: none;
    }

    .wam-mole--up {
      display: block;
    }

    .wam-score {
      font-size: 2rem;
      text-align: center;
    }

    .wam-message {
      font-size: 1rem;
      text-align: center;
      margin-top: 20px;
      cursor: pointer;
    }
  </style>
</head>

<body>
  <h1>砸地鼠</h1>
  <div class="bigBox">
    <div class="wam-container">
      <div class="wam-hole">
        <div class="wam-mole">
        </div>
      </div>
      <div class="wam-hole">
        <div class="wam-mole">
        </div>
      </div>
      <div class="wam-hole">
        <div class="wam-mole">
        </div>
      </div>
      <div class="wam-hole">
        <div class="wam-mole">
        </div>
      </div>
      <div class="wam-hole">
        <div class="wam-mole">
        </div>
      </div>
    </div>
    <div class="wam-score">分数: 0</div>
    <div class="wam-message">准备好了吗?点击我开始</div>
  </div>

  <script>
    const container = document.querySelector('.wam-container');
    const scoreBoard = document.querySelector('.wam-score');
    const message = document.querySelector('.wam-message');
    const moles = Array.from(container.querySelectorAll('.wam-hole'));

    let lastHole;
    let score = 0;
    let isPlaying = false;
    let timeUp = false;

    // 随机时间生成地鼠
    function popUpMole () {
      if (timeUp) return;
      const time = Math.random() * (1500 - 500) + 500;
      const hole = randomHole(moles);
      hole.querySelector('div').classList.add('wam-mole--up');
      setTimeout(() => {
        hole.querySelector('div').classList.remove('wam-mole--up');
        if (!timeUp) popUpMole();
      }, time);
    }

    // 随机选择一个地鼠洞
    function randomHole (holes) {
      const idx = Math.floor(Math.random() * holes.length);
      const hole = holes[idx];
      if (hole === lastHole) return randomHole(holes);
      lastHole = hole;
      return hole;
    }

    // 点击地鼠
    function whackMole (e) {
      if (!e.isTrusted) return; // 防止作弊
      if (!isPlaying) return;
      if (!e.target.matches('.wam-mole')) return;
      score++;
      scoreBoard.textContent = `分数: ${score}`;
      e.target.parentNode.querySelector('div').classList.remove('wam-mole--up');
    }
    // 开始游戏
    function startGame () {
      score = 0;
      scoreBoard.textContent = '分数: 0';
      isPlaying = true;
      timeUp = false;
      message.textContent = '';
      popUpMole();
      setTimeout(() => {
        isPlaying = false;
        timeUp = true;
        message.textContent = `一分钟您的得分是: ${score};点我再来一次!`;
      }, 60000);
    }

    // 初始化地鼠洞 
    moles.forEach(mole => mole.addEventListener('click', whackMole));
    document.querySelector('.wam-message').addEventListener('click', startGame);
  </script>
</body>

</html>

本期推荐

原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

有关前端搭建砸地鼠游戏(内附源码)的更多相关文章

  1. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

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

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

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

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

  4. elasticsearch源码关于TransportSearchAction【阶段三】 - 2

    1.回顾.TransportServicepublicclassTransportServiceextendsAbstractLifecycleComponentTransportService:方法:1publicfinalTextendsTransportResponse>voidsendRequest(finalTransport.Connectionconnection,finalStringaction,finalTransportRequestrequest,finalTransportRequestOptionsoptions,TransportResponseHandlerT>

  5. (附源码)vue3.0+.NET6实现聊天室(实时聊天SignalR) - 2

    参考文章搭建文章gitte源码在线体验可以注册两个号来测试演示图:一.整体介绍  介绍SignalR一种通讯模型Hub(中心模型,或者叫集线器模型),调用这个模型写好的方法,去发送消息。  内容有:    ①:Hub模型的方法介绍    ②:服务器端代码介绍    ③:前端vue3安装并调用后端方法    ④:聊天室样例整体流程:1、进入网站->调用连接SignalR的方法2、与好友发送消息->调用SignalR的自定义方法 前端通过,signalR内置方法.invoke()  去请求接口3、监听接受方法(渲染消息)通过new signalR.HubConnectionBuilder().on

  6. 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

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

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

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

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

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

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

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

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

随机推荐