美文网首页前端学习
实战!半小时写一个脑力小游戏

实战!半小时写一个脑力小游戏

作者: 1194b60087a9 | 来源:发表于2019-04-23 16:28 被阅读0次

    本实战使用了HTML5,CSS3和JavaScript的基本的技术。 我们将讨论数据属性、定位、透视、转换、flexbox、事件处理、超时和三元组。 你不需要在编程方面有太多的知识和经验就能看懂,不过还是需要知道HTML,CSS和JS都是什么。

    🕹Demo: Memory Game Project【https://marina-ferreira.github.io/memory-game/】(点击底部“原文”直达GayHub项目)

    项目结构

    先在终端中创建项目文件:

    HTML

    初始化页面模版并链接css文件js文件.

    这个游戏有 12 张卡片。 每张卡片中都包含一个名为.memory-card的容器div,它包含两个img元素。 一个代表卡片的正面front-face,另一个个代表背面back-face。

    您可以在GitHub下载本项目的资源文件: Memory Game Repo【https://github.com/code-sketch/memory-game】。

    这组卡片将被包装在一个section容器元素中。 最终代码如下:

    CSS

    我们将使用一个简单但非常有用的配置,把它应用于所有项目:

    box-sizing: border-box属性能使元素充满整个边框,所以我们就可以不用做一些数学计算了。

    把display:flex设置给body,并且把margin:auto应用到到.memory-game容器,这样可以使它将垂直水平居中。

    .memory-game是一个弹性容器,在默认情况下,里面的元素会缩小宽度来适应这个容器。通过把flex-wrap的值设置为wrap,会根据弹性元素的大小进行自适应。

    每个卡片的width和height都是用 CSS 的calc()函数进行计算的。 下面我们需要制作一个三行四列的界面,并且把width设置为25%,height设置为33.333%,还要再减去10px留足边距.

    为了定位.memory-card子元素,还要添加属性position: relative,这样我们就可以相对它进行子元素的绝对定位。

    把front-faceandback-face的position属性都设置为absolute,这样就可以从原始位置移除元素,并使它们堆叠在一起。

    这时页面模版看上去应该是这样:

    我们还需要添加一个点击效果。 每次元素被点击时都会触发:active伪类,它引发一个 0.2秒的过渡:

    翻转卡片

    要在单击时翻转卡片,需要把一个flip类添加到元素。 为此,让我们用document.querySelectorAll选择所有memory-card元素,然后使用forEach遍历它们并附加一个事件监听器。 每当卡片被点击时,都会触发flipCard函数,其中this代表被单击的卡片。 该函数访问元素的classList并切换到flip类:

    CSS 中的flip类会把卡片旋转180deg:

    为了产生3D翻转效果,还需要将perspective属性添加到.memory-game。 这个属性用来设置对象与用户在z轴上的距离。 值越小,透视效果越强。 为了能达得最佳的效果,把它设置为1000px:

    接下来对.memory-card元素添加transform-style:preserve-3d属性,这样就把卡片置于在父节点中创建的3D空间中,而不是将其平铺在z = 0的平面上(transform-style)。

    再把transition属性的值设置为transform就可以生成动态效果了:

    耶!现在我们得到了带有 3D 翻转效果的卡片, 不过为什么卡片的另一面没有出现? 由于绝对定位的原因,现在.front-face和.back-face都堆叠在了一起。 每个元素的back face都是它front face的镜像。 属性backface-visibility默认为visible,因此当我们翻转卡片时,得到的是背面的 JS 徽章。

    为了显示它背面的图像,让我们在.front-face和.back-face中添加backface-visibility:hidden。

    如果我们刷新页面并翻转一张卡片,它就消失了!

    img

    由于我们将两个图像都藏在了背面,所以另一面没有任何东西。 所以接下来需要再把.front-face翻转180度:

    效果终于出来了!

    匹配卡片

    完成翻转卡片的功能之后,接下来处理匹配的逻辑。

    当点击第一张卡片时,需要等待另一张被翻转。 变量hasFlippedCard和flippedCard用来管理翻转状态。 如果没有卡片翻转,hasFlippedCard的值为true,flippedCard被设置为点击的卡片。 让我们切换到toggle方法:

    现在,当用户点击第二张牌时,代码会进入else块,我们将检查它们是否匹配。为了做到这一点,需要能够识别每一张卡片。

    每当我们想要向HTML元素添加额外信息时,就可以使用数据属性。 通过使用以下语法:data-*,这里的*可以是任何单词,它将被插入到元素的 dataset 属性中。 所以接下来为每张卡片添加一个data-framework:

    这下就可以通过访问两个卡片的数据集来检查匹配了。 下面将匹配逻辑提取到它自己的方法checkForMatch(),并将hasFlippedCard设置为false。 如果匹配的话,则调用disableCards()并分离两个卡上的事件侦听器,以防止再次翻转。 否则unflipCards()会将两张卡都恢复成超过 1500 毫秒的超时,从而删除.flip类:

    把代码组合起来:

    更优雅的进行条件匹配的方法是用三元运算符,它由三部分组成: 第一部分是要判断的条件, 如果条件符合就执行第二部分的代码,否则执行第三部分:

    锁定

    现在已经完成了匹配逻辑,接着为了避免同时转动两组卡片,还需要锁定它们,否则翻转将会被失败。

    先声明一个lockBoard变量。 当玩家点击第二张牌时,lockBoard将设置为true,条件if (lockBoard) return;在卡被隐藏或匹配之前会阻止其他卡片翻转:

    点击同一个卡片

    仍然是玩家可以在同一张卡上点击两次的情况。 如果匹配条件判断为 true,从该卡上删除事件侦听器。

    为了防止这种情况,需要检查当前点击的卡片是否等于firstCard,如果是肯定的则返回。

    变量 firstCard和 secondCard需要在每一轮之后被重置,所以让我们将它提取到一个新方法 resetBoard()中, 再其中写上 hasFlippedCard = false;和 lockBoard = false。 es6 的解构赋值功能 [var1, var2] = ['value1', 'value2']允许我们把代码写得超短:

    接着调用新方法disableCards()和unflipCards():

    洗牌

    我们的游戏看起来相当不错,但是如果不能洗牌就没有乐趣,所以现在处理这个功能。

    当display: flex在容器上被声明时,flex-items会按照组和源的顺序进行排序。 每个组由order属性定义,该属性包含正整数或负整数。 默认情况下,每个flex-item都将其order属性设置为0,这意味着它们都属于同一个组,并将按源的顺序排列。 如果有多个组,则首先按组升序顺序排列。

    游戏中有12张牌,因此我们将迭代它们,生成 0 到 12 之间的随机数并将其分配给flex-item order属性:

    为了调用shuffle函数,让它成为一个立即调用函数表达式(IIFE),这意味着它将在声明后立即执行。 脚本应如下所示:

    终于完成了!

    十五年编程经验,今年1月整理了一批2019年最新WEB前端教学视频,不论是零基础想要学习前端还是学完在工作想要提升自己,这些资料都会给你带来帮助,从HTML到各种框架,帮助所有想要学好前端的同学,学习规划、学习路线、学习资料、问题解答。只要加入WEB前端学习交流Q群:296212562,即可免费获取。

    相关文章

      网友评论

        本文标题:实战!半小时写一个脑力小游戏

        本文链接:https://www.haomeiwen.com/subject/lvzvgqtx.html