我正在参加掘金社区游戏创意投稿大赛团队赛,详情请看:游戏创意投稿大赛
前言
wordle,一个作者没想到会流行起来的流行字母猜词游戏。
中文版wordle,叫做汉兜,是由Vue核心成员antfu开发的,并且已经开源。
正好碰上掘金游戏创意投稿大赛,就想着实现一个双简版wordle:汉林。顾名思义,双简版本呢,就是简单的简体中文版本wordle。简单的版本,还有点简单的bug,大家简单的玩一玩,简单的吐槽就好。
如果说汉兜的【每日一题】是致敬wordle,那我们的【同色标识】就是致敬汉兜。但是致敬经典,仅仅实现一个简单的版本那怎么行呢。因此,我们有一些和汉兜不一样的实现:随机词库的无限模式。
体验地址:wordle.lovetime.top/
技术选型
uniapp&uniCloud
看到掘金游戏创意大赛的时候,时间就稍微有些紧张了,而且wordle不同于传统类型的游戏,并不适用使用phaser/cocos等游戏引擎框架来实现,因此选择了基础件相对齐全、入门简单的uniapp结合uniCloud云开发搞起来。
云开发只是为了记录一些排行数据、在线增删词库信息,其实核心功能完全用不到云。
pinyin-pro
整理好基本需求之后,我们就在考虑关键点:成语的拼音格式输出。皇天不负有心人(OS:JavaScript真强大),看到了pinyin-pro 这个依赖包,它的介绍只有一句话“专业的汉字拼音转换工具”,清晰明了,直指本心,在这个需求里面,简直是贴心打造的完美助攻,感谢!
核心笔记
成语猜词很简单,怎么判断完全猜对了呢?强大的JavaScript的一个全等符号===就完美解决了。很简单,根本没有啥技术难度。
没错,就是这么简单。
但是,我们要考虑一下下用户猜错的情况。毕竟根据不靠谱数据显示,目前已收录成语都有三五万个(这里说的是成语,而非词语,词语大概是50多万个)。
用户猜错的时候,我们不能直接一个alert说:“不好意思,猜错啦,再试一下吧”。嗯,也不是不可以,就是可能会被用户打死。
因此,需要解决的核心问题就是如何优化用户猜错时的展示和提示。往大的说,就是让用户更好用;往小的说,就是让用户别老想着要打死我。
字符匹配逻辑
拆分匹配
成语的匹配,一是逐字(汉字)匹配,二是对每个字的不同部位进行匹配,也就是最终我们拆分开每部分进行处理。大致可以划分为声母(initial)匹配、韵母(final)匹配、声调(num)匹配、文字(term)匹配,最后还要处理一下声调的位置。
详见下图
拆分之后,我们还需要再抽象一下,把声母、韵母、声调、文字的匹配抽象为字符匹配。
字符匹配
首先对pinyin-pro的调用简单封装一下。因为我们拆分匹配的处理方式相同,输出相同类型的数组就行。
/**
* 拼音封装
* @param {String} word 传入的词语
* @param {String} pattern 输出的类型
* @param {String} toneType 输出形式
* @param {String} type 输出结果类型:字符串/数组
*/
export function convertPinyin(word, pattern = '', toneType = 'string', type = 'array') {
if (pattern === 'final') {
toneType = 'none'
}
return pinyin(word, {
pattern,
toneType,
type,
nonZh: 'removed'
})
}
然后,真正要进行字符匹配啦。
- 先通过上述封装的方法,得到目标成语和用户成语的字符数组。如果是文字字符匹配,就直接把字符串转为数组。
let todayLetter = convertPinyin(todayIdiom, pattern)
let currentLetter = convertPinyin(idiom, pattern)
// 汉字匹配
if (pattern === 'term') {
todayLetter = [...todayIdiom]
currentLetter = [...idiom]
}
-
通过文字字符的匹配来确定状态标记。
- 状态标记为1,表示字符和位置都匹配。
- 状态标记为2,表示字符匹配。
- 状态标记为3,表示完全不匹配(凑热闹的)。
-
组装好状态标记数组
markers。 -
根据用户成语数组的长度来遍历两个转换后的数组。
- 如果目标字符数组
todayLetter当前索引位置元素为空,跳过本次循环。 - 如果
todayLetter和currentLetter当前索引位置元素相同,状态标记改为1,并且把todayLetter对应元素赋值为''。 - 如果当前元素包含在
todayLetter中,并且标记数组markers对应索引位置的元素不为1,就把状态标记改为2,并且把todayLetter对应元素赋值为''。
- 如果目标字符数组
声调位置的处理
待开发
大致捋了下声调位置的处理,有两个主要功能点。一个是根据韵母中包含的元音和辅音来确定声调应该标注在哪个字母上;二是根据韵母标注的位置来进行展示位置的定位。
但是呢,还是留作后续开发吧,毕竟还有一堆堆bug等着去优化呢,而且以我们中国人的阅读习惯,位置颠倒都不影响阅读,何况一个小小的声调位置,是吧?(找这理由,我自己都给自己打99分)
开发流程
本来想按照一个标准的入门流程来写的,但是想了想没必要,而且大家也未必喜欢看。就挑了这个让我掉了几根头发的关键点介绍了下(虽然可能依然没有人会在意),大家如果有什么想了解的点,可以在评论区说一下。
当然,我是说如果,如果有jym愿意去玩上了两局,不管是bug还是槽点,也欢迎大家评论区说一说。
写在最后
关于汉林
关于汉林,也就是这个小游戏名字的立意,我觉得有必要说两句。
原版wordle,中文版叫做汉兜,那我们这个效仿者应该叫做什么呢?猜词游戏?是天狗呀提议叫做汉林,我有一丝不解,但是一解释就通了。成语出自汉字,而古往今来翰林又多代指文化研究的最高集聚地,汉字+翰林就有了“汉林”的存在。
顺势,我们在游戏对局中,又引入了“汉林学士”的称号。是的,你没看错,不是翰林学士。而目前游戏开放初期,我们也放低了称号准入标准,只要在一次对局中连续猜对5个成语,就能获取并分享“汉林学士”证书。
不知道叫啥名队
wordle和汉兜都是优秀的作品,我们的『汉林』可能并不完美,而且还有肉眼可见的bug,我们还会继续优化完善下去。当然如果大家感兴趣,我们优化着优化着,也可以开源出来(只要你不嫌弃里面可能会丑陋的代码)。
本次游戏创意的整个开发过程中,离不开大帅老师对我们游戏立项和开发的指导,感谢!
我们“不知道叫啥名队”的美女队友也很给力,我们一直在探讨第一版游戏创意,而且她在游戏的体验试玩、难度调整等问题的回馈中,还实现了记分板和证书分享等功能点。
因此,真心希望大家能去玩一局,起码生成分享证书看一眼嘛。