# 3D-GameBoy **Repository Path**: ns2250225/3D-GameBoy ## Basic Information - **Project Name**: 3D-GameBoy - **Description**: 3D的GameBoy游戏机 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-31 - **Last Updated**: 2026-08-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Game Boy 3D 网页模拟器 网页中央是一台可旋转的 3D Game Boy(DMG-01)模型(按 `gameboy.jpeg` 参照图 1:1 测量建模), 上传游戏 ROM 后,游戏画面会实时渲染到 3D 机身的屏幕上。 模拟内核是 [binjgb](https://github.com/binji/binjgb)(官方预编译 WebAssembly 构建), 3D 渲染使用 three.js。支持 Game Boy / Game Boy Color(CGB)游戏、实时音频、 电池存档(SRAM)自动保存、键盘 / 鼠标点按机身 / 触屏虚拟按键 / USB 手柄多种操作方式, 并已适配移动端(手机竖屏 / 横屏均可游玩)。 ![预览](gameboy.jpeg) ## 快速开始 ```bash ./start.sh # 默认 8123 端口;或 ./start.sh 9000 换端口 ``` 然后浏览器打开 **http://localhost:8123/**: - **右侧货架上就是 `roms/` 目录里的游戏**,每个都是一台 3D 卡带模型—— 把卡带拖到机身上即可插入开机;点击已插入的卡带会弹出并暂停游戏; - 也可以点击右上角「上传 ROM」选择 `.gb` / `.gbc` 文件,或直接把 ROM 拖进网页。 > 必须通过 HTTP 访问(WebAssembly 的加载限制),不能直接双击 index.html。 > 货架内容由服务端动态生成(`/roms/manifest.json`,启动脚本内置)—— > 往 `roms/` 目录放新的 `.gb`/`.gbc` 文件后刷新页面即可上架。 > `cpu_instrs.gb` 是 binjgb 兼容性自测程序,全部通过会显示 “Passed all tests”。 > **本仓库不含任何游戏 ROM**(版权原因,`.gitignore` 已排除 `roms/`), > 请自备 ROM 放入本地 `roms/` 目录。 ### 部署到自己的服务器 页面按以下顺序获取游戏列表,任一方式可用即可: 1. 请求 `roms/manifest.json` 时返回动态生成的清单(`start.sh` 内置该路由; nginx 等服务器也可用 cgi/php 等方式实现); 2. `roms/` 目录的自动索引列表页(python http.server、nginx `autoindex on`、 Apache 默认支持,页面会自动解析其中的 `.gb`/`.gbc` 链接); 3. 静态的 `roms/manifest.json` 文件(随项目附带,ROM 变更后需手动同步更新)。 部署时请确保服务器上的 `roms/` 目录包含你的 ROM 文件;若三者都无法满足, 货架为空但仍可通过「上传 ROM」按钮或拖拽文件游玩。注意部分托管平台会 缓存静态文件,如列表未更新可在 URL 后加随机参数强制刷新。 ## 操作说明 | GB 按键 | 键盘 | 备注 | | --- | --- | --- | | 十字键 | `↑` `↓` `←` `→` | 方向键 | | A 键 | `X` | | | B 键 | `Z` | | | START | `Enter` | | | SELECT | `Shift`(左/右均可) | | | 暂停 / 继续 | `空格` | | | 重新开机 | `R` | 保留电池存档 | - **直接点击 3D 机身上的按键**也能操作(十字键、A/B、SELECT/START 均可点按,带按压动画); - 鼠标拖拽旋转模型、滚轮缩放、**双击复位视角**;快速点一下货架上的卡带也能直接换卡; - 支持 USB / 蓝牙手柄(HTML5 标准按键映射自动识别)。 ### 移动端 / 触屏 手机浏览器打开后自动进入触屏模式: - **屏幕虚拟按键**:载入游戏后底部出现十字键 + A/B + SELECT/START, 支持多键同按与十字键滑动换向; - **底部游戏条**:竖屏下 3D 货架移出画面,游戏条替代货架——点一下即换卡; 横屏下也可以直接点 3D 货架上的卡带换卡; - **视角**:单指拖拽旋转、双指捏合缩放、双击复位;竖屏时相机自动居中取景; - 首次触屏会自动解锁 iOS 的音频(AudioContext 需在用户手势中恢复)。 > 在桌面浏览器加 `?touch=1` 参数可强制开启触屏模式调试。 右上角还可以:暂停 / 继续、重新开机、切换 DMG 屏幕配色(经典绿 / 翠绿 / 灰阶等)、调节音量。 ## 存档 游戏内保存(电池存档 SRAM)会自动持久化到浏览器的 `localStorage`, 按 ROM 文件名 + 大小区分;换游戏、重启浏览器都不会丢失。重启(`R`)会保留存档。 ## 目录结构 ``` index.html 页面骨架 / importmap / 早期错误捕获 style.css UI 样式 main.js Three.js 场景、灯光、拖拽/插入交互、UI 胶水 gb-glb.js GLB 精模加载与归一化(朝向/缩放/屏幕面/按键映射) gb-model.js 程序化 Game Boy 模型(GLB 缺失时的兜底)+ 屏幕画布工厂 game-shelf.js 3D 卡带模型与右侧货架(标签贴图按 ROM 名生成) emulator.js binjgb 封装:主循环 / 视频 / 音频 / 输入 / SRAM vendor/ binjgb.js|wasm binjgb 官方预编译 WebAssembly(github.com/binji/binjgb) three.module.js three.js r169 GLTFLoader.js GLB 加载器(含 utils/BufferGeometryUtils.js) OrbitControls.js 轨道控制器 RoomEnvironment.js 环境光照 nintendo_game_boy_original_1989.glb Game Boy 精模(Sketchfab 来源) roms/ 你的 ROM(货架自动读取);cpu_instrs.gb 为自测程序 start.sh 一键启动本地服务(内置 roms/manifest.json 动态接口) ``` ## 技术说明 - **模拟循环**:`requestAnimationFrame` 驱动,按真实时间换算 CPU 周期(4.19MHz)步进, 掉帧时限制最大追赶量防止快进;窗口被遮挡(rAF 停发)时用心跳定时器兜底。 - **视频**:binjgb 输出 160×144 RGBA 帧缓冲 → `putImageData` 到离屏画布 → three.js `CanvasTexture` 贴到机身屏幕(最近邻采样,保留像素颗粒感)。 - **音频**:binjgb 输出 8-bit 无符号立体声样本(中心 128),按 4096 帧一块 调度到 Web Audio,提前 100ms 排期,落后时自动丢弃重新对齐。 - **配色**:DMG 游戏使用 binjgb 内建调色板(默认 74 号 “GB pocket green”,贴近实机绿屏); CGB 游戏使用自带色板 + Gambatte 色彩曲线。 - **模型**:机身使用 `nintendo_game_boy_original_1989.glb` 精模(加载时自动归一化: 隐藏自带的装饰卡带、按可见网格包围盒缩放到整机高 148mm 并居中);模拟器画面通过 一块叠加屏幕面贴合到模型屏幕开窗(模型原生屏幕面 UV 分组杂乱,不宜直接贴图)。 A/B/SELECT 按键网格可直接点按(带按压动画),十字键与 START 由按实机位置标定的 透明热区承接;若 GLB 文件缺失,自动回退到 `gb-model.js` 的程序化模型。 - **模型细节**:GLB 精模自带完整外观细节;程序化兜底模型依实机参考照片建模 (背面卡带槽通道/浮雕铭牌/棱纹电池盖、锯齿音量轮等)。 ## 致谢与版权 - 模拟内核:[binjgb](https://github.com/binji/binjgb)(MIT License,作者 Ben Smith) - 3D 渲染:[three.js](https://threejs.org)(MIT License) - Game Boy 是任天堂的商标,本项目仅为技术演示。请使用你有权使用的 ROM 文件。