游戏2026年10月29日

墨局 · 麻将

墨局 · 麻将:一人对三家电脑的国潮水墨麻将,杭州 / 成都 / 血战到底三种打法,牌面是 AI 贴图再由代码合成。

墨局 · 麻将
使用的技术PixiJSCanvas 2DWeb Audio自托管子集字体

玩法

一桌四人:你坐庄或闲,另外三家是电脑。三种打法在开场屏直接选:

| | 杭州麻将 | 成都麻将 | 血战到底 | |---|---|---|---| | 牌数 | 136(含东南西北中发白) | 108(仅万条筒) | 108 | | 财神 | 白板为财神,可当任意牌 | 无 | 无 | | 定缺 | 不需要 | 必须定缺 | 必须定缺 | | 胡牌限制 | 无番不可胡 | 有番型即可 | 有番型即可 | | 胡牌之后 | 本局结束 | 本局结束 | 不下桌,可继续连胡 | | 结束条件 | 一人胡牌即结束 | 一人胡牌即结束 | 牌墙摸尽 | | 一炮多响 | 否 | 否 | 是 |

分数按 底分 × 2^(番数−1),番数封顶 10 番。自摸由其他在桌的人各付,点炮由放炮者付。跨局连续胡牌有连番(每连一次 +1,上限 +3),庄家胡牌连庄同样加番。

不吃牌是刻意的:杭州、成都、血战三种玩法的通行规则都不允许吃,与其做一个玩家用不上的按钮,不如把操作列留给胡 / 槓 / 碰 / 过。

怎么打

点牌选中(那一张会浮起来),再点一次打出。摸到的牌单独摆在手牌最右侧一个独立槽位里,所以理好的那一摞不会因为摸牌而整体左右跳;那一格摆的一定是本巡摸进来的那张——打别的牌它就收进整排重新理齐,打它自己则整排一张不动。

胡 / 槓 / 碰 / 过贴在屏幕右缘,窄竖屏自动换成手牌下方的横排,任何形态都不压自己的牌、也不挡右侧对手的牌。顶栏「番数」打开的浮层按当前玩法列出全部番型,每一条都带可读的牌型图示(单吊用虚线空牌表示)。

手柄 / 键盘:左右方向键或左摇杆在手牌与右侧按钮之间走一格(光标那一张会浮起并描一圈冷白细框,与「可以碰的牌」的描金框是两件事),A / Enter 确认——第一次选中、再按一次打出,X / Backspace 取消选中,Start 暂停。开始屏、结算屏、排行榜、番数表、暂停面板由站点共用壳子接管,手柄可以直接逛。

榜单口径是单局净胜分:一局结算后,在结算屏打开排行榜、填昵称、点「提交成绩」才会上榜,同一局只记一次;开下一局会自动清掉上一局的快照。指标带胡牌次数、玩法、本局最高番。

实现

  • 逻辑与表现彻底分开:src/core/(牌定义、胡牌判定含癞子、番型计算、可序列化的对局状态机、AI)不引用任何 DOM 或 PixiJS,能在 Node 里原样跑;src/ui/ 只认「同形对象」,换成联机快照渲染不用改场景代码。
  • 牌面不是字体画的,是 AI 生成的写实贴图:原图压到工作尺寸后以 data URI 嵌进 src/ui/art.gen.js,运行时按牌宽二分求解版式再 multiply 合成,小于 40px 自动换 small 档(图案放大一档 + 垫柔暗边)。所以条 / 筒 / 万的点数与花色由代码决定,素材只负责材质。
  • 字体自托管:fonts/ 下 8 个字面是从上游完整 TTF 裁出的子集(460 个字符,合计 719 KB),带 sha256 清单。改了文案必须回开发机重出子集,否则 npm run check:fonts 会红——线上新增文案缺字变成豆腐块,是肉眼最难发现的回归。
  • 三种玩法共用一套番型表与结算流程,血战的「胡牌不下桌」靠状态机里的 continueAfterWin 开关,而不是另写一局。
墨局 · 麻将 - 图片 1
墨局 · 麻将 | YODFZ