# mini-game **Repository Path**: zhengbaitech/mini-game ## Basic Information - **Project Name**: mini-game - **Description**: 小游戏合集,内含五子棋,围棋,黑白棋等小游戏 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-24 - **Last Updated**: 2026-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 小游戏合集(五子棋 + 标了个标 + 标你的标 + 黑白棋 + 围棋 + 麻将 + 俄罗斯方块 + 贪吃蛇) Web 版小游戏合集,当前包含 **五子棋(双人/人机)**、**标了个标(车标三消)**、**标你的标(实时投掷对决)** 与 **黑白棋(双人/人机)**、**围棋(双人/人机)**、**麻将(推倒胡,单机/联机)**、**俄罗斯方块(经典 NES 手感,单人/双人)** 与 **贪吃蛇(纯单机,闯关/无尽)**。前后端打包在同一个可执行 JAR 中,一条命令即可部署。 ## 功能 ### 大厅 - 游戏列表,游戏名居中展示 - 首次进入必须填写昵称(保存在浏览器 `localStorage`,下次自动带出,可随时点击右上角修改) - 玩家 ID 按浏览器标签页隔离:同一浏览器开两个标签页即可自己和自己测试对战 ### 五子棋 - **房主**:创建房间 → 进入房间后选择执黑/执白 → 等待对手加入并准备 → 点击"开始游戏" - **对手**:输入 6 位房间号加入 → 系统自动分配颜色(房主选剩下的颜色)→ 点击"准备" → 等待房主开始 - 经典木纹棋盘(Canvas 绘制:木纹、星位、A-O / 1-15 坐标、渐变棋子、最后一手红点标记、五连金线高亮) - 一局结束后双方都点击 **继续游戏** 即开始下一局(棋盘清空,黑棋先手) - 侧栏展示 **对局比分**(随胜负实时更新)与 **对局记录**(局数、胜方、获胜原因、时间) - 断线处理:掉线方 60 秒内刷新页面可自动重连;超时未归,对局中判负,对方接管房主位 - 房间号复制 / 邀请链接(打开即预填房间号) - 落子、开局、胜利音效(WebAudio 合成,无外部资源) ### 标了个标(车标三消) - 玩法类似"羊了个羊":多层错位堆叠的牌堆,只有未被压住的牌可点,拿到的牌进入底部 **7 格槽位**,凑齐 **3 张相同车标** 即消除;槽位塞满或场上无牌可拿即出局,清空所有牌即通关 - **单人闯关**:关卡制——第 1 关很简单,失败重试本关(同一副牌),通关解锁下一关 - **双人同题竞速**:双方拿到一模一样的牌堆各自消除,**先清空者胜**;一方出局不立即结束,对方继续打,双方都出局为平局 - 12 款卡通化车标(手绘简化 SVG,无外部图片资源) - 三个道具每关各 1 次:**洗牌**(重排场上牌花色)、**撤回**(撤销最后一次拿牌,含连带三消)、**移出**(槽内前 3 张放回原位) - 难度曲线:第 1 关很简单(3 层 / 6 种花色 / 21 张),第 2 关飙升为 10 层高塔(10 种 / 72 张),此后层数恒为 10,第 3 关起每关牌数约 +10%(上限 252 张,花色每 2 关 +1 上限 12 种);竞速模式按局数套用同一曲线,双方同题保证公平 - 牌堆布局:羊了个羊式 —— 每张牌占 3×3 虚拟格(位置步长 1/3 牌宽),同层牌互不重叠、边贴边铺放,层间错位 1/3~2/3 张形成咬合;边界按"顶/底/右/左"轮换逐层收缩 1 格,牌堆轮廓有机;排面大小随单层牌数自适应 - 房间、断线重连、退出判负、继续下一局、比分与对局记录等机制与五子棋一致 ### 围棋(Go) - **双人对战**:19/13/9 路可选,执黑/执白,中国规则白贴 7.5 目 - **人机对战**:AI 段位按真实围棋业余段位分级——15级 / 10级 / 5级 / 1级 / 业余初段 / 业余高段,强度逐档提升(启发式战术 + 蒙特卡洛终局模拟),对局中可随时切换段位(弃局重开) - **完整规则**:提子、打劫(简单劫)、禁着点(自杀);双方连续停两手进入数子阶段 - **数子阶段**:点击棋组标记/取消死子,实时预览黑目/白目/差距,双方确认后结算;也可恢复对局继续下 - **认输 / 悔棋**:对局中随时认输(高段位 AI 劣势也会中盘认输);悔棋与五子棋同款(SOLO 直接悔,PVP 请求-同意) - 输家下一局可互换执色、断线重连、对局记录等与合集一致 ### 麻将(推倒胡) - **单机/联机一体**:单人开局即 1v3 电脑;创建联机房间后好友可凭房间号/邀请链接加入(最多 4 人),**开局时空座位自动由电脑补齐** —— 1~4 人皆可开局 - **AI**:向听最小化出牌,碰/杠以不升向听决策,能胡必胡 - **简化规则**:只有万/筒/条 108 张,无风无花、无吃、无番;标准 4 副 + 1 对胡,或七对 - **完整流程**:摸牌打牌、碰/明杠/暗杠(杠后补牌)、自摸/点炮、牌墙摸完流局;庄家轮庄 - **要牌仲裁**:多人同时可要牌时开 3 秒仲裁窗(胡 > 杠 > 碰,同优先级离打牌者近者得);唯一要牌者是人类则不限时等待 - **掉线托管**:联机中玩家掉线,座位自动由电脑托管打完;重连(同浏览器)自动归位接管;全员离线 60 秒后解散房间 - 各家视角自动换位(自己永远在下方);快照按座位个性化(只下发自己的手牌/要牌选项) ### 黑白棋(Reversi) - 经典规则:8×8 棋盘,落子必须夹住对方棋子并**翻转为己方颜色**;无合法落子自动跳过;双方均无子可下或棋盘下满即结束,**子多者胜** - **单人挑战 AI**:自选执黑(先行)/执白 + 四档难度(简单→超级困难);AI 采用位置权重表 + 行动力 + α-β 搜索,残局精确算子 - **双人对战**:创建房间/房间号加入/邀请链接,准备-开始流程,执黑先行 - 合法落子位**实时高亮**提示,落子/翻子带动画与音效,顶部实时显示黑白子数比 - 悔棋(单人直接悔/双人需对方同意,不限次数)、切换难度(重开局)、比分与对局记录、断线重连/判负等机制与合集一致 ### 标你的标(实时投掷对决) - 双方站在随机高度的石柱上**实时互掷标枪**,没有回合限制,操作即可投掷(0.9 秒装填冷却),全凭手速与准度 - 操作:在画面上**按住拖拽**——拖拽方向决定投掷角度、拖拽距离决定力度,松手即投;**按住 S/↓ 蹲下**躲避(蹲姿变矮且无头部判定,蹲下时无法投掷) - 部位伤害:爆头 45 / 身体 25 / 腿部 15,HP 100 先归零者输 - 每局随机石柱高度与**风力**(水平风影响弹道,投掷前留意顶部风向标) - 服务器权威模拟:标枪弹道、命中判定全部在服务器逐 tick(33ms)推进,客户端仅做瞄准与动画,无法作弊 - **单人挑战 AI**:四档难度(简单→超级困难),AI 会解算弹道并按难度"抖枪"、加快投掷节奏、概率下蹲躲避你的标枪;对局中可随时切换难度(以新难度重新开局) - **双人对战**:创建房间/房间号加入/邀请链接,准备-开始流程,实时同屏对扔 - **人物与武器**:哪吒(火尖枪·伤害×1.25/装填×1.2)、后羿(落日箭·连射快)、悟空(金箍棒·均衡),非对局中随时切换 - **防御动作**:按住 D 举枪格挡,命中只掉 15% 血(保底 1 点);与蹲避互斥,防御中无法投掷 - **操作方式可选**:指向投掷(拖向哪射向哪)或拉弓模式(向后拉、向前射),侧栏一键切换并记忆偏好 - **碰撞表现**:命中部位判定(爆头暴击+屏幕震动+金色火花)、格挡蓝色火花、标枪撞柱插柱残留、KOF 式顶部大血条(带掉血残影) - 对局中断线 8 秒内刷新可重连,超时判负;其余闭环交互(返回大厅、退出确认等)与合集一致 ### 俄罗斯方块(Tetris) - **经典 NES 手感**:10×20 场地 + NES 逐级重力表(0.8 秒/格起步,29 级到达 1G)、按住 267ms 后自动横移(DAS)、软降 1/2G、计分 1/2/3/4 消 = 40/100/300/1200 ×(等级+1),每 10 行升 1 级 - **经典配色**:Guideline 标准七色(I 青 / J 蓝 / L 橙 / O 黄 / S 绿 / T 紫 / Z 红),黑底白框像素质感,方块斜面高光,右侧 NEXT/SCORE/LINES/LEVEL 经典 NES 信息栏 - **无尽模式**:纯单人生存,无对手无攻击,每 30 秒下落自动加速一级(封顶 1G),消行只计分;结算展示本局得分/消行与房间历史最高分,侧栏与对局记录随时回顾 - **单人挑战 AI**:四档难度(简单→超级困难),AI 枚举全部落点按启发式(聚合高度/消行/空洞/崎岖度/井)评估,低难度带噪声与失误率、反应更慢 - **双人对战**:消行攻击——1/2/3/4 消分别送 0/1/2/4 行垃圾行(整批同一空洞),消行时先抵消自己待接收的垃圾;垃圾行随对方下次落定升起,顶部红色预警条显示待接收行数 - **服务器权威模拟**:33ms tick 在服务端推进重力/DAS/锁定/消行/垃圾,客户端只上送按键事件(左右/旋转/软降/硬降),无法作弊;幽灵落点、消行闪烁、堆顶危险红光均为本地渲染 - 对局中掉线自动暂停,8 秒内刷新重连恢复,超时判负;下方触屏按键(◀ ▶ ⟲ ⟳ ▼ 硬降)桌面/手机均可点按 - 旋转带简易踢墙、0.5 秒锁定延迟(贴地移动可刷新,限 15 次)、硬降每格 +2 分;比分/对局记录/继续游戏/切难度重开等机制与合集一致 ### 贪吃蛇(Snake) - **纯单机页面游戏**:不联机、无 AI 对手,纯前端实现(无 WebSocket),最高分存浏览器 localStorage - **边界可选**:开局前可切换「有边界 / 无边界」——无边界时穿过上下左右任一边界,从对侧回到场地(棋盘变为蓝色虚线框提示);两种边界的最高分分开记录 - **闯关模式**:每关吃满 10 个食物过关,通关奖励 50×关卡分;逐关提速(150ms/格 → 70ms 封底),第 2 关起出现障碍物且逐关增多(布局按关卡号播种,重试同一关布局一致);失败可从本关重来(分数回到进关时的检查点) - **无尽模式**:没有障碍,每吃一个食物提速一点(150ms → 60ms 封底),一命到底冲击最高分 - **金色限定果子**:每吃 5 个食物出现一次,限时 6 秒(临期闪烁),值 50 分 - 撞障碍、咬到自己即结束(有边界时撞墙也结束);方向输入带 3 格缓冲(快速连按不丢转向)、防 180° 掉头 - 操作:方向键 / WASD,手机滑动棋盘或点屏幕方向键;空格/P 暂停,切走页面自动暂停 - 复古像素绿画风:蛇身头亮尾暗渐变、眼睛随行进方向转动;音效 WebAudio 合成,无外部资源 ## 构建与部署 环境要求:JDK 17+(本机验证使用 JDK 21)、Maven 3.6+。 ```bash mvn package -DskipTests ``` 生成可执行 JAR:`target/minigame.jar`。 ```bash # 默认 8080 端口 java -jar minigame.jar # 指定端口 java -jar minigame.jar --server.port=8080 ``` 访问 `http://<服务器IP>:<端口>` 即可。两台电脑/两个浏览器各自打开页面即可联机对战(同一浏览器请开两个标签页,每个标签页算一个独立玩家)。 > 房间与对局数据保存在内存中,重启服务即清空;无需数据库。 ## 技术栈 - 后端:Spring Boot 3.3 + Spring WebSocket(原生 WebSocketHandler,无 STOMP) - 前端:原生 HTML / CSS / JavaScript(Canvas 棋盘),无任何第三方依赖,全部静态资源内嵌 JAR - 通信:客户端每步操作发消息,服务端校验后广播全量房间快照(`room_update`),客户端按快照渲染,保证双端一致 ## 消息协议(WebSocket `/ws/gomoku`) 客户端 → 服务端: | type | 说明 | 关键字段 | |---|---|---| | create_room | 创建房间 | playerId, nickname, color? | | join_room | 加入房间(重连同 ID 自动恢复身份) | roomId, playerId, nickname | | choose_color | 房主换执子颜色(开始前) | roomId, playerId, color | | ready | 访客准备/取消准备 | roomId, playerId, ready | | start_game | 房主开始(需对手已准备) | roomId, playerId | | move | 落子 | roomId, playerId, x, y | | continue_game | 结束后投票继续 | roomId, playerId | | leave_room | 主动退出 | roomId, playerId | | ping | 心跳(25s 一次) | - | 服务端 → 客户端:`room_update`(全量快照,渲染的唯一依据)、`created`、`joined`、`game_start`、`move`、`error`、`opponent_left`、`host_changed`、`pong`。 ## 消息协议(WebSocket `/ws/biao`) 客户端 → 服务端: | type | 说明 | 关键字段 | |---|---|---| | create_room | 创建房间(mode=SOLO 创建后可直接开局) | playerId, nickname, mode | | join_room | 加入房间(仅竞速房间;重连同 ID 自动恢复) | roomId, playerId, nickname | | ready | 访客准备/取消准备 | roomId, playerId, ready | | start_game | 开局(竞速需对手已准备;单人随时可开) | roomId, playerId | | pick | 拿牌(自动三消/出局/通关结算) | roomId, playerId, tileId | | use_prop | 使用道具 | roomId, playerId, kind=shuffle/undo/moveout | | continue_game | 结束后继续(竞速需双方都点) | roomId, playerId | | leave_room | 主动退出 | roomId, playerId | | ping | 心跳(25s 一次) | - | 服务端 → 客户端:`room_update`(全量快照,`boards.host/boards.guest` 为双方各自牌面,客户端只渲染自己那份)、`created`、`joined`、`game_start`、`pick`(含 triple 标记,供音效)、`prop`、`error`、`opponent_left`、`host_changed`、`pong`。 ## 消息协议(WebSocket `/ws/go`) 客户端 → 服务端: | type | 说明 | 关键字段 | |---|---|---| | create_room | 创建房间(mode=SOLO 创建后可直接开局) | playerId, nickname, mode, difficulty, color, boardSize | | join_room | 加入房间(重连同 ID 自动恢复) | roomId, playerId, nickname | | choose_color | 房主选执黑/执白(开始前) | roomId, playerId, color | | set_board_size | 设置棋盘路数 9/13/19(开局前,房主) | roomId, playerId, size | | ready | 访客准备/取消准备 | roomId, playerId, ready | | start_game | 开始(人机随时;双人需对手准备) | roomId, playerId | | move | 落子 | roomId, playerId, x, y | | pass | 停一手(连续两手进入数子) | roomId, playerId | | resign | 认输 | roomId, playerId | | toggle_dead | 数子阶段标记/取消死子(整组) | roomId, playerId, x, y | | confirm_score | 确认数子结果 | roomId, playerId | | resume_game | 数子阶段恢复对局 | roomId, playerId | | continue_game | 结算后继续下一局 | roomId, playerId | | set_difficulty | 人机切换段位(弃局重开) | roomId, playerId, difficulty | | undo_request / undo_accept / undo_reject | 悔棋三段流程 | roomId, playerId | | leave_room | 主动退出 | roomId, playerId | | ping | 心跳(25s 一次) | - | 服务端 → 客户端:`room_update`(全量快照:棋盘/死子/提子/数子预览/确认状态)、`created`、`joined`、`game_start`、`move`(含提子数)、`pass`、`resign`、`error`、`opponent_left`、`host_changed`、`hb`、`pong`。 ## 消息协议(WebSocket `/ws/mahjong`) 客户端 → 服务端:create_room(mode=SOLO/PVP) / join_room(联机加入或重连归位) / start_game / discard(tileId, seat) / hu / peng / gang / pass / continue_game / leave_room / ping(各消息带 seat)。 服务端 → 客户端:`room_update`(**按座位个性化**快照:自己的手牌/摸牌/自摸暗杠提示/要牌选项与 倒计时,牌河副露名册为公共部分;座位含 isAI/online/wins/托管标记)、`created`、`joined`(含座位号)、 `game_start`、`discard`、`peng`、`gang`、`hu`、`player_left`、`error`、`hb`、`pong`。 ## 消息协议(WebSocket `/ws/tetris`) 客户端 → 服务端: | type | 说明 | 关键字段 | |---|---|---| | create_room | 创建房间(mode=SOLO 创建后可直接开局;ENDLESS=无尽模式) | playerId, nickname, mode, difficulty | | join_room | 加入房间(重连同 ID 自动恢复) | roomId, playerId, nickname | | ready | 访客准备/取消准备 | roomId, playerId, ready | | start_game | 开始(人机随时;双人需对手准备) | roomId, playerId | | input | 按键事件(即按即生效) | roomId, playerId, a=L_on/L_off/R_on/R_off/D_on/D_off/R/CCW/HD | | continue_game | 结算后继续(双人需双方都点) | roomId, playerId | | set_difficulty | 人机切换难度(弃局重开) | roomId, playerId, difficulty | | leave_room | 主动退出 | roomId, playerId | | ping | 心跳(25s 一次) | - | 服务端 → 客户端:`room_update`(全量快照)、`created`、`joined`、`game_start`、`tick`(约 30Hz 双方面板快照:可见网格/活动方块/NEXT/分数/行数/等级/待接收垃圾/消行动画行,附 fx 事件 lock/clear/garbage/levelup/die 供音效)、`game_over`、`error`、`opponent_left`、`host_changed`、`pong`。 ## 项目结构 **按游戏分目录组织**:每款游戏的全部代码(后端逻辑 + 前端页面)集中在一个目录下,互不干扰。 ``` src/main/java/com/zb/minigame/ ├── MiniGameApplication.java # 启动类 ├── common/ │ └── PlayerSession.java # 通用:房间内玩家(含断线状态) ├── config/ │ └── WebSocketConfig.java # 通用:WebSocket 路由注册(新游戏加一行) └── games/ ├── gomoku/ # ★ 五子棋(全部代码在这一个目录) ├── tetris/ # ★ 俄罗斯方块(经典 NES 手感) │ ├── TetrisPiece.java # 七种方块形状/旋转/踢墙定义 │ ├── TetrisStack.java # 单人局面状态机(重力/DAS/锁定/消行/垃圾行) │ ├── TetrisAi.java # 落点搜索 + 启发式评估,四档难度 │ ├── TetrisRoom.java # 房间(SOLO/PVP,双方局面编排与胜负判定) │ ├── TetrisRoomManager.java # 房间表 + 过期清理 │ └── TetrisGameServer.java # 33ms tick 服务器权威模拟 + 协议处理 ├── snake/ # ★ 贪吃蛇(纯前端单机,无后端) ├── index.html # http://host:port/games/snake/ ├── snake.css # 复古像素绿样式 + 触屏方向键 └── snake.js # 闯关(播种障碍)/无尽 + localStorage 最高分 ├── mahjong/ # ★ 麻将·推倒胡(全部代码在这一个目录) │ ├── GomokuBoard.java # 15路棋盘 + 五连判定 │ ├── GomokuRoom.java # 房间状态机 WAITING→READYING→PLAYING→RESULT │ ├── GomokuRoomManager.java # 房间表 + 过期清理 │ └── GomokuGameServer.java # 对战协议处理(WebSocket Handler) └── biao/ # ★ 标了个标(车标三消,全部代码在这一个目录) ├── BiaoLevel.java # 一局牌堆静态布局(双方共享) ├── BiaoLevelGenerator.java # 错位层叠布局生成 + 按"3张一组"发花色 ├── BiaoTile.java # 单张牌实时状态(场上/槽内/已消除) ├── BiaoPlayerState.java # 玩家牌局(槽位/道具/撤回栈/胜负结算) ├── BiaoRoom.java # 房间(SOLO/RACE 双模式,状态机同五子棋) ├── BiaoRoomManager.java # 房间表 + 过期清理 └── BiaoGameServer.java # 对战协议处理(WebSocket Handler) src/main/resources/static/ ├── index.html # 大厅(游戏列表) ├── css/style.css # 公共样式 ├── js/common.js # 公共逻辑(昵称、WebSocket 地址等) └── games/ ├── gomoku/ # ★ 五子棋前端(页面/样式/脚本) │ ├── index.html # http://host:port/games/gomoku/ │ ├── gomoku.css │ └── gomoku.js # 经典棋盘 Canvas 绘制 + 对局交互 └── biao/ # ★ 标了个标前端(页面/样式/脚本) ├── index.html # http://host:port/games/biao/ ├── biao.css └── biao.js # DOM 牌堆渲染 + FLIP 飞槽动画 + 12款卡通车标 SVG └── snake/ # ★ 贪吃蛇前端(纯单机,无 WebSocket) ├── index.html # http://host:port/games/snake/ ├── snake.css └── snake.js # Canvas 格子渲染 + 闯关/无尽 + 触屏方向键 ``` ### 如何新增一款游戏 1. 后端新建 `com.zb.minigame.games.<游戏名>/` 包,实现自己的 `XxxGameServer`(参考 `GomokuGameServer`),并在 `config/WebSocketConfig` 中注册路由(如 `/ws/chess`); 2. 前端新建 `static/games/<游戏名>/` 目录,放入 `index.html` 及资源,引用外层 `../../css/style.css` 与 `../../js/common.js`; 3. 在大厅 `static/index.html` 的游戏列表中加一张卡片,链接指向 `games/<游戏名>/`。