聚会开场五分钟,空气安静得能听见冰块化的声音。有人掏出手机搜"真心话大冒险",排在前面的不是广告就是题目就那么几十条的模板应用。你心想:要不自己做一个?打开 AI,敲了两句提示词,一个首页确实出来了——然后真机上导航栏挡住了标题,转盘旋转卡成幻灯片,分享按钮点了没反应。
做完你的,做你的——说的就是 AI 编程和真机调试之间那种反复横跳的日常。
这篇不是教你"三步做小程序"的速成帖。我把一个真实项目的六种聚会玩法(抽卡、掷骰子、转盘、转酒瓶、快闪抽题、指尖轮盘)从架构到动效到题库的全链路摊开来讲,踩过的坑和最终跑通的方案都在。你读完至少能带走两样东西:一套 AI 协作小程序的拆任务方法,和一份"哪些事必须查官方文档而不是问模型"的判断清单。
这一篇主要是记录关于这个小程序的制作流程,如果想从0开始的,可以看看这篇:保姆级教程:手把手教你3小时做出第一个微信小程序(配图+源码)
小程序的名字叫“不一样的真心话大冒险”(至于具体哪里不一样,有兴趣的可以来瞅瞅。)
这张图是小程序首页真机截图,能看到粉紫渐变背景、毛玻璃卡片、六个玩法入口(抽卡模式、掷骰子、欢乐转盘、快闪抽题、转酒瓶、指尖轮盘)和底部的"甜蜜建议"一键切换主题。整个布局是 CSS 变量驱动的,下面会拆。
一、六种玩法塞进一个小程序,架构先别散架
很多人用 AI 做小程序的第一个错误是:每个功能都开一个新对话,最后代码风格四分五裂,工具函数重复写了三遍,存储 key 撞了还查不出来。
这个项目的做法是先把骨架钉死,再往里填肉。app.json 里的页面注册顺序就是产品链:
{
"pages": [
"pages/index/index",
"pages/settings/settings",
"pages/mode-card/mode-card",
"pages/mode-dice/mode-dice",
"pages/finger/index",
"pages/draw/draw",
"pages/question/question",
"pages/bank/bank"
]
}
八个页面,覆盖首页入口、设置、抽卡、骰子、指尖、转盘/转酒瓶(共用一个页面通过 ?mode=bottle 区分)、快闪抽题和题库管理。微信官方文档里写得很清楚:pages 字段是必填的字符串数组,第一项就是默认启动页,页面路径不注册就不存在。
关键的工具层拆分:
-
utils/storage.js:所有持久化 key 集中管理,玩家会话、题库、题目栏、主题偏好、骰子旋转次数全在这一个文件声明,避免各页面自己发明 key 然后互相覆盖。 -
utils/safe-layout.js:处理状态栏、胶囊按钮位置、安全区高度等度量。这个文件的存在就是因为一个血泪教训:不同机型的状态栏高度、胶囊位置千差万别,写死数字在鸿蒙适配和异形屏上会反复翻车。 -
data/theme-config.js:两套主题(简约 / 暧昧)的全部色值集中在这,通过buildThemeCssVars()注入页面根节点的 CSS 变量,一次切换,全站生效。
给 AI 的第一条指令不应该是"帮我写个转盘页面",而是"帮我梳理这个项目的目录结构和公共依赖关系"。架构搞明白了,后面加页面才是填空题而不是作文题。
二、毛玻璃主题 + 双套皮肤,AI 搓 UI 的上限和你想的不一样
很多人对 AI 做 UI 的预期是"给个截图让它抄"。实际上小程序的 UI 限制比 Web 多得多——没有 backdrop-filter 的完美兼容,没有 CSS Grid 在所有基础库版本上的一致表现,Canvas 是原生层会压在其他元素上面。
这个项目的首页用了一个很有意思的方案:多层渐变背景 + 半透明卡片 + backdrop-filter 毛玻璃。色值全部走 CSS 变量:
.glass-card {
background: var(--panel);
border: 1rpx solid var(--border);
backdrop-filter: blur(24rpx);
-webkit-backdrop-filter: blur(24rpx);
box-shadow: var(--shadow-glass);
}
而 --panel 在简约主题下是 rgba(255,255,255,0.46),在暧昧主题下是 rgba(255,244,252,0.48)——切换主题不是换一张背景图,而是整套色系联动,从渐变锚点到阴影到文字色全部跟着变。
这张图是抽卡模式的真机截图。顶部"当前题型:真心话",中间展示题目"你最想向过去的自己道歉的一件事是什么?",底部有"发给朋友""朋友圈"分享入口,以及"真心话/混合/大冒险"切换。整个卡片的粉紫渐变和毛玻璃透出底层背景,这就是 CSS 变量主题系统在子页面的实际效果。
这里有个坑值得说:抽卡的主卡(hero-card)因为有 overflow:hidden 裁剪旋转元素,backdrop-filter 会失效。最终方案是主卡放弃毛玻璃,靠半透明底色 + 内部装饰层撑视觉。这种取舍 AI 不会主动告诉你,需要你在真机上看到"磨砂怎么没了"之后,回头查文档和社区讨论才能定位。
三、转盘、骰子、转酒瓶——三种动效踩坑实录
动效是聚会小程序的灵魂,也是 AI 编程最容易翻车的地方。
欢乐转盘经历了三个方案迭代:
第一版用 Canvas 2D 画扇区——进页面白屏。原因:navigateTo 过渡动画还没结束就挂载 Canvas,getContext 拿到的宽高是 0。加了延迟重试(最多 8 次 requestAnimationFrame),还要在宽高正常后才执行 paintWheel,进场 420ms 之后才能稳定出图。
第二版发现更大的问题:Canvas 是原生层,会压在页面其他元素上面。退出转盘页回到首页,Canvas 还飘在那里挡住首页的菜单。最终方案:wx:if 控制 Canvas 挂载,onHide/onUnload 时卸载,onShow 时重建。
第三版干脆换成了 DOM conic-gradient 方案——用 CSS 画扇区色块,极坐标定位文字标签,旋转动画走 transform: rotate()。告别了 Canvas 的原生层问题,与页面同层渲染,再也不会压住弹窗。
这张图是欢乐转盘的真机截图。顶部"命运之箭指向谁?",转盘用红蓝双色扇区(支持 2-12 人),中心有固定指针。底部可调玩家数量、自定义玩家名、重置转盘、邀请好友和发朋友圈。这个转盘是纯 DOM 实现的,扇区用 conic-gradient 生成,旋转用 CSS transition 驱动。
掷骰子的坑不在动效本身,而在凹点绘制。第一版用 CSS Grid 画 3×3 的凹点矩阵——部分机型不支持,凹点全部消失。改成 flex 嵌套(行→列双层 wx:for)之后稳了。动画是"左侧扇形握牌 → 同时甩出到随机落点",每颗骰子有独立的 transition-delay 做错落效果,飞行中 setInterval 高速切换凹点模拟翻滚。
转酒瓶和转盘共用 pages/draw/draw 页面,通过 ?mode=bottle 区分。酒瓶用 image 组件加 rotate(90deg) 平放,旋转走 CSS transform,停下来后根据角度判定"谁接受惩罚"。深蓝渐变背景 + 涟漪圈动效 + 旋转次数统计,退出页面时次数清零(不再持久化,避免换场景数据串)。
四、题库管理与快闪抽题:内容层才是聚会体验的命根子
界面做得再漂亮,题目就那几十条,玩两轮就重复了——用户直接卸载。
这个项目的题库系统分三层:内置题(出厂自带)+ 题目栏(可多栏管理)+ 自定义题(用户自己加)。抽题引擎(utils/question-engine.js)支持按场景(经典/校园/情侣/网聊)和氛围(走心/搞怪/大胆)过滤,加权随机抽取,保证不连续重复。
这张图是题库管理页的真机截图。顶部四宫格展示题目类型(经典模式、校园聚会、情侣模式、网聊模式),当前选中"经典模式"高亮显示。中间是操作工具条(编辑类型、添加题),下方是题目列表,真心话和大冒险用"真""险"标签区分。双击题目行可打开编辑弹窗,支持修改文案、启停和删除。
快闪抽题是最有聚会感的模式:进入后先选真心话或大冒险,然后题目以 48ms 的间隔高速闪动(马卡龙色系随机切换背景和文字色),点击"停"定格当前题目。这个节奏是调了好几轮的——100ms 太慢像幻灯片,30ms 太快眼睛跟不上内容,48ms 是那个"看得到在变但来不及读清"的甜点。
指尖轮盘用的是多点触控检测:每人把手指按在屏幕上,随机选中一个手指高亮(波纹动画),被选中的人接受挑战。"点击开始"按钮做了个细节:文字整体 rotate(90deg) 竖排,因为 writing-mode 在部分机型上排版异常,直接旋转 transform 更稳。
今天就能做的一步:如果你也想用 AI 做一个聚会类小程序,先别急着写页面。打开 微信小程序开发指南,把你想做的功能对应到"框架—组件—API"三条线上各找一个锚点页面;再新建一个 utils/storage.js 把所有存储 key 集中声明。给 Cursor 的第一条指令写成:"读完这三个文档链接,帮我梳理项目目录结构和公共依赖关系,不要直接写页面代码。" 这一步大概花十五分钟,但能让后面每个功能页的开发少踩一半的坑。
对了,如果你也想做一个自己的小程序,但是不知道怎么制作,或者可以试试这个,也许会对你有启发。