翻牌小游戏(NG版)
18 Feb 2018
2018年第一篇,今天大年初三,回想起来,2017年给自己每个月必须产出一篇日志的目标,在最后一个月失败了,唯一欣慰的是,这一年里写的日志不低于12篇,虽然博客基本没人看,也就自己写着玩,不过记录一下还是好的。
因为十月份刚换了工作,新的工作比起之前的打鱼晒网来说,确实忙了不少,以往都是闲的发慌,赶紧找点东西学学,看点源代码,现在刚忙完一个需求,还没喘息过来,组长就给了我一个新的需求,所以比起之前的学习时间,现在就变得少了很多,有时候都没空优化之前的代码,更别说优化一下构建工具脚本了。
牢骚发完,继续这次的主题。这个小游戏是我四年前春节做的了,当时因为玩着一个类似的游戏,所以想着自己实现一个,当时也因为产品经理给我看一个网站的效果问我能否实现,于是有了启发。
这个游戏主要是通过点击翻转匹配消除的方式来得分通关。点我来玩啦~
实现
css
翻转的效果,是通过backface-visibility: hidden;
和transfrom
来实现的。前者是实现元素背面不可见,后者则是用于样式翻转。
布局
每张牌,通过设置两个div
(一个代表前面,一个代表后面)。 前者设置backface-visibility
来设置背面隐藏,通过设置点击翻转rotate
,同时翻转前后div,实现翻牌效果。
每张牌用一个唯一字符来表示,这样的话那么多个字符,其实能代表的牌数就很多了,每一个关初始化时,从字符池里随机出几个字符,再复制一倍,就有了n对字符,每次点击翻牌两张时,判断两者是否相同字符,是则消除,否则重新盖住。
对于牌子后面的图案,则采用font-face
属性来做设置,一方面,这样的话,每次游戏生成的字符就可以用简单的字母来做随机生成即可,将固定的字符固定对应不同的团并生成对应的font-face
文件即可。
逻辑实现
mvvm框架来说,重点是将展示的内容数据化,通过动态修改数据,从而触发界面重新渲染。在这里的话,我将界面展示的字符对存放到一个数组内,同时用一个变量来标识已经翻出一张牌所对应的数组的索引。
items: Item[]
first: number
level: number
由于牌子在展示上需要摆满一行,因此,我设定了一个级别,第一级每行只有两张牌,第二级则为三张牌,于是一行偶数张牌时(牌数n),则需要的牌数是n*n
,为奇数张牌时,需要的牌数为n*(n+1)
,这样就能保证不会凑不齐整行的牌了。
至于牌的字符集组合,直接用lodash的方法来打乱顺序,其次,代表牌的数组元素,用属性表示是否被翻开,是否已经被匹配,是否翻开过。
这样子做的情况下,在view层面就可以直接根据这几个属性,来处理牌的翻转、隐藏交互。
组件的模板可以这么做:
<div class="map" [ngStyle]="{'width': (80*(level+1))+'px'}">
<div *ngFor="let item of items; let i = index;" class="item"
[ngClass]="{'un':!item.showed, 'match':item.isCheck, 'show':item.isShow}"
(click)="clickItem(item, i);">
<div class="back"><span></span></div>
<div class="front"></div>
</div>
</div>
剩下的交互判断逻辑就很明了了。
至此,本篇结束,很奇怪,每次实现完一个东西,总不能很好的写出其内容来,有时候写文档确实比写代码要累得多,累的是整理。