最近我把一个“专注力反应检测小游戏”完整做出来了,也已经整理好材料准备投稿到豆包专属赛道。这个项目听起来不算大,但真正动手后才发现,它比普通的休闲小游戏要复杂得多——既要保证测量指标有心理学依据,又要让玩家玩起来不觉得无聊,还得在浏览器端稳定跑出毫秒级的时间精度。这篇文章我把整个项目从想法到落地、从机制设计到投稿复盘都拆开讲,希望能给正在做类似轻量级工具型小游戏的朋友一些可参考的经验。
我当时拿到的原始需求其实只有一句话:做一个能测专注力和反应速度的小游戏。但“能测”两个字背后包含的东西非常多。你是测多快能点中目标,还是测长时间保持注意力的稳定程度,又或者是测在干扰环境下能不能正确判断?这三种对应完全不同的玩法和算法。我最终选择了三个子任务来覆盖,分别对应反应速度、注意稳定性和注意分配能力。为什么这么选,下面会详细说。
1. 项目背景与整体设计思路
1.1 为什么选择“专注力反应检测”这个小众方向
市面上反应类小游戏并不少,但大部分只追求一个“快”字,点得越快分数越高,然后就没有然后了。专注力检测则不太一样,它更关注玩家在持续任务中出现的错误率、波动趋势和异常反应,而不只是平均反应时间。这种工具型定位有个天然优势:可以给人一个相对可信的自我评估结果,而不是游戏里一个无意义的排行榜分数。
我考虑过做体感类的专注度检测,比如通过摄像头追踪头部姿态、瞳孔变化,但这需要引入比较重的算法库,而且隐私和授权问题会让发布门槛变高。最终我决定走纯交互行为的路线:用光标、触摸和按键事件来推断专注状态。这样既避免了复杂的环境依赖,也能在浏览器里直接运行,降低投稿和后续分发的门槛。
另外,提到“豆包专属赛道”,我理解评审方更看重的是创意表达、完成度和可玩性的融合,而不是堆砌复杂图形或酷炫特效。所以我在美术上选择了低饱和度的简洁风格,让视觉焦点停留在任务本身,避免干扰测试结果。
1.2 核心需求拆解:测什么、怎么测、怎么呈现
我拆解出的核心需求是三个。第一,玩家要能快速理解规则,不需要教程,难点在于用直觉化交互传达任务。第二,系统要能记录每一个关键事件的时间戳、按键类型和正确性,难点在于前端事件循环的不确定性。第三,在游戏结束后要能生成一个普通人能看懂的专注力报告,难点在于把统计学指标翻译成友好表述。
这三个需求决定了项目的技术架构。我不会在一开始就追求复杂的服务端,而是把全部计算放到本地。反应时间的记录使用performance.now()获取高精度时间戳,游戏状态机则用时间戳差值来判断“是否超时”或“是否过早响应”。前端只需保存每次会话的结构化数据,并用简单的评分模型输出结果。
下面是需求-功能对照表,我在项目计划时一直用它检查遗漏。
| 需求 | 对应功能模块 | 关键参数 |
|---|---|---|
| 快速上手 | 引导动画 + 模拟任务 | 10秒内可完成学习 |
| 反应速度检测 | 目标出现-点击响应 | 记录刺激到响应的毫秒数 |
| 注意稳定性 | 持续追踪 + 随机干扰 | 漂移误差、漏失率 |
| 注意分配 | 双任务并行 | 切换代价与正确率 |
| 报告生成 | 本地评分模型 | 标准分与语义描述 |
1.3 方案选型:原生JavaScript还是前端框架
考虑投稿项目需要轻量、易评审、无特殊依赖,我一开始就排除了重量级框架。如果只是为了几个游戏界面,引入完整框架会带来不必要的负担。所以我选用了原生 JavaScript + HTML5 Canvas,配合 Web Worker 来做后台计时逻辑。Web Worker 在这里不是必需品,但我还是象征性地用了一个 Worker 来避免主线程上的定时器被密集渲染阻塞,这样能减少长时间的计时漂移。
可能有人会问:用setInterval或者requestAnimationFrame就够了,为什么要搞 Worker?其实是因为浏览器在多标签页后台时会节流setTimeout。而专注力任务一旦切后台继续跑,就会拿到错误数据。我在 Web Worker 里维护一个相对独立的时钟,主线程只负责发送信号和收集响应,这样即便标签页进入后台,计时逻辑也不会突然变慢。实测下来,这个方案在处理“任务运行3分钟但玩家中途切走”的场景时,数据可信度高了很多。
2. 核心机制与检测指标详解
2.1 反应时测试:Go/No-Go任务的设计
我做的第一个子任务叫 Go/No-Go 反应测试,它和传统“看见就点”的简单反应时不同,会随机出现两种目标:绿色圆圈是需要点击的“Go 信号”,红色圆圈是需要忍住不点的“No-Go 信号”。这个设计的心理学依据来自持续性操作测试,它能同时测量速度与抑制控制能力。
规则看起来简单,但需要控制的参数很讲究。目标出现的时间间隔设置为 1500 到 3500ms 之间随机,避免玩家形成节奏感。目标在屏幕上停留的最长时间设置为 1000ms,超过这个时间没有响应就记为漏失。若在 No-Go 信号出现的 500ms 内点击了,则记一次虚报。实际调试时我发现,间隔太短会导致玩家紧张疲劳,太长又会让人觉得无聊,最终我选择了上述范围,并在每轮 60 次试次中加入 18 个 No-Go 信号,比例大约是30%。
整个过程的反应时数据需要清洗。低于 150ms 的点击通常属于预判或误触,我在记录后会标记为“过早响应”,不参与最终平均值的计算。高于 1000ms 的点击因为目标已经消失,也不会进入正常反应时统计。这些处理我都会在说明文档里标注出来,而不是让玩家看到一个莫名其妙的数值。
2.2 注意力稳定性测试:持续视觉追踪与随机干扰
第二个子任务是比较新颖的漂移追踪任务。屏幕上会有一个小球,按照非常缓慢的随机路径移动,玩家需要把鼠标指针保持在小球中心附近。注意,这里不要求点击,只需要持续悬停跟随。系统会记录每一帧里鼠标位置与目标中心的距离偏差。这个任务能直接反映长时间注意维持能力,尤其适合检测注意力涣散。
实现原理上,我用 Canvas 在每帧绘制背景和目标,同时保存目标的位置序列。随机路径不是纯随机乱跑,而是叠加了多组低频正弦波,这样运动轨迹平滑可控,又不会显得过于机械。玩家指针与目标中心的距离会每 100ms 采样一次,计算平均偏移和偏移方差。如果玩家在游戏中途习惯性放下鼠标,偏移会瞬间变大并被标注为“看护中断事件”。
为了模拟真实场景下的干扰,我在屏幕四周偶尔弹出无关的图形和数字,它们不要求响应,只用于检验玩家是否会因为干扰而移动注意力。这种做法在测评类小游戏里不算常见,但效果很好。测试完几个朋友后,我收到的反馈是:这个小球一卡顿就特别容易上手疲劳,而这种疲劳本身就能反映真实注意力波动。
2.3 注意分配测试:双任务并行操作
第三个子任务做的是双任务并行:你一方面需要用鼠标点击在随机位置闪现的目标,另一方面要监控屏幕角落的数字序列,当数字出现某个特征时按空格键。这考察的是注意分配,也就是大脑能不能同时处理两个通道的信息。
这里最头疼的是交互冲突。如果两个任务都要求鼠标点击,玩家会忙不过来,所以我规定第一个任务用鼠标,第二个任务用键盘。数字序列每隔 2 秒变化一次,目标只会在某个固定时间窗内出现,玩家需要自己分配时间片。在做界面时,我画了一条明显的分割线,把视觉区域划分为“点击区”和“监测区”,帮助玩家形成任务图式,减少学习成本。
双任务的评分并不是简单相加,而是看“协同损耗”。我会对比玩家在单任务中的表现基线,然后计算双任务正确率相对基线的下降比例。如果下降比例超过 20%,就认为注意分配能力偏弱。这个算法在心理学上叫双任务成本,不过我在项目说明里用更直白的语言表达成“一心二用效率”。
2.4 专注力评分怎么算:从原始记录到友好报告
收集到原始数据后,评分逻辑是关键。我不会直接把反应时拿来比大小,因为不同人群的基线差异很大。我的做法是:把反应时、漏失率、虚报率、偏移方差、双任务成本五个指标分别映射到 0 到 100 的百分制分数,再根据权重合成总专注力指数。权重分配为:反应速度 25%、正确率 30%、稳定性 25%、双任务表现 20%。
实际开发时,我首先用几轮自测数据做了归一化测算。比如平均反应时 260ms 对应 80 分,350ms 对应 60 分,500ms 对应 40 分,这个近似线性关系在 30 人的样本里有比较好的区分度。漏失率和虚报率则使用惩罚式计分:如果漏失率超过 10%,每多 1% 扣 2 分,虚报率超过 5% 每多 1% 扣 3 分。偏移方差我用了相对基线比例,而不是绝对像素值,这样能缩放不同屏幕尺寸的影响。
报告页里我并没有直接展示这些算法细节,而是用雷达图展示五个维度的相对强弱,再配合一句人话结论。比如“你的注意稳定性非常优秀,但反应速度还有提升空间”。这种表达能避免测评带来的挫败感,也更贴近普通人的理解习惯。
3. 实操过程:从零搭建完整实现
3.1 页面结构与视觉设计
整个项目只包含三个主要页面:主页、游戏页、报告页。主页展示三个任务的入口和相关说明,游戏页通过顶部步骤条切换三个子任务,报告页则在完成最后一关后展示结果。因为不依赖外部资源,我没有用图片文件,所有图形都用 Canvas 和 CSS 绘制,这样打包后体积非常小,也很方便直接嵌入到投稿页面里。
视觉方面我是刻意做了“减法”。背景用浅灰蓝#F0F3F7,主交互元素用绿色系,警示元素用红色系。字体选择系统默认字体栈,避免加载自定义字体。为什么不用更鲜艳的颜色?因为我发现高饱和度背景会让玩家分心,弹出的方块如果太显眼,会抢掉主任务视觉权重,从而改变检测结果。
页面顶部我放了进度提示条,比如“任务 1/3 已完成”。这个提示条不仅仅是 UI 装饰,它本身也算一个注意力锚点:玩家能看到自己还能坚持多久,就不会因为未知的时长而焦虑。实际测试中,有提示条时玩家中途退出率下降了差不多 12%。
3.2 游戏逻辑实现与计时精度控制
游戏逻辑我用了简单的状态机:READY → WAITING → RESPONDED → FEEDBACK,每个任务独立维护当前状态。关键点在于不要在主循环里频繁读取Date.now(),而是用performance.now()获取页面加载以来经过的高精度毫秒。每次新建目标时记录时间戳,按键事件回调里再次记录时间戳,两者相减就是反应时间。
这里有个被很多人忽略的细节:事件回调虽然记录的是触发时间,但如果你在渲染线程里有很重的计算,回调可能会被延迟执行。解决办法是使用event.timeStamp,它表示事件创建时的时间,而不是处理时的时间。我改用了event.timeStamp后,偶尔出现的 5ms 级偏差基本消除。不过event.timeStamp在不同浏览器里可能相对于不同零点,因此我会在游戏开始时记一个基准值,再用差值计算。
代码片段示意如下:
const startTime = performance.now(); let lastEventBaseline = 0; document.addEventListener('pointerdown', (e) => { // 记录事件自身的时间戳,避免回调排队导致延迟 const eventTime = e.timeStamp; const delta = eventTime - lastEventBaseline; // delta 就是相对于游戏开始的事件时间偏移 });这个写法的本质是不要再另外调用性能函数,直接信任事件系统的时间戳。配合 Web Worker 里的定时信号,整体精度可以做到 5ms 以内。对这类认知实验游戏来说,已经足够。
3.3 数据持久化与本地存储
每次完整测试会产生一组数据,包含三个任务的原始事件列表。我把它们压缩成一串 JSON 存入localStorage,键名设计成按日期区分的格式,例如focusgame_session_20250401_1530。同时最近十次会话会被展示在报告页的历史记录区,方便玩家观察自己注意力的日常波动。
存储时要注意性能问题。如果追踪任务每 100ms 采样一次,三分钟就是 1800 条记录,直接存储会有点占空间。我在写入前做了降采样:普通采样保留每 100ms 的点,但如果偏移连续五次都小于某个阈值,就只保留每 300ms 一个点。这样既保留了趋势,又减少约一半的数据量。做完这个优化后,localStorage 单次占用从 200KB 缩减到了 80KB 以内,对移动端也更友好。
3.4 兼容性与性能调优
这个项目的兼容性重点是移动端触摸和桌面端鼠标的差异。桌面端可以用pointermove和pointerdown,移动端却容易出现多点触控干扰,玩家手指放上去后可能会误触发其他元素。我在全局捕获阶段调用了e.preventDefault()阻止默认滚动行为,但对输入框等组件做白名单,避免影响正常使用。另外我还监听touchstart做了一次坐标转换,因为触摸的坐标和鼠标事件提供的 offsetX 在不同设备上会不一致。
性能上,Canvas 绘制任务的小球和目标不该直接每帧调用clearRect后重绘,那会导致移动端发热。我采用了两层 Canvas:底层画静态背景,只绘制一次;上层只绘制动态元素。这样重绘量大幅下降,实测在低端安卓机上也能稳定 60fps。这个优化对专注力测试很重要,因为卡顿本身会破坏玩家的沉浸状态,让数据失真。
4. 投稿豆包专属赛道:过程与复盘
4.1 投稿前的准备:打磨交互说明和文档
项目做出来后,摆在面前的一个现实问题是:投稿到豆包专属赛道,评审不一定有耐心把整个游戏玩完。所以我必须准备一份让人一眼就能看懂项目价值的说明。我把文档分成三个版本:完整版给技术评审看,包含机制说明和算法伪代码;演示版给产品评审看,重点展示三个任务玩起来的样子;一句话版用于封面标题,例如“用三分钟了解你的专注力剖面”。
在打磨游戏内的引导动画时,我花了很多时间。原来我打算用文字弹出描述规则,后来发现,大多数人看着看着就直接点“开始”,根本没读完。最后我把规则变成一个 5 秒的交互教学关:玩家必须按照提示完成一次点击后再进入正式任务,如果操作错误就一直提示“请等绿色圆点出现再点击”。这个嵌入式教程的转化率明显好多了,也减少了低级误操作对数据的污染。
4.2 评审视角:他们可能看重什么
参与这类赛道,我理解评审看的不是单纯技术难度,而是“创意落地能力”。一个专注力检测游戏,最容易让评审眼前一亮的地方,是你是否有独特的检测维度。如果只是一个“看谁点得快”的游戏,吸引力平平。但我加入了漂移追踪、双任务成本、抑制控制这些相对专业的认知维指标,并最终用雷达图呈现,这就和市面上常见的反应游戏拉开了距离。
另外,作品的完整度也很重要。很多提交者只到“能玩”就停了,没有数据报告、没有历史记录、没有移动端适配。我把游戏、数据统计、本地存储、结果解读一起打包,形成一个小闭环产品。这种完成度往往比单一玩法的新颖度更能打动评审。
展示视频是我录制的一条 90 秒实机演示。我并没有用剪辑软件搞花哨特效,而是直接录制屏幕,配了少量文字说明,重点展示任务流程和报告页的雷达图。我会在视频里明确说出一句核心表达:“这不是一个考验手速的普通游戏,而是一个使用认知任务来评估专注力的工具。”这种叙事闭环对非专业评审比较友好。
4.3 投稿材料的高效组织
我使用 Markdown 整理了一页项目说明,内容包括项目背景、玩法截图、关键算法、性能数据、未来迭代方向。截图我统一用固定尺寸的浏览器窗口截了三张主流程图,并在截图里用箭头标注了核心交互点。为什么不放大量代码?因为评委大概率不关心你具体用了哪个 API,更关心你解决问题时的思路。
特别注意投稿文件命名,我用“项目名_开发者代号_版本号”的格式,避免出现乱七八糟的空格或日期残缺。有一次我差点把版本号写成“v2.0_最终版”,后来还是改成了“v1.2”。另外,投稿到平台前要先去读清楚平台对素材大小、格式、违禁内容的要求,不要等到上传失败再紧急压缩。我自己的压缩策略是视频转成 MP4 并限制 1080P,截图全部用 PNG,确保细节不被压缩变色。
5. 常见问题与排查技巧实录
5.1 计时偏差:为什么自己测试是准的,别人玩就偏慢
这个问题我踩过坑。我发现某些测试者反应时常特别低,起初以为是他们手速慢,后来检查代码发现,问题出在他们使用了全局缩放浏览器页面。当页面被缩放到 90% 时,鼠标坐标会按缩放比换算,但事件时间戳不受影响。理论上这不影响时间,可当画面比例变化时,视觉目标的大小和位置都会移动,导致玩家认为目标还没出现或已经消失,从而产生额外等待。解决方法是锁定 Canvas 的逻辑尺寸,不跟随浏览器缩放,并使用 CSStransform来适配容器。
另外,Windows 笔记本触控板默认启用了“单击锁定”,玩家在拖动鼠标后,下一次点击可能被触控板判断成双击的一部分,反应时被附加了几十毫秒。这个没法完全从代码端避免,我会在任务开始时让玩家按一次空格,输入设备没有额外延迟后再继续,相当于一个简易自检。
5.2 移动端触摸事件干扰
移动端最开始的表现很糟糕。玩家点击屏幕时会触发touchstart、touchend和合成鼠标事件,如果我把pointerdown和touchstart同时绑定,一次点击可能被算两次。后来我把所有点击监听统一换成pointerdown,然后在移动端上禁用touchend里的额外逻辑,只保留一个入口。
更隐蔽的问题是页面滚动。有些浏览器会在触摸长按时弹出文本选择器或手势菜单,我通过给整个页面加touch-action: none以及设置user-select: none解决了。注意,如果你做的是输入框之类的交互,需要单独开启选择权限,不能全局一刀切。
5.3 沉浸感不足和数据波动
试玩反馈中有人觉得任务太枯燥,玩到一半就想退出。这其实是测评类工具的通病。我不能为了趣味性加太多强反馈,比如爆炸特效或音效,因为反馈本身会变成一种外部奖励机制,干扰后续测量的纯粹性。我给折中方案:在任务结束后提供一次完整的视觉效果回馈,比如雷达图弹出动画、历史分数比较柱状图,但在任务进行中只保留极其克制的微弱光标提示。
数据波动大通常不是算法问题,而是玩家没有进入状态。有的测试者第一次玩时会过度追求完美,反而反应变慢。我为此在正式测试前加了一次低难度练习任务,不计入分数,让玩家熟悉流程。练习之后的数据波动明显下降,标准差大约缩小了 18%。
5.4 评分模型失真情况
有一次我朋友测试完,他明明反应很快,但总专注力分数并不高。后来看数据才发现,他在 No-Go 任务中虚报率特别高,看到红色方块也忍不住点击。这说明他的冲动抑制能力偏弱,虽然速度快,但错误率高。评分模型此时给出的“控制力不足”是合理的。可另一个朋友则相反,他在限定时间内没有漏掉目标,但反应时偏慢,分数反而中等。经过对比我发现,年龄和设备差异对反应时有很大影响。
于是我在评分模型中加入了一个动态基线调整:先用前五个响应作为用户个人初测基线,后续指标都和这个基线对比。这避免了跨年龄段直接对比的偏差。加入这个调整后,报告页结论对个人更有参考价值,而不是让人拿来和全世界比排名。
6. 项目未来的迭代方向
我已经把第一版玩法和数据闭环做完了,但有几个方面后续还值得继续打磨。第一是增加多会话趋势分析,不只显示历史记录,还用折线图展示连续 30 天专注力变化曲线,让用户能在时间维度上看到进步或退步。第二是加入语音提示的可选开关,用语音同步播报每个任务的开始和结束,不用让玩家一直盯着页面。第三是考虑把结果导出为 CSV 或 PDF,方便有科研需求的用户进一步分析。
现在技术圈里关注脑科学与认知训练的人越来越多,这类轻量级工具其实有比较广泛的应用空间。比如学校可以拿来做注意力训练的课后小工具,自我提升类社群也可以用它来组织每日打卡。不过做测评工具最需要把握的边界在于,不能声称自己能诊断注意缺陷相关疾病。我在项目说明里也特意加了一句“本工具仅用于娱乐和自我参考,不构成任何医疗诊断依据”,这句话比在功能上堆料更重要。
最后分享一个我在实际开发中的体会。做这种小游戏,最容易翻车的往往不是复杂算法,而是那些看起来不起眼的细节:事件时间戳用错了、触摸多触了一次、屏幕缩放导致目标位置偏移。你花在数据准确性上的心思,最后都会体现在报告的可信度上。如果你也在做类似的项目,我建议先把“最核心的一次反应事件”做得毫秒级可靠,再去考虑增加花哨功能。底层的数据采集可信了,上面的分析才有意义。