# fbox **Repository Path**: hhf002/fbox ## Basic Information - **Project Name**: fbox - **Description**: FBOX游戏盒子安卓版,支持NES卡带\GBA卡带\SFC卡带游戏。内置安卓原生小游戏、H5web小游戏。可离线运行 - **Primary Language**: Unknown - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-25 - **Last Updated**: 2026-07-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FBox > **经典游戏,一触即达** — 八九十年代经典单机游戏聚合平台 > APK ≈ 15 MB(NES×2 + GBA×2 + SFC) --- ## 📦 项目文件总览 | 类别 | 说明 | |:---|:---| | **架构** | libretro + LibretroDroid GLRetroView,零自定义 JNI | | **交互** | 点击直接玩,长按看详情,♥收藏 | | **导入** | 单文件 + 批量目录扫描,自动按平台分类 | | **特色页** | 今日可玩 + 卡片/列表双视图切换(仅在线时展示,离线不展示) | | **虚拟手柄** | 3 种风格(经典十字键 / PS 分体式 / MOBA 摇杆) | | **手柄增强** | 透明度 SeekBar 滑块 / 震动反馈 10ms / 自定义布局拖拽保存 | | **物理键盘** | 外接键盘映射:X→A, Z→B, 方向键, Enter→START, Shift→SELECT | | **合规** | 仅内置 7 款原生小游戏 + 14 款 H5 游戏,不包含任何有版权的商业 ROM | | **后端对接** | fbox-backend (Spring Boot), ApiService OkHttp 异步请求,数据回退本地 | | **自动更新** | 启动时静默检查 + 手动检查入口,支持强制/可选双策略、应用市场跳转、APK 下载安装 | | **APK** | ≈ 15 MB(仅 NES+GBA+SFC libretro 核心) | --- ## 🏗 项目结构 ``` gbox/ ├── 📄 settings.gradle # 项目设置(JitPack 仓库) ├── 📄 build.gradle # 项目级构建配置 ├── 📄 gradle.properties # Gradle 参数 ├── 📄 README.md # 本文件 ├── 📄 ROADMAP.md # 开发路线图 ├── 📄 DEVELOPMENT.md # 开发环境说明 ├── 📄 roadmap_strategic.md # 战略规划 ├── gradle/wrapper/ │ └── gradle-wrapper.properties # Gradle 8.4 ├── app/ │ ├── 📄 build.gradle # 应用构建配置(SDK 21-34, abiFilters arm64-v8a) │ ├── 📄 proguard-rules.pro # 混淆规则 │ └── src/main/ │ ├── 📄 AndroidManifest.xml # 权限 + Activity 声明 + usesCleartextTraffic │ ├── res/ │ │ ├── values/ │ │ │ ├── colors.xml # 色彩方案(#F0F4F8 背景, #4A90E2 蓝色) │ │ │ ├── strings.xml # 中文字符串 │ │ │ ├── themes.xml # 4 套主题(浅/深/启动/全屏) │ │ │ └── dimens.xml # 间距/圆角/字号 │ │ ├── drawable/ # XML 可绘制资源 │ │ ├── mipmap-*/ # 启动图标 │ │ └── layout/ # XML 布局 │ ├── jniLibs/ # libretro 核心 .so 文件 │ │ ├── arm64-v8a/ │ │ │ ├── libfceumm_libretro.so # 4.1 MB │ │ │ ├── libnestopia_libretro.so # 5.7 MB │ │ │ ├── libmgba_libretro.so # 3.1 MB │ │ │ ├── libgpsp_libretro.so # 677 KB │ │ │ └── libsnes9x_libretro.so # 2.8 MB │ │ └── x86_64/ │ │ └── ... (同上, 构建时通过 abiFilters 排除) │ └── java/com/fbox/app/ │ ├── 📄 FBoxApplication.java # Application 入口 │ ├── 📄 MainActivity.java # 主界面(4 Tab 底部导航) │ ├── manager/ │ │ ├── FavoriteManager.java # 收藏管理(SharedPreferences) │ │ ├── ImportedRomManager.java # 本地 ROM 导入管理 │ │ ├── PlayHistoryManager.java # 游玩历史记录 │ │ ├── GamepadStyleManager.java # 手柄偏好 │ │ ├── RecommendManager.java # 今日推荐管理 │ │ └── AppUpdateManager.java # App自动更新(检查/下载/安装) │ ├── emulator/ │ │ ├── CoreID.java # 核心 ID 定义 │ │ └── CoreManager.java # 核心路径解析 │ ├── util/ │ │ ├── StorageUtil.java # 存储路径 + 下载记录/版本号持久化(SharedPreferences) │ │ ├── VersionUtil.java # 语义化版本比较(isNewer/compare) │ │ ├── MD5Util.java # MD5 文件校验 │ │ └── ZipUtils.java # zip 解压(H5 游戏下载) │ ├── download/ │ │ └── DownloadManager.java # 下载管理(断点续传 + MD5 校验 + 版本号保存) │ ├── model/ │ │ ├── Game.java # 游戏模型(含 version、logo 字段) │ │ └── DownloadTask.java # 下载任务模型 │ │ └── AppUpdateInfo.java # App更新信息模型 │ └── ui/ │ ├── home/HomeFragment.java # 首页 Tab │ ├── favorite/FavoriteFragment.java # 收藏 Tab │ ├── recommend/RecommendFragment.java # 特色 Tab │ ├── hall/HallFragment.java # 游戏仓库 Tab │ ├── detail/GameDetailActivity.java # 游戏详情(长按弹出) │ ├── member/MemberActivity.java # 会员中心 │ ├── update/UpdateDialogActivity.java # App更新对话框 │ ├── emulator/ │ │ ├── EmulatorActivity.java # 模拟器游玩页面 │ │ └── VirtualGamepadView.java # 虚拟手柄(3 种风格) │ ├── mine/ProfileActivity.java # 个人中心 │ └── adapter/GameCardAdapter.java # 游戏卡片适配器 │ └── api/ │ └── ApiService.java # fbox-backend API 客户端 ``` --- ## 🚀 技术栈 | 类别 | 选型 | 版本 | |:---|:---|:---| | 语言 | Java | 17 | | 最低 SDK | API 21 | Android 5.0+ | | 目标 SDK | API 34 | Android 14 | | 构建工具 | Gradle | 8.4 | | JSON 解析 | Gson | 2.10.1 | | 图片加载 | Glide | 4.16.0 | | UI 组件 | Material Design | 1.11.0 | | 架构 | ViewBinding + Fragment | — | | 模拟器引擎 | **LibretroDroid GLRetroView** | 零自定义 JNI | | 模拟器核心 | FCEUmm / Nestopia / mGBA / gpSP / Snes9x | 5 核 7 平台 | --- ## 📱 功能模块 ### 1️⃣ 首页(HomeFragment) - 搜索栏 + 用户头像入口 - 内置游戏网格(「我的游戏」,本地所有游戏,含 7 款原创小游戏 + assets/roms 扫描 ROM,按游玩时间倒序) - 热门游戏(从 fbox-backend `/api/config/home` → `hotGames` 加载,支持自动/手动模式,失败回退本地) ### 2️⃣ 收藏(FavoriteFragment) - 已收藏游戏网格(卡片/列表切换) - 导入 ROM 文件(单文件) - 导入 ROM 目录(批量扫描子目录 + 进度条) - 本地游戏搜索 - 长按多选 + 批量删除 - 分页加载(每页 8 行 × 4 列 = 32 个) ### 3️⃣ 特色(RecommendFragment) - 今日可玩(从 fbox-backend /api/config/featured 加载,失败回退本地) - 距离次日刷新倒计时(从 /api/recommends/countdown 加载) - 卡片/列表双视图切换 - 收藏后当天可玩,过期引导开通高级版 ### 4️⃣ 游戏仓库(HallFragment) - 游戏搜索 + 平台/类型筛选(筛选Tab从 /api/config/repository 加载) - 游戏列表(从 /api/games 查询,支持平台/类型/关键词筛选,失败回退本地 GameManager) ### 5️⃣ 模拟器游玩(EmulatorActivity) - 全屏横屏沉浸式体验 - 3 种虚拟手柄风格可选(经典 / PS / MOBA) - 存档/读档 + 即时存档/读档 - 2 倍加速模式 - 多点触控支持 ### 6️⃣ 会员中心(MemberActivity) - 会员状态显示(普通/永久/剩余天数) - 购买入口 ### 7️⃣ 个人中心(ProfileActivity / MineFragment) - 左上角 ← 关闭按钮 - 用户信息展示 - 服务器设置入口(配置 fbox-backend 地址) - 检查更新入口(手动检查 App 新版本,带进度对话框) ### 8️⃣ 设置菜单(EmulatorActivity ⚙️ 弹出) - 点击左上角 ⚙️ 弹出分组设置菜单 - **💾 存档管理**:存档、读档、即时存档、即时读档 - **🎮 游戏设置**:游戏速度切换(1x/2x) - **🕹️ 虚拟手柄设置**:手柄风格切换、透明度 SeekBar 滑块、手柄自定义(拖拽编辑)、恢复默认布局 - 弹窗半透明可透视游戏画面,调节透明度可实时预览效果 - **打开菜单自动暂停游戏**,关闭菜单自动恢复 ### 9️⃣ 游戏版本管理与更新提示 详情页(`GameDetailActivity`)支持基于语义化版本号的更新检测,覆盖 H5 远程游戏和 ROM 游戏。 | 维度 | 说明 | |:---|:---| | **版本来源** | API 详情接口返回的 `game.version` 字段(后端 `fbox_game.version`) | | **本地版本** | 下载完成后由 `DownloadManager` 调用 `StorageUtil.saveGameVersion()` 持久化到 `SharedPreferences`;内置 web 游戏从 `manifest.json` 的 `version` 字段读取 | | **版本比较** | `VersionUtil.isNewer(remote, local)` 按数值逐段比较 `x.y.z`(如 `1.10.0` > `1.9.0`) | | **更新提示** | 详情页状态标签优先显示「🆕 有新版本 v{x.y.z}」,下载按钮变为「📥 更新」可点击触发覆盖下载 | | **跳过检测** | `mg` 内置小游戏、内置 web 游戏(非远程下载)不检测更新 | | **删除清理** | 删除游戏时同步调用 `StorageUtil.clearGameVersion()` 清除版本记录 | | **下载量上报** | 下载完成后调用 `ApiService.reportDownload(gameId)` 通知后端递增 `download_count`(fire-and-forget,失败不影响本地流程),用于热门游戏排序和详情页下载次数展示 | **数据流**: ``` fbox-backend fbox_game.version → API 详情响应 game.version → VersionUtil.isNewer(远程版本, StorageUtil.getDownloadedGameVersion()) → hasUpdate() = true → 状态标签「🆕 有新版本」 + 下载按钮「📥 更新」 → 重新下载完成 → StorageUtil.saveGameVersion(新版本) → 提示消失 ``` ### 1️⃣1️⃣ 后端游戏数据同步(含内置游戏) App 在线时,后端返回的游戏数据会自动同步到本地 `GameManager`,**包括内置 mg 游戏**。这样后端修复游戏 bug、更新版本或上传新 logo 后,首页"我的游戏"也能展示最新数据。 | 维度 | 说明 | |:---|:---| | **同步方法** | `GameManager.updateFromList(List remoteGames)` — 按 gameId 匹配本地游戏并同步可变字段 | | **同步字段** | name/version/logo/cover/downloadUrl/md5/fileSize/downloadCount/description/genre/genreLabel/year/company/isFree | | **保留本地字段** | platform/platformLabel — 避免后端字段缺失导致 NPE | | **接入点** | `ApiService` 的 4 个接口 onSuccess 回调:`fetchHotGames`/`fetchGameList`/`fetchGameDetail`/`fetchFeaturedConfig` | | **失败处理** | fire-and-forget,同步失败仅打日志,不影响调用方流程 | | **downloadUrl** | 同步时拼接 CDN base(相对路径 → 完整 URL) | | **cover/logo** | 存相对路径,由 `GameCardAdapter.bindIcon()` 的 `resolveCdnUrl()` 拼接 | **Logo 展示优先级**(`GameCardAdapter.bindIcon`): 1. 后端 logo URL(Glide 加载,同步后内置游戏也可用) 2. `GameIconDrawable` canvas 自绘图(7 款 mg 游戏专属矢量图标) 3. emoji 文字兜底 **数据流**: ``` 后端 /api/games 或 /api/games/{gameId} 返回 Game 列表 → ApiService.syncToGameManager(games) (fire-and-forget) → GameManager.updateFromList(games) → 按 gameId 匹配本地游戏 → 已存在:同步 version/logo/cover/downloadUrl 等可变字段 → 不存在:加入本地游戏列表 → 首页"我的游戏"下次 onResume 刷新时展示最新数据 ``` ### 🔟 App 客户端自动更新 支持 App 整包自动更新,覆盖启动检查、手动检查、强制更新、频次控制、应用市场跳转等场景。 | 维度 | 说明 | |:---|:---| | **检查时机** | ① App 启动时(`MainActivity` 静默检查,失败不提示)
② 手动检查(「我的」→「检查更新」,带进度对话框,绕过频次控制)
③ 从桌面/其他应用切回时(`MainActivity.onResume` 兜底,防止绕过强制更新) | | **版本比较** | 客户端 `versionCode` < 后端最新启用版本 `versionCode` 时触发更新 | | **更新策略** | ① 强制更新:对话框无法关闭,返回键无效,必须更新,绕过所有频次控制
② 可选更新:提供「立即更新」「稍后再说」「跳过该版本」三个按钮 | | **频次控制** | 自动检查时按以下规则限制提示频次(强制更新和手动检查不受限):
① **跳过版本**:用户点击「跳过该版本」后永久跳过该 `versionCode`,直到后端发布更高版本
② **稍后提醒**:用户点击「稍后再说」后进入 24h 冷却期,期间自动检查不再弹窗
③ 冷却期过后或后端发布新版本,恢复正常提示 | | **下载安装** | OkHttp 流式下载 + 进度条 + MD5 校验 + FileProvider 调起系统安装器 | | **应用市场** | 对话框提供「前往应用市场」次级入口,跳转设备已安装的应用市场 | | **APK 存储** | 下载到 `外部存储/FBox/apk/fbox-.apk`,覆盖旧文件 | | **权限** | `REQUEST_INSTALL_PACKAGES`(安装 APK)+ `FileProvider`(共享文件) | **核心类:** | 类 | 职责 | |:---|:---| | `AppUpdateManager` | 单例,检查更新/下载APK/安装APK/跳转应用市场 + `shouldShowUpdate()` 频次控制判断 | | `AppUpdateInfo` | 更新信息模型(Serializable,对应后端 `AppVersion`) | | `UpdateDialogActivity` | 更新对话框 UI(三按钮:立即更新/稍后再说/跳过该版本 + 进度条 + 市场入口) | | `StorageUtil` | 频次控制持久化(跳过版本 versionCode + 稍后提醒时间戳) | | `ApiService.fetchAppUpdate()` | 调用 `GET /api/app/check-update?versionCode=N` | **频次控制持久化字段**(`SharedPreferences` / `download_records`): | 字段 | Key | 类型 | 说明 | |:---|:---|:---|:---| | 跳过版本 | `app_skipped_version_code` | int | 用户点击「跳过该版本」后记录的 `versionCode`,永久跳过直到新版本 | | 稍后提醒时间戳 | `app_last_skip_timestamp` | long | 用户点击「稍后再说」时的时间戳,24h 冷却期(`REMINDER_COOLDOWN_MS`) | **频次控制判定规则**(`AppUpdateManager.shouldShowUpdate(update, manual)`): | 场景 | 自动检查(启动/onResume) | 手动检查(「我的」→检查更新) | |:---|:---|:---| | 强制更新 | ✅ 弹窗 | ✅ 弹窗 | | 非强制 + 首次 | ✅ 弹窗 | ✅ 弹窗 | | 非强制 + 点过「稍后再说」(24h 内) | ❌ 静默 | ✅ 弹窗 | | 非强制 + 点过「跳过该版本」 | ❌ 静默 | ✅ 弹窗 | | 后端发布更高版本 | ✅ 弹窗(versionCode 不同) | ✅ 弹窗 | **数据流**: ``` fbox-backend fbox_app_version (enabled=1, 最新 versionCode) → API /api/app/check-update?versionCode=客户端versionCode → 返回 AppUpdateInfo(versionCode > 客户端 → 有更新;null → 已是最新) → AppUpdateManager.shouldShowUpdate(update, manual) → 强制更新 / 手动检查 → 直接弹窗 → 自动检查 → 跳过版本 / 24h 冷却期内 → 静默;否则弹窗 → UpdateDialogActivity.launch() → 用户选择: ├─ 立即更新 → AppUpdateManager.downloadApk() → installApk() ├─ 稍后再说 → StorageUtil.markLaterReminder() → 24h 冷却 └─ 跳过该版本 → StorageUtil.skipAppVersion(versionCode) → 永久跳过 ``` **发布新版本流程**: 1. 在 `fbox/app/build.gradle` 升级 `versionCode` 和 `versionName` 2. gradle 打包 APK 3. 浏览器打开后台 → 系统管理 → App版本管理 → 上传 APK,填写版本号/更新说明/是否强制 4. 客户端下次启动自动检测到新版本,按频次控制规则决定是否弹出更新对话框 ### 1️⃣1️⃣ 后端 API 集成 | 端点 | 用途 | 调用方 | |:---|:---|:---| | `GET /api/config/home` | 首页配置(热门游戏 + Banner) | HomeFragment | | `GET /api/config/featured` | 特色页配置(今日可玩 + 倒计时) | RecommendFragment | | `GET /api/config/repository` | 仓库筛选Tab配置 | HallFragment | | `GET /api/games` | 游戏列表(分页+平台/类型/搜索筛选) | HallFragment | | `GET /api/games/hot` | 热门游戏(按下载量排序) | HomeFragment | | `GET /api/games/gameId/{gameId}` | 游戏详情(含 `version` 字段) | GameDetailActivity | | `POST /api/games/gameId/{gameId}/download` | 上报下载事件(递增下载次数) | DownloadManager | | `GET /api/recommends/today` | 今日推荐 | (FeaturedConfig 回退) | | `GET /api/recommends/countdown` | 刷新倒计时 | RecommendFragment | | `GET /api/app/check-update` | App 自动更新检查 | MainActivity / MineFragment | | `GET /apps/` | App 更新包下载(静态资源) | AppUpdateManager | 后端地址默认为 `http://192.168.1.100:8080`,可在「我的」→「设置」中修改。 所有 API 调用失败时自动回退到本地 GameManager / RecommendManager。 --- ## 📊 交互规则 | 操作 | 行为 | |:---|:---| | 点击游戏卡片 | 直接进入模拟器游玩(EmulatorActivity) | | 长按游戏卡片 | 弹出游戏详情页(GameDetailActivity) | | ♥ 图标点击 | 收藏/取消(实心 ♥ 红 / 空心 ♡ 灰) | | 搜索栏头像 | 进入个人中心(ProfileActivity,←返回) | | 搜索栏点击 | 跳转游戏仓库(Tab 3) | | 特色页视图切换 | ▦ 卡片 / ≡ 列表 两种模式 | | 导入本地游戏 | 单文件选择 或 目录批量扫描 → 按后缀分类 | | 本地游戏批量删除 | 长按进入多选 → 勾选 → 批量删除 | --- ## 🗺️ 页面导航 | Tab | 图标 | Fragment | 说明 | |:---|:---|:---|:---| | 首页 | ⌂ | HomeFragment | 搜索栏 → 我的游戏(本地) → 热门游戏(API) | | 收藏 | ♥ | FavoriteFragment | 已收藏网格 + 导入按钮 + 本地游戏(卡片/列表切换) | | 特色 | ★ | RecommendFragment | 今日可玩 + 倒计时 + 卡片/列表双视图 | | 游戏仓库 | ▣ | HallFragment | 游戏搜索 + 筛选 + 列表 | | 个人中心 | 👤 | ProfileActivity | 左上角 ← 返回,头像从首页搜索栏进入 | --- ## 🕹️ 模拟器核心一览 | 平台 | 核心 | 核心来源 | 核心描述 | 体积 | ROM 格式 | ROM 后缀 | 游戏相关公司 | 状态 | 代表作 | |:---|:---|:---|:---|:---|---:|:---|:---|:---|:--------------------------------------------------------------------------------------------------------------------------------| | 🕹️ NES/FC | FCEUmm | 社区维护(FCEUX 分支) | 基于 FCEUX 的轻量级 NES 核心,兼容性优秀,性能极佳 | 4.1 MB | NES 卡带 | `.nes` | 任天堂、Konami、Capcom、Hudson | ✅ 保留 | **任天堂**: 超级马里奥兄弟、塞尔达传说、银河战士、恶魔城;**Konami**: 魂斗罗、沙罗曼蛇;**Capcom**: 洛克人、松鼠大作战;**Hudson**: 冒险岛、炸弹人;**其他**: 坦克大战、忍者龙剑传、双截龙 | | 🕹️ NES/FC | Nestopia | 社区维护(Nestopia UE 分支) | 高精度 NES 核心,追求原版硬件行为还原,画面精确 | 5.7 MB | NES 卡带 | `.nes` | 任天堂、Konami、Capcom、Hudson | ✅ 保留 | **任天堂**: 超级马里奥兄弟3、塞尔达传说2、星之卡比;**Konami**: 恶魔城、月风魔传;**Capcom**: 街头霸王2010、出击飞龙;**其他**: 最终幻想、勇者斗恶龙、三国志 | | 🎮 GBA | mGBA | endrift | 现代 GBA 核心,兼容性极高,支持多种增强功能与调试工具 | 3.1 MB | GBA 卡带 | `.gba` | 任天堂、Game Freak、Capcom | ✅ 保留 | **任天堂**: 超级马里奥Advance、塞尔达传说 缩小帽、银河战士 融合;**Game Freak**: 宝可梦 红宝石/蓝宝石/绿宝石、宝可梦 火红/叶绿;**Capcom**: 逆转裁判、洛克人Zero、恶魔城 月之轮回 | | 🎮 GBA | gpSP | Exophase | 早期开源 GBA 核心,极致轻量高效,兼容性良好 | 677 KB | GBA 卡带 | `.gba` | 任天堂、Game Freak、Capcom | ✅ 保留 | **任天堂**: 马里奥与路易吉RPG、耀西岛Advance;**Game Freak**: 宝可梦 不可思议的迷宫;**Square**: 最终幻想VI Advance、最终幻想I&II;**其他**: 火焰之纹章 封印之剑、黄金太阳 | | 🎮 SFC | Snes9x | 社区维护 | 经典 SFC 核心,历经数十年开发打磨,兼容游戏数量最广 | 2.8 MB | SFC 卡带 | `.smc` / `.sfc` | 任天堂、Square、Enix | ✅ 保留 | **任天堂**: 超级马里奥世界、塞尔达传说 众神的三角力量、星之卡比 超级豪华版、银河战士;**Square**: 时空之轮、最终幻想VI、圣剑传说3;**Enix**: 勇者斗恶龙V、勇者斗恶龙VI;**其他**: 皇家骑士团、火焰之纹章 圣战之系谱 | | 🕹️ 街机 | FBNeo | 社区维护(FinalBurn Neo) | 街机模拟核心,支持数千款街机 ROM,精度高但体积巨大 | 65 MB | 街机 ROM 合集 | `.zip` | Capcom、SNK、Namco | 🗑️ 已移除(体积大 + 版权风险) | **Capcom**: 街头霸王II、恐龙快打、名将、吞食天地;**SNK**: 拳皇97、合金弹头、侍魂;**Namco**: 吃豆人、铁拳;**其他**: 三国战纪、西遊释厄传 | | 🕹️ MD | Genesis Plus GX | 社区维护 | MD/Genesis 高精度核心,兼容性优秀,支持多区域 BIOS | 13 MB | MD 卡带 | `.bin` / `.md` / `.gen` | SEGA、Treasure、Technosoft | 🗑️ 已移除(精简体积) | **SEGA**: 索尼克2、怒之铁拳2、光之继承者;**Treasure**: 火枪英雄、幽游白书 魔强统一战;**Technosoft**: 雷鸟号、雷电;**其他**: 梦幻之星IV、光明力量II | > FBNeo 移除原因:65MB 体积过大且包含大量未经授权的商业游戏 ROM 支持,存在版权风险。 > Genesis Plus GX 移除原因:13MB 体积偏大,MD 平台经典游戏较少,用户需求低。 --- ## 🎯 内置安卓原生游戏 FBox 内置了 **7 款纯 Java 实现的安卓原生小游戏**,无需模拟器核心,使用 Canvas + SurfaceView 直接渲染,永远免费。 | 游戏 | 类文件 | 平台标签 | 类型 | 实现方式 | 操作方式 | |:---|:---|:---|:---:|:---|:---| | 🐍 **贪吃蛇** | `SnakeGame.java` | 内置 | 益智 | Canvas 网格绘制 | 滑动/方向键控制 | | 🔷 **俄罗斯方块** | `TetrisGame.java` | 内置 | 益智 | Canvas 方块绘制 | 虚拟键盘/滑动手势 | | 💣 **扫雷** | `MineSweeperGame.java` | 内置 | 益智 | Canvas 格子绘制 | 点击翻开/标记 | | 🔢 **2048** | `Game2048.java` | 内置 | 益智 | Canvas 数字方块 | 滑动合并数字 | | 🧩 **拼图** | `PuzzleGame.java` | 内置 | 益智 | Canvas 滑块绘制 | 点击滑块移位 | | 🐤 **Flappy Bird** | `FlappyBirdGame.java` | 内置 | 动作 | Canvas 管道绘制 | 点击飞行 | | ♟️ **中国象棋** | `ChineseChessGame.java` | 内置 | 策略 | Canvas 棋盘绘制 | 双人对弈 | ### 管理入口与展示方式 | 维度 | 说明 | |:---|:---| | **注册位置** | `GameActivity.createGame(gameId)` switch 分支 + `GameManager` 初始化 `addGame()` | | **平台标记** | `"mg"`(代码层)/ `"内置"`(UI 展示层) | | **定价** | 永远免费(`isFree=true`) | | **入口** | 与模拟器游戏混排,首页/收藏/特色/仓库中统一展示为游戏卡片 | | **点击行为** | 卡片点击 → 判断平台为 `"mg"` → 启动 `GameActivity` 而非 `EmulatorActivity` | | **长按行为** | 与模拟器游戏一致,弹出 `GameDetailActivity` 详情页 | | **收藏支持** | ✅ 支持 ♥ 收藏,走 `FavoriteManager` | ### 技术架构 ``` GameActivity (AppCompatActivity) └── SurfaceView (全屏) + 60fps 渲染线程 └── MiniGame 接口 ├── onInit(w, h) -- 初始化 ├── onTick(deltaMs) -- 每帧更新逻辑 ├── onDraw(Canvas) -- 每帧绘制 ├── onTouch(event) -- 触摸事件(SurfaceView 坐标,修正 ARM64 偏移) ├── onKeyDown(key, ev) -- 物理按键事件 ├── onVirtualKey() / onVirtualKeyUp() -- 虚拟键盘回调 ├── onPause() -- 暂停 └── onResume() -- 恢复 ``` - 视图层:`SurfaceView` + `SurfaceHolder.Callback` 管理生命周期 - 渲染线程:固定 60fps 循环,防跳帧(delta > 100ms 时钳位到 16ms) - 每个游戏类实现 `MiniGame` 接口,独立维护游戏状态 - 游戏列表图标:`GameIconDrawable` 用 Canvas API 为每个游戏绘制专属矢量图标 ### 后续扩展策略 | 策略 | 说明 | |:---|:---| | **扩展方式** | 新增类实现 `MiniGame` 接口 → `GameActivity.createGame()` 添加分支 → `GameManager.initGames()` 添加元数据 | | **建议方向** | 2048、拼图、Flappy Bird 克隆、打地鼠 等轻量级休闲游戏 | | **技术限制** | Canvas 2D 渲染,不适合 3D/物理引擎密集型游戏 | | **优先级** | 🟢 低(排支付 IAP / 物理手柄 / 深色模式之后) | | **目标定位** | 作为模拟器游戏的补充内容,吸引非核心玩家,提高日活 | --- ## 🌐 内置 HTML5 游戏 FBox 内置了 **14 款 HTML5 + CSS3 + JavaScript 实现的 H5 小游戏**,运行于系统 WebView(无需模拟器核心),单文件 `index.html` 打包在 `assets/webgames/` 目录下。所有游戏遵循统一规范:深色主题、规则弹窗 + 下滑关闭、`transform:scale` 屏幕适配、触摸友好。 | gameId | 名称 | 类型 | 渲染 | 亮点 | |:---|:---|:---|:---|:---| | `web_gomoku` | 五子棋 | 策略 | Canvas | 15×15 棋盘 + 人机 AI | | `web_emoji_match` | Emoji 连连看 | 益智 | DOM | 16 关,提示/重列道具 | | `web_emoji_memory` | Emoji 翻卡配对 | 益智 | DOM | 16 关,3D 翻转动画 | | `web_zuma` | 祖玛 | 动作 | Canvas | 特殊球 + 连锁 + 冒险/生存模式 | | `web_sokoban` | 推箱子 | 益智 | Canvas | 30 关,3 难度,撤销/重置 | | `web_tetris` | 俄罗斯方块 | 益智 | Canvas | 7 种 Tetromino + 等级系统 | | `web_breakout` | 打砖块 | 动作 | Canvas | 多关砖块布局 + 反弹角度 | | `web_match3` | 开心消消乐 | 益智 | DOM | 10 关,连击 + 特殊棋子 | | `web_checkers` | 国际跳棋 | 策略 | Canvas | 飞王 + 强制吃子 + AI 三档 | | `web_junqi` | 军棋 | 策略 | Canvas+DOM | 明/暗/双明/全暗 + AI 三档 | | `web_animal` | 斗兽棋 | 策略 | Canvas | 经典 8 动物 + 陷阱兽穴 + AI 三档 | | `web_sudoku` | 数独 | 益智 | DOM | 三难度 + 笔记 + 提示/撤销/检查 | | `web_oneline` | 一笔画 | 益智 | Canvas | 12 关,欧拉图奇点理论 | | `web_plumber` | 水管工 | 益智 | Canvas | 12 关,位掩码管道 + BFS 水流 | ### 管理入口与展示方式 | 维度 | 说明 | |:---|:---| | **注册位置** | `GameManager.loadWebGames()` 自动扫描 `assets/webgames/*/manifest.json` | | **平台标记** | `"web"`(代码层)/ `"H5游戏"`(UI 展示层) | | **入口 Activity** | `WebGameActivity`(独立 Activity,加载 `file:///android_asset/webgames/{id}/index.html`) | | **JS 桥接** | `WebGameJavaScriptInterface` 暴露 `FBoxBridge.saveGame/loadGame/getDensity` 等 | | **图标** | `GameIconDrawable` 为每款游戏绘制专属 Canvas 矢量图标 | | **存档** | `SharedPreferences`(`webgame_saves`)通过 `FBoxBridge` 读写 | ### 技术架构 ``` WebGameActivity (AppCompatActivity) └── WebView (全屏, JS 启用, DOMStorage 启用) └── file:///android_asset/webgames/{gameId}/index.html ├── HTML + CSS + JS 单文件实现 ├── transform:scale 屏幕适配 ├── Canvas 2D / DOM 渲染 └── 规则弹窗 + 下滑关闭手势 ``` ### 通用开发规范 所有 H5 游戏遵循统一规范(详见 `roadmap_web.md` 第 10.0 节): - **视觉主题**:背景 `#1a1a2e`、卡片 `#16213e`、边框 `#0f3460`、金色 `#ffd700`、蓝色 `#4a90e2` - **规则弹窗**:右上角 📖 按钮,弹窗支持下滑超过 80px 关闭 - **屏幕适配**:`#game` 固定 480×720,`transform-origin:top left` + `scale = min(sw/480, sh/720)` - **触摸友好**:点击区域 ≥ 40×40px,DPR 高清适配 - **无外部依赖**:纯 HTML+CSS+JS 单文件,不引用 CDN/字体/图片 ### 后续扩展策略 | 策略 | 说明 | |:---|:---| | **扩展方式** | 创建 `assets/webgames/{gameId}/` 目录 + `index.html` + `manifest.json` → 自动注册 | | **无需改 Java** | `GameManager` 自动扫描 manifest,`GameIconDrawable` 仅在需要自绘图标时改 | | **建议方向** | 数独、俄罗斯方块、消消乐、棋类、解谜类等轻量级 H5 游戏 | | **技术限制** | WebView 性能依赖设备,不适合 3D/物理引擎密集型游戏 | | **目标定位** | 补充原生小游戏,提供多样化休闲体验 | --- ## 📦 模拟器核心部署 核心 .so 文件存放路径 `app/src/main/jniLibs/{abi}/`: | 架构 | 目录 | |:---|:---| | arm64-v8a(真机) | `jniLibs/arm64-v8a/` | | x86_64(模拟器,通过 abiFilters 排除) | `jniLibs/x86_64/` | 构建时在 `app/build.gradle` 中配置: ```groovy ndk { abiFilters 'arm64-v8a' } ``` --- ## 📁 ROM 导入 | 功能 | 实现 | |:---|:---| | 单文件导入 | `ActivityResultContracts.OpenDocument` | | 批量目录导入 | `OpenDocumentTree` → 递归扫描子目录 | | 权限持久化 | `takePersistableUriPermission` | | 平台检测 | `.nes` → FC / `.gba` → GBA / `.smc/.sfc` → SFC | | 存储 | `ImportedRomManager`(SharedPreferences + Gson) | --- ## 🎮 虚拟手柄 — 3 种风格 ### 切换方式 模拟器界面左上角控制栏点击 🎮 按钮循环切换,偏好自动持久化。 ### 风格一览 | 风格 | 名称 | 方向操控 | 动作键 | SELECT/START | |:---|:---|:---|:---|:---| | 0 | **经典红白机** | 十字键 136dp(左下,16dp 圆角) | 2×2 圆形 AB 键 68dp(右下) | 底部中央圆角矩形 72×32dp | | 1 | **PS 分体式** | 4 独立圆形方向键菱形排列(左半区) | 2×2 圆形 AB 键 68dp(右下) | 底部中央圆角矩形 | | 2 | **MOBA 摇杆** | 🕹️ 虚拟摇杆,8 方向精确映射,蓝色摇杆头(左下) | 2×2 圆形 AB 键 68dp(右下) | 底部中央圆角矩形 | ### 通用特性 | 特性 | 说明 | |:---|:---| | **半透明背景** | 所有按钮半透明黑底 `#80000000`,按下加深 `#B3000000` | | **按下反馈** | 文字/箭头变为蓝色 `#4A90E2` | | **触控区域** | 比视觉区域大 20%,防误触 | | **多点触控** | 支持同时按方向 + AB + SELECT/START | | **偏好保存** | 选择后自动保存,下次进入恢复 | | **透明度调节** | SeekBar 滑块 30%-100%,设置弹窗半透明可透视游戏 | | **震动反馈** | 按下按钮 10ms 短震动(VibrationEffect API) | | **自定义布局** | 点击"手柄自定义"进入编辑模式,拖拽按钮移动 + 双指缩放大小,💾保存 ✕取消 | | **恢复默认** | 一键恢复手柄布局 + 透明度 + 速度 + 风格到初始状态 | | **物理键盘** | 外接键盘:X→A, Z→B, 方向键, Enter→START, Shift→SELECT | | **按钮描边** | 所有按钮 1.5px 白色半透明边框,与摇杆边缘风格统一 | | **D-Pad 长条** | 经典风格方向键改为分离长条形,中心 10% 十字间隙 | | **设置自动暂停** | 打开 ⚙️ 菜单自动暂停游戏(模拟 START),关闭菜单恢复 | | **毛玻璃弹窗** | 设置菜单 24dp 圆角 + 27% 不透明度 + Android 12+ 硬件模糊 | ### MOBA 摇杆详解 | 特性 | 实现 | |:---|:---| | **底座** | 圆形半透明区域(外圈 + 填充),清晰可见 | | **摇杆头** | 蓝色圆形按钮(默认 `#CC4A90E2`,激活 `#FF4A90E2`) | | **拖动** | 手指拖动摇杆头跟随,限位在底座半径 70% 内 | | **死区** | 中心 20% 半径内不触发,防止抖动 | | **方向** | 8 方向精确映射(上/下/左/右/左上/右上/左下/右下) | | **对角处理** | 同时对两个方向键发送 KeyEvent(如 右上 = UP + RIGHT) | | **回中** | 松手自动回到中心并释放所有按键 | --- ## 🎨 色彩系统 | 用途 | 色值 | |:---|:---| | 背景 | `#F0F4F8` | | 卡片 | `#FFFFFF` | | 主强调(蓝色) | `#4A90E2` | | 次强调(浅蓝) | `#E3F2FD` | | 主文字 | `#1A1A1A` | | 次文字 | `#666666` | | 辅助文字 | `#999999` | | 图标容器 | `#F5F7FA` | | 成功/已下载 | `#4CAF50` | | 今日免费标签 | 底 `#E3F2FD` + 字 `#1976D2` | | 会员标签 | 底 `#F3E5F5` + 字 `#7B1FA2` | | 免费标签 | 底 `#E8F5E9` + 字 `#388E3C` | --- ## 🧪 单元测试 项目包含 **185 个单元测试**(JUnit 4 + 内存 SharedPreferences),覆盖管理器/工具/模型/模拟器核心逻辑。路径:`app/src/test/` ```bash ./gradlew testDebugUnitTest ``` --- ## 🔧 构建与运行 ```bash # 构建 Debug APK ./gradlew assembleDebug # 构建 Release APK ./gradlew assembleRelease # APK 输出路径 # app/build/outputs/apk/debug/app-debug.apk # app/build/outputs/apk/release/app-release.apk ``` --- ## 📌 注意事项 1. **支付 SDK**:华为/小米 IAP SDK 尚未接入,当前为模拟支付实现 2. **ROM 版权**:App 不内置 ROM 文件,用户需自行导入合法 ROM 3. **存储权限**:Android 11+ 需 MANAGE_EXTERNAL_STORAGE 权限管理 ROM 文件 4. **应用签名**:上架应用市场前需生成 Release Key 5. **J2ME/JAR 支持**:Libretro 不支持 Java JAR 格式游戏,需额外集成 FreeJ2ME 等独立引擎 --- ## 📄 许可证 本项目为教学演示用途。游戏 ROM 版权归各自版权方所有。 --- *文档版本:v3.22 | 最后更新:2026-07-09*