加入CODE CHINA

· ä¸é™é€Ÿ    · ä¸é™ç©ºé—´    · ä¸é™äººæ•°    · ç§ä»“免费

免费加入
    README.md

    单词天天斗

    基于“微信小程序” + “云开发”实现的单词对战小程序,支持好友对战、随机匹配、人机对战三种对战的形式,含四级核心词、四级大纲词、六级核心词、六级大纲词、考研真题核心词、考研大纲词、小学必备词、中考大纲词、高考大纲词、雅思大纲词、商务词汇等多种单词书。

    系统演示视频:https://www.bilibili.com/video/BV1hg4y1i714

    微信:34805850,期待大佬关注微信公众号:前端面试之道,部署文档/视频教程,Star后微信联系 ~

    该项目适用于:

    • 毕业设计:文档齐全、难度合适、技术广度大、业务闭环,含项目解析教程;使用微信小程序云开发,无需搭建服务器/环境等,无后序成本;注意项目上手需要的基础包含:HTML、CSS、JavaScript,另外需要看一下微信小程序开发者文档
    • 运营恰饭: 小程序日UV1000,即可日收入100 (微信广告收入);项目业务闭环,可以自己开发更多功能;裂变模式丰富,好友对战、提示卡、挑战模式群分享等。云开发有一定免费额度,恰小饭无其他服务器成本 ~ 不错的副业项目
    • 学习小程序:代码封装性强,使用了微信小程序常用API,小程序云开发上手;文档齐全

    代码仓库

    ↓ 图片加载不出来,可以Star后clone项目,查看README.md ~

    在线体验

    二维码

    UI截图

    s_1 s_2 s_3 s_4 s_5 s_6 s_7 s_8 s_9

    需求概述

    需求图解

    单词对战模式

    对战业务需求解析

    单词对战的游戏核心为:随机生成一定数量的单词列表的单选题类型题目,题目文本为该单词,有 4 个随机中文释义的选项,其中仅有一个为正确释义,双方用户一起选择释义,正确率高且速度快的用户获得对战胜利。

    单词对战游戏分为好友对战、随机匹配、人机对战三种对战的形式,均通过上述游戏核心的方式进行对战。

    对战设置

    用户还可以对以下对战信息进行自定义设置

    • 对战的单词书,用户可以选择自己想要背诵的单词类型,包含四级核心词、四级大纲词、六级核心词、六级大纲词、考研真题核心词、考研大纲词、小学必备词、中考大纲词、高考大纲词、雅思大纲词、商务词汇等多种单词书,亦可以选择随机单词书模式,则将从所有的单词中进行随机抽取;
    • 设置每一局对战的单词数目为以下任意一种:8、 10(默认)、 12、 15、 20
    • 设置切换下一题是否自动播放单词发音
    • 设置错词是否加入到生词本
    • 开始和错词的时候是否震动
    • 设置默认是否播放背景音乐,游戏中也可以随时关闭/开启背景音乐

    其他细节优化

    • 加入正在对战过程中、对战已结束、房间已满等非正常类型房间,做出相应的交互提示,然后跳转至首页
    • 在对战过程中任意用户退出游戏或掉线,则结束本局游戏,进行对战结算
    • 对战结束后,房主可以选择再来一局,当房主创建好再来一局的房间后,另外一个用户可以选择再来一局,加入继续对战
    • 在对战过程中,选择错误的单词或使用提示卡选择的单词,自动加入到用户生词本,用户可以在生词本中进行复习
    • 加入倒计时机制,每一个单词的对战周期为 10s,超时则判断为错选

    完整对战流程图

    完整对战流程图

    词汇挑战模式

    词汇挑战模式业务解析

    词汇挑战的核心为:获取随机的一个单词作为单选题题目文本,包含四个中文释义选项,其中一个为正确答案,选择错误则失败,选择正确再获取随机单词,循环下去。

    挑战复活机制

    在词汇挑战的过程中,如果选择错误,可以有两次复活机会

    • 首次复活:通过分享小程序获得复活机会
    • 第二次复活:通过观看一个 15s 之内的广告获得复活机会
    • 当第三次选择错误,显示再来一局,从零开始记录分数

    其他

    • 词汇挑战每正确一个词,得分增加 100 分
    • 当挑战失败的时候,如果挑战分数高于历史最高分数,则修改历史最高分数为当前分数,用于排行榜排行
    • 可以使用提示卡进行选择

    完整挑战流程图

    完整挑战流程图

    其他功能

    生词本

    • 用户可以在生词本中查看在单词对战模式、词汇挑战模式中选择错误的单词
    • 可以查看单词及单词释义、播放单词发音、删词生词
    • 在设置中可以一键清空所有生词

    学习打卡

    • 当在单词对战模式中,当天对战局数超过 5 局且胜利局数超过 2 局,则打卡成功
    • 可以在在打卡页面查看当日进度,可以查看历史的打卡日历

    排行榜

    • 排行榜包含词力值、词汇挑战分数、签到天数等排名信息
    • 每类排行版显示前 20 名的排名头像和昵称以及分数
    • 显示自己当前类目下的排名以及分数

    用户相关

    • 数据库应记录的用户数据包含:昵称、头像、对战局数、胜利局数、选择的单词本、词力值
    • 词力值机制:在单词对战模式、单词挑战模式中,每局对战都可以获得相应的词力值分数,作为用户的经验值

    其他

    • 建议反馈:用户可以在小程序中,反馈意见,然后再后台可以查看用户留言
    • 打赏作者:用户可以在小程序中,通过扫码的形式,对小程序进行打赏
    • 小程序友情链接:可通过当前小程序跳转至作者的其他小程序中
    • 小程序中加入部分广告,不影响用户体验

    团队组成

    整个项目的产品方案、UI 设计、开发、测试、上线运营等皆一个人独立完成。

    技术方案

    设计

    设置使用sketch完成,设计稿上传至蓝湖,作为数据标注。

    蓝湖链接

    链接:https://lanhuapp.com/url/qe2Dl 密码: ydIX

    设计图源文件

    首页和单词书封面设计图

    对战页面设计图

    对战结束、生词本、排行榜设计图

    设置、词汇挑战设计图

    下载链接: https://pan.baidu.com/s/1KsZjvlTUbtyYFDcVCy91lg 密码:vylm

    开发技术栈

    • 前端:原生微信小程序
    • 服务端:微信小程序云开发

    其他工具

    • ESLint
    • Git + Github
    • vscode
    • Electron
    • NodeJS
    • Python

    系统架构

    项目文件简介

    ├── cloudfunctions # 云开发_云函数目录
    |  ├── model_auto_sign_trigger # 自动签到定时触发器
    |  ├── model_book_changeBook # 改变单词书
    |  ├── model_userWords_clear # 清除用户生词
    |  ├── model_userWords_get # 获取用户生词
    |  └── model_user_getInfo # 获取用户信息
    ├── db # 数据整理的脚本
    ├── design # 设计稿文件、素材文件
    |  └── words-pk-re.sketch # 设计稿
    ├── docs # 项目文档
    ├── miniprogram # 小程序前端目录
    |  ├── app.js # 小程序全局入口
    |  ├── app.json # 全局配置
    |  ├── app.wxss  # 全局样式
    |  ├── audios # 选词正确错误的发音
    |  |  ├── correct.mp3
    |  |  └── wrong.mp3
    |  ├── components # 全局组件
    |  |  ├── header # header组件
    |  |  ├── loading # 全局loading
    |  |  └── message # 全局弹窗
    |  ├── images
    |  |  ├── ... 图片素材
    |  ├── miniprogram_npm # 小程序npm目录
    |  |  └── wxapp-animate # 动画库
    |  ├── model # 所有的数据库操作
    |  |  ├── base.js # 基类,所有集合继承该基类
    |  |  ├── book.js # 单词书集合
    |  |  ├── index.js # 导出所有数据库操作
    |  |  ├── room.js # 房间集合
    |  |  ├── sign.js # 签到集合
    |  |  ├── user.js # 用户集合
    |  |  ├── userWord.js # 生词表集合
    |  |  └── word.js # 单词集合
    |  ├── pages # 页面
    |  |  ├── combat # 对战页
    |  |  ├── home # 首页
    |  |  ├── ranking # 排行榜
    |  |  ├── setting # 设置页
    |  |  ├── sign # 签到页
    |  |  ├── userWords # 生词表页
    |  |  └── wordChallenge # 单词挑战
    |  └── utils
    |     ├── Tool.js # 全局工具类,放了加载、全局store等
    |     ├── ad.js # 广告
    |     ├── log.js # 日志上报
    |     ├── router.js # 全局路由
    |     ├── setting.js # 全局设置
    |     └── util.js # 全局工具函数
    ├── package.json
    └── project.config.json # IDE设置、开发设置

    云开发数据交互的 Model 层设计

    在该项目中,将所有的服务端交互、数据库的读取、云函数的调用都放到了 model 目录下,对该目录结构深入解析。

    (1) Base.js

    base 基类,所有其他数据集合都继承该类,在构造函数中,用来做数据集合初始化和生命一些可能所需用到的变量。

    import $ from './../utils/Tool'
    
    const DB_PREFIX = 'pk_'
    
    export default class {
      constructor(collectionName) {
        const env = $.store.get('env')
        const db = wx.cloud.database({ env })
        this.model = db.collection(`${DB_PREFIX}${collectionName}`)
        this._ = db.command
        this.db = db
        this.env = env
      }
    
      get date() {
        return wx.cloud.database({ env: this.env }).serverDate()
      }
    
      /**
       * 取服务器偏移量后的时间
       * @param {Number} offset 时间偏移,单位为ms 可+可-
       */
      serverDate(offset = 0) {
        return wx.cloud.database({ env: this.env }).serverDate({ offset })
      }
    }
    
    (2)其他集合文件 (model 目录下,除了 base 和 index 之外的文件)

    在这些文件中,对应和文件名同名的集合的所有数据操作,比如 book.js 中,包含了所有对 pk_book 集合的所有数据增删改查操作。

    import Base from './base'
    import $ from './../utils/Tool'
    const collectionName = 'book'
    
    /**
     * 权限: 所有用户可读
     */
    class BookModel extends Base {
      constructor() {
        super(collectionName)
      }
    
      async getInfo() {
        const { data } = await this.model.get()
        return data
      }
    
      async changeBook(bookId, oldBookId, bookName, bookDesc) {
        if (bookId !== oldBookId) {
          const { result: bookList } = await $.callCloud('model_book_changeBook', { bookId, oldBookId, bookName, bookDesc })
          return bookList
        }
      }
    }
    
    export default new BookModel()
    
    (3)index.js

    在该文件中,对所有的数据集合操作文件进行引入,然后又导出,之后在其他文件中的的调用,就只需要引入该文件即可,就可以实现调用不同的集合操作。

    import userModel from './user'
    import bookModel from './book'
    import wordModel from './word'
    import roomModel from './room'
    import userWordModel from './userWord'
    import signModel from './sign'
    
    export {
      userModel,
      bookModel,
      wordModel,
      roomModel,
      userWordModel,
      signModel
    }

    环境区分

    在小程序初始化的时候,对云开发环境进行了全局的初始化,区别开发环境和正式环境。

    // app.js
      initEnv() {
        const envVersion = __wxConfig.envVersion
        const env = envVersion === 'develop' ? 'dev-lkupx' : 'prod-words-pk' // 'prod-words-pk' // ['develop', 'trial', 'release']
        wx.cloud.init({
          env,
          traceUser: true
        })
        this.store.env = env
      },
      onLaunch() {
        this.initEnv()
        this.initUiGlobal()
      },

    难点解析

    难点 1:单词数据

    1. 抓包分析和代码实现

    本课题中使用 MacOS 系统、Charles 抓包软件、安卓手机作为抓包的基本环境。首先在电脑上安装 Charles,然后开启 Proxy 抓包代理,同局域网下配置手机 WiFi 代理实现抓取手机包。

    2. 单词数据整理

    通过爬虫下来的单词数据如下,对于该课题的项目单词数据相对复杂,所以我们对单词数据结构进行简化,只提取项目中需要的字段,以单词 yum 为例:

    优化前:

    {"wordRank":63,"headWord":"yum","content":{"word":{"wordHead":"yum","wordId":"PEPXiaoXue4_2_63","content":{"usphone":"jʌm","ukphone":"jʌm","ukspeech":"yum&type=1","usspeech":"yum&type=2","trans":[{"tranCn":"味道好","descCn":"中释"}]}}},"bookId":"PEPXiaoXue4_2"}

    优化后:

    {"rank":286,"word":"yum","bookId":"primary","_id":"primary_286","usphone":"jʌm","trans":[{"tranCn":"味道好"}]}

    通过 NodeJS 编写批量格式整理的程序,整理后导出 JSON 文件

    整理数据的代码

    3. 数据文件批量导入(传入数据库)

    由于微信小程序云开发控制台不支持数据文件的批量导入数据库,所以开发了一个支持云开发数据集合批量导入的程序

    批量导入首页

    批量导入过程

    导入测试

    难点 2:单词对战模式

    本节详细解析单词对战模式的实现,将从创建房间(生成随机词汇、新增房间数据)、对战监听、对战过程(好友对战、随机匹配、人机对战)、对战结算的角度进行分析。

    创建对战房间

    对战房间的创建,分为触发创建房间事件、获取当前选择的单词书、获取单词对战每一局的词汇数量、从数据库 pk_word 集合读取随机单词、格式化获取的随机单词列表、创建房间(使用生成的单词列表、是否好友对战条件)、根据房间的 roomId(主键)跳转至对战页等多个步骤流程组成。

    创建流程图

    房间数据监听

    单词对战模式中,对 room 数据集合的监听是对战的核心要点,进入对战页面后,调用数据集合的 WatchAPI 对 room 集合中的当前房间记录进行监听,在当前房间记录数据发生变化的时候,将会调用 watch 函数的回调,执行相应的业务,详细流程如下:

    房间数据监听

    好友对战的实现

    有了前面创建好的对战房间,也建立好了对当前房间的数据监听,接下来就可以实现有趣的对战交互了。游戏会监听好友用户准备,更新 room 集合中的 right.openid 字段,触发 watch,通知房主可以开始对战;房主点击开始对战,会更新 room 集合中的 state 字段为 PK,watch 回调通知双方开始对战,显示第一道题目,双方用户选择释义的时候,会把选择结果和得分更新至 left/right 中的 grades 和 gradeSum 字段,在 watch 的回调中对双方的选择结果进行显示;当对战到达最后一道题目,且双方都选择完毕,进入结算流程,将房间 state 更新至 finish;如果在对战过程中,有任意用户离开对战,将修改房间 state 为 leave;对战结束之后,房主可以选择再来一局,进行创建房间,更新上一个房间的 nextRoomId 字段,在 watch 回调中通知非房主用户可以加入新的房间,进行再来一局的对战。

    好友对战

    随机匹配的实现

    随机匹配对战相对于好友对战的区别在于:好友对战是通过房主将房间链接(roomId)分享到微信好友/微信群,当用户点击分享卡片之后,会跳转至对战页面且房间 Id 为当前分享的房间 roomId,用户进入房间之后就进行上述的监听操作和准备、开始对战等。然而随机匹配的实现原理为,当用户触发随机匹配操作之后,会先在数据库检索有没有符合自己所选择的单词书、目前房主在等待的房间,如果有则加入该房间,如果没有则创建新的随机匹配房间,等待其他用户进入。用户进入之后会自动触发准备操作,房主在 watch 中监听到有用户准备,然后自动触发开始对战操作,后续对战、结算、再来一局流程则和好友对战流程一致。

    随机匹配

    人机对战的实现

    人机对战的核心思想为:房主用户端随机取一名人机用户,房主端触发人机的自动准备,房主端也自动开始对战,在对战过程中,房主端通过页面 UI 用户手动选词,人机将在 2~5s 或房主选词之后随机完成选词操作,正确率为 75%。 后期可以对正确率进行优化,根据用户的历史正确率进行自动化推算,实现更智能的人机用户,提供更好的用户体验。

    人机对战

    微信小程序云开发实现的单词PK小程序,支持好友对战、随机匹配、人机模式,完整代码 ~ UI可以披靡市场上所有同类型小程序,体验也是一流的哦 ~ 目前已经有同学在QQ小程序、阿里小程序部署;也有同学修改成了公务员题库 ~ 期待看到各类优秀产品上线哦 ~

    上线说明: 源码开源,但上线需要经过作者许可哦 ~ 开发不易、创作不易。需要支付RMB 200+方可上线,保障作者著作权益 ~ 如果你觉得项目对你有所帮助 ~ 期待得到你的打赏哦,每一分收入,都能让我在开源路上不放弃!慢慢开源这些年独立开发的项目!

    收费服务

    微信:34805850,期待大佬关注微信公众号:前端面试之道

    标题 价格/元 场景
    套餐一:部署文档+单词数据+项目文档+自定义词库教程 99 会使用git、npm、了解小程序云开发、有一定的问题分析能力,可根据部署文档,直接搭建运行
    套餐二:“套餐一” + 部署视频教程 199 从代码下载到项目运行,完整的视频演示
    上线授权(个人/小团队) 299 代码部署后,如果需要上线至微信(单个小程序授权),能对外使用,需要上线授权;相信后面通过运用,也能很快回本
    机构部署 999 如果您是英语培训班,需要自己的单词学习小程序,可以联系部署,可自定义单词数据
    项目串讲 99 代码部署后,视频讲解每个代码模块作用,串讲快速上手开发

    请作者喝咖啡

    微信扫码赞赏

    授权小程序名单

    • 上线后可『自行』PR合入自己的小程序信息,不完整榜单
    小程序名称 上线时间 联系(可选)
    比心单词 ㊙️ ㊙️
    雪团词汇大PK ㊙️ ㊙️
    单词pk ㊙️ ㊙️
    背单词|百词 ㊙️ ㊙️
    单词天天斗 ㊙️ ㊙️
    英语单词王 ㊙️ ㊙️
    爱上记单词 ㊙️ ㊙️

    项目简介

    🚀 Github 镜像仓库 🚀

    源项目地址 ⬇ ⬇ ⬇

    https://github.com/arleyGuoLei/wx-words-pk

    发行版本

    当前项目没有发行版本

    贡献者 2

    A arleyGuoLei @arleyGuoLei
    L lijunchao16 @lijunchao16

    开发语言

    • JavaScript 100.0 %