一、 为什么又是扫雷?
扫雷是每个程序员的“Hello World”进阶版,但市面上大多数扫雷都高度依赖鼠标。作为一个长期沉浸在终端、习惯 hjkl 的开发者,我一直在想:能不能有一款扫雷,能让我的手指不离开键盘,甚至能玩出 Vim 的“丝滑感”?
于是,zsweep 诞生了。它不仅是一个游戏,更是一个实验场,用来验证如何将 Vim 的操作逻辑(Grammar)完美平移到 Web 交互中。
二、 技术选型:为什么是 Svelte 5?
在开发 zsweep 时,我果断选择了最新的 Svelte 5。
- Runes 的魔力:使用
$state和$derived彻底简化了复杂的棋盘状态管理。在扫雷这种需要频繁触发邻近格子更新的场景下,Svelte 5 的细粒度更新让性能表现极佳。 - 零负载感:极简的 API 让代码量大幅减少,非常契合项目“极简主义”的初衷。
三、 核心挑战:在浏览器里复现 Vim 体验
为了让 zsweep 拥有真正的“Vim 魂”,我实现了以下特性:
- 基础移动:
hjkl映射。 - 高效跳转:实现
w/b跳转(自动跳过已打开的安全区,直达未标记区域)。
// src/lib/game/input/vim.ts
export function handleVimKey(key: string, buffer: string) {
// 处理数字前缀(用于 5j, 10l 等组合键)
if (/^[1-9]$/.test(key)) {
return { type: 'DIGIT', value: key };
}
// 核心动作映射
switch (key) {
case 'h': return { type: 'MOVE_CURSOR', dx: -1, dy: 0 };
case 'j': return { type: 'MOVE_CURSOR', dx: 0, dy: 1 };
case 'k': return { type: 'MOVE_CURSOR', dx: 0, dy: -1 };
case 'l': return { type: 'MOVE_CURSOR', dx: 1, dy: 0 };
// 单词级跳转:跳过已打开区域,直达下一个未开块
case 'w': return { type: 'WORD_FORWARD' };
case 'b': return { type: 'WORD_BACKWARD' };
// 搜索模式:按 / 进入,跳转至匹配数字的格子
case '/': return { type: 'START_SEARCH' };
// 游戏核心操作:空格标记/双击效果,回车揭开
case ' ': return { type: 'SMART_ACTION' }; // 自动判断是 Flag 还是 Chord
case 'Enter': return { type: 'REVEAL' };
default: return null;
}
}
在 Svelte 5 组件中,通过 $state 驱动的游标配合上述逻辑,可以实现极其平滑的响应:
<script lang="ts">
let cursor = $state({ r: 0, c: 0 });
let vimBuffer = $state("");
function onKeyDown(e: KeyboardEvent) {
const action = handleVimKey(e.key, vimBuffer);
if (!action) return;
if (action.type === 'MOVE_CURSOR') {
const mult = parseInt(vimBuffer) || 1;
// 计算新位置并更新 cursor
updateCursor(action.dx * mult, action.dy * mult);
vimBuffer = ""; // 执行完动作清空缓冲
}
}
</script>
- 数字检索:支持按
/后接数字,快速定位到棋盘上的特定提示数。 - 组合技:支持数字前缀(如
5j向下移动五格)。
为了保证操作的即时性,我构建了一套基于状态机的输入处理引擎,确保每一帧输入都能获得 0 延迟反馈。
四、 细节打磨:从 1k+ 活跃用户中学到的
项目上线后,迅速吸引了超过 1000 名活跃用户。在与社区(如 Hacker News, Reddit)的交流中,我不断优化细节:
- 数据精度陷阱:早期使用 Supabase 统计全局时间时,遇到了经典的 1000 行分页限制问题,导致统计“漂移”。后来通过 RPC 服务端聚合彻底解决了这一统计 Bug。
- UI 的“呼吸感” :参考了 Monkeytype 的审美,加入了极简的主题切换系统,让“摸鱼”也能摸出高级感。
- 键盘辅助:在底部加入了实时的按键提示,帮助非 Vim 重度用户也能快速上手。
五、 开源与未来
目前 zsweep 已在 GitHub 完全开源。
- GitHub 地址:github.com/oug-t/zswee…
- 体验地址:zsweep.com
目前项目正在推进 Chording(双键消除) 和 移动端手势支持 的特性,欢迎各位掘友来提 PR 或 Issue,一起探讨 Svelte 5 的更多可能性!