一镜到底,围观一个周边猜猜看是如何实现的【玩转Web小游戏】
星光坠心
一切还要从我收到拍拍灯说起。
我之前收到一份神秘的周边,打开发现竟然是期待已经的拍拍灯,实物如下,造型蛮特别的。
我看着这昏黄的光,似遥远星球闪耀的星光,一下子来了灵感。
新年 FLAG,当然是拥有更多掘金周边。拍拍灯算一个,再加上几款新年限定,可以在练练看中组合「出道」。这样一来新年愿望就达成了一半(另一半靠接下来的努力)。
有些路,想着想着就走通了。
我用了52秒决定做一个功能,又用了10分钟想清楚实现过程。
接下来,和我一起围观,如何实现一个网页游戏,一个遮挡版的掘金周边连连看。
试玩一刻
周边解锁
如果出现如下的界面,恭喜,已解锁小游戏中的全部周边图片。
细听分说
一句话介绍
12张头像图片遮挡了6组掘金周边,每次的点击可以掀开被隐藏的掘金周边,确定两个一样的周边,直到六组全部被找到,游戏通关。
一表格演示
规则 |
规则内容 |
展示规则 |
1、遮挡头像图片每次会随机展示一张运营大佬的头像。 2、6组周边的展示位置是随机的,每次刷新或者重开游戏,会重排位置。 |
遮挡规则 |
1、每次点击查看一个周边。 2、两次是否相同
|
通关规则 |
1、找到全部6组周边,游戏成功。 2、成功之后
|
重开规则 |
1、游戏通关弹窗中,有重开按钮; 2、游戏中,可以点击游戏机底部按钮,进行重开。 |
解锁规则 |
1、根据当前游戏玩家的id判断是否有解锁功能; 2、待开发功能。 |
一镜到底
那日的夜幕下,连连看的实现过程,在我的脑海里,像一部短片,镜头从头到尾,没有一刻的晃动。
我带着奇妙的观影感,一镜到底,丝滑的实现了整个游戏的开发。
从造型开始
我想一个有趣的内在,也应该拥有一个有趣的外在,换了几次装,想到之前实现过一个游戏机的功能,于是给连连看增加了一个游戏机的外型。
<div class="game"></div>
变化的乐趣
我曾经玩过的游戏,印象有些模糊了,但是这次我想遮挡的图案是变化的,会更有趣。
我在想遮盖图案的随机和周边图案摆放的随机时,意外的发现,可以用相同的方式,即都是从一组图片中随机取一张。
只不过,遮盖图案全部都是同一个,周边图片每组是同一个。
获取随机值
- 设置一个随机空数组;
- 进行循环操作,从目标数组中,每次随机得到索引值;
- 通过索引得到对应的元素,存入新数组中,而目标数组去掉该元素;
- 直到目标数组的值为空,此时就得到了完整的随机之后的新数组。
// 数组随机排序
function getListRandom(list) {
let randomList = [];
let listInit = [].concat(list);
while (listInit.length > 0) {
// 获取随机数索引值
let numIndex = Math.floor(Math.random() * listInit.length);
randomList.push(listInit[numIndex]);
// 将当前索引对应的元素去除
listInit.splice(numIndex, 1);
}
return randomList;
}
随机,遮盖图案
1、定义一组图案。
var itemImageSrcListInit = ['https://p3-passport.byteimg.com/img/user-avatar/0779dd287afeb3e6a983deb0ff79d724~180x180.awebp', 'https://p3-passport.byteimg.com/img/user-avatar/8db3fdff9a85ee60ad0e6706b6632064~180x180.awebp', 'https://p3-passport.byteimg.com/img/user-avatar/ed03b70fe4ab1ce93c74ff5cf4ae82d0~180x180.awebp', 'https://p3-passport.byteimg.com/img/user-avatar/5d08c09da9bffd1331bc6220b884a466~180x180.awebp', 'https://p3-passport.byteimg.com/img/user-avatar/b72e991ee9b1c9bdca7b2bd4c8dc78a8~180x180.awebp', 'https://p3-passport.byteimg.com/img/user-avatar/7e4a7c01e7022917f7242419f19a6c03~180x180.awebp', 'https://p3-passport.byteimg.com/img/user-avatar/e3a142ceef01d6d640ac417a16f127f6~180x180.awebp', 'https://p3-passport.byteimg.com/img/user-avatar/8378ae90f38c97148d85582b480fd3ad~180x180.awebp'];
2、得到随机图案数组,页面遮挡元素进行循环,将得到的图案,按照索引值,一一进行回显。
// 遮挡图片随机
function initItemImageList(itemImageSrcListInit, itemImageList) {
let itemImageSrcList = getListRandom(itemImageSrcListInit);
for (let i = 0; i < itemImageList.length; i++) {
itemImageList[i].src = itemImageSrcList[0];
itemImageList[i].style.display = 'block';
itemImageList[i].classList.remove('hidden');
// vip不遮挡
if (vipFlag) {
itemImageList[i].style.display = 'none';
}
}
}
3、还有一个特殊处理,初始化遮挡图案的展示样式,后续会用到。
随机,周边图案
1、定义一组周边图案。
var positionImageList = ['https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1c27f38b3f5746e5b368385504af2d0c~tplv-k3u1fbpfcp-no-mark:0:0:0:0.image?', 'https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/59eb9d261a9f487a9674a2bc9049bea7~tplv-k3u1fbpfcp-no-mark:0:0:0:0.image?', 'https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/31198c6444a94f129caaf4d5eecb667b~tplv-k3u1fbpfcp-no-mark:0:0:0:0.image?', 'https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c918c454e0ae4e5da06f08fc3b597c9c~tplv-k3u1fbpfcp-no-mark:0:0:0:0.image?', 'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b9ec814cb7c143f7a271ebda55f85819~tplv-k3u1fbpfcp-no-mark:0:0:0:0.image?', 'https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d9694d784a75485b943f152ff3a88c2d~tplv-k3u1fbpfcp-no-mark:0:0:0:0.image?'];
2、再定义一组位置索引值。
var positionListInit = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
3、得到位置索引的随机数组,页面周边元素进行循环,将索引随机数组得到周边图案,回显到页面对应的元素中。
// 位置随机
function initPositionList(positionListInit, coverImageList) {
let positionList = getListRandom(positionListInit);
for (let i = 0; i < coverImageList.length; i++) {
let positionListIndex = positionList[i];
coverImageList[i].src = positionImageList[positionListIndex];
setTimeout(function () {
coverImageList[i].style.display = 'block';
}, 500);
}
}
4、因为遮挡图案也是随机获取的,两个随机一起进行,可能图案会出现交错,所以我将周边图案的回显延迟了500毫秒。
追逐与嬉戏
前期的背景、走位已布置分配妥当,接下来就开始点击进行玩耍了。
1、监听每个元素的点击事件。
for (let i = 0; i < itemList.length; i++) {
// 监听点击事件
itemList[i].onclick = function () {
......
};
}
2、设置一个接收点击位置的数组,后面的相同判断和重组都是通过它进行判断的。
// 接收每次点击的位置 当长度等于2的时候情况
var receivePositionList = [];
每次点击之后,将点击元素的索引放入接收数组中。
receivePositionList.push(i);
3、点击时,对应的遮挡元素添加隐藏样式
itemImageList[i].classList.add('hidden');
// 一段时间之后因此动画
setTimeout(function () {
itemImageList[i].style.display = 'none';
}, 500);
4、当接收数组的长度等于2时,开始判断两个位置的周边是否相同。
- 如果不同,则继续进行遮挡,并移除遮挡的动画。
- 如果相同,成功的数量增加1。
最后将接收数组的值清空。
// 当点击的位置的数量是两个的时候 判断是否一致
if (receivePositionList.length === 2) {
let positionIndex1 = receivePositionList[0];
let positionIndex2 = receivePositionList[1];
// 两个一致则连连看成功的数量加1
if (coverImageList[positionIndex1].src === coverImageList[positionIndex2].src) {
receiveCount += 1;
} else {
if (!vipFlag) {
// 两个不一致则关闭
setTimeout(function () {
itemImageList[positionIndex1].style.display = 'block';
itemImageList[positionIndex1].classList.remove('hidden');
itemImageList[positionIndex2].style.display = 'block';
itemImageList[positionIndex2].classList.remove('hidden');
}, 800);
}
}
// 清空接受的位置
receivePositionList = [];
}
5、当所有的周边都被连成功之后,给出成功提示。
let positionListLen = positionListInit.length;
if (receiveCount === positionListLen / 2) {
setTimeout(function () {
openModal('restart');
}, 800);
}
倒带重来
既然是游戏,肯定想多玩几次,所以我设计了游戏重开的功能,有两个入口。
1、成功提示弹层上面增加了「重新开始」的按钮。
点击「重新开始」,重置周边连接成功的数据和接收位置的值,重新计算遮挡和周边的位置,并关闭弹窗。
// 弹窗重开
modalBtn.onclick = function () {
if (modalType === 'restart') {
initData();
receivePositionList = [];
receiveCount = 0;
}
closeModal();
};
这里有一个需要注意的点,就是成功连接所有周边,遮挡图片被添加了样式,重开的时候需要进行一次初始化处理,否则样式会有问题,所以前面提到了特殊处理。
2、在游戏机底部有「重开」的按钮。
点击「重开」,重置数据。
// 按钮重开
btnRestart.onclick = function () {
initData();
receivePositionList = [];
receiveCount = 0;
};
未完待续
一个基础版的连连看小游戏,从游戏规则到游戏实现的全过程,到这就基本结束了。
接下来是收获时刻,简单总结一下:
小游戏的基本特点
- 简单有趣又解压。
- 麻雀虽小,五脏俱全。有开始的功能,也要有重新开始的功能。
猜猜看的基本特点
- 多组相同的图案。
- 图案的随机摆放。
- 相连的两次操作中,相同与不同的处理。
提升之处
除去编程实现功能的快乐等收获,逻辑思维的训练,创意思路的繁衍,也在每一次的创作中,增强、加快、演化。
创作心得
除去功能实现过程的分享,还想跟大家分享一下我的心得:
遇见它,了解它,实现它。
因为这样的创作理念,除去过去的这一年,我实现了多个小游戏。
后会有期
我还有多个待实现的创意想法,正在欢快的排队中。期待后面的相见。
作者:非职业「传道授业解惑」的开发者叶一一
简介:「趣学前端」、「CSS畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)