TS实现“核心-适配”分离,轻松适配任何小游戏平台
📌 摘要
很多开发者用AI生成的游戏TypeScript代码,看似能用,实则平台逻辑与游戏规则高度耦合:换一个发布渠道(微信小程序 → 抖音小游戏 → H5 → 安卓App),就得重写一半代码。
本文提供一套基于TypeScript的清晰分层架构,利用TS的接口、泛型、抽象类,将平台无关的核心逻辑与平台相关的适配层彻底分离。并给出可直接复用的代码模板,让你一套代码优雅运行在任意端。
📑 目录
-
为什么选择TypeScript?
-
核心架构:四层分离模型
-
实战:用TS接口定义平台适配层
-
跨平台发布工作流
-
3个最容易踩的坑
-
总结与行动清单
一、为什么选择TypeScript?
| 特性 | 对跨平台架构的价值 |
|---|---|
| 接口(interface) | 强制定义平台适配器的契约,换平台只需实现同一接口 |
| 泛型(generic) | 让数据存储、网络请求等模块复用不同平台的返回类型 |
| 抽象类 | 提取公共逻辑(如重试机制、缓存策略),子类只实现平台特化部分 |
| 编译时检查 | 避免运行时才发现“微信有wx.request而抖音是tt.request”这类错误 |
👉 一句话:TS让“架构约束”变成代码,而不是靠开发者的记忆。
二、核心架构:四层分离模型
text
┌─────────────────────────────────────────┐ │ 表现层(UI / 渲染引擎) │ ← 使用Pixi.js/Cocos,与平台无关 ├─────────────────────────────────────────┤ │ 游戏核心逻辑层(纯TS) │ ← 合成规则、数值计算、状态机(无任何平台API) ├─────────────────────────────────────────┤ │ 平台适配器接口层(抽象层) │ ← 定义 Storage, Network, Share, Payment 等接口 ├─────────────────────────────────────────┤ │ 平台具体实现(微信 / 抖音 / H5 / RN) │ ← 每个平台一个文件,实现上述接口 └─────────────────────────────────────────┘
依赖方向:外层依赖内层,内层绝不依赖外层。
换平台时:仅替换最底层的实现文件,游戏核心逻辑和UI零修改。
三、实战:用TS接口定义平台适配层
3.1 定义核心接口(platform.interface.ts)
// 存储接口
export interface IStorage {
set(key: string, value: any): Promise<void>;
get<T>(key: string): Promise<T | null>;
}
// 网络请求接口
export interface IHttpClient {
get<T>(url: string, options?: any): Promise<T>;
post<T>(url: string, data: any): Promise<T>;
}
// 分享接口
export interface IShare {
share(options: { title: string; imageUrl?: string; query?: string }): Promise<void>;
}
// 支付接口
export interface IPayment {
requestPayment(params: { goodsId: string; price: number }): Promise<boolean>;
}
// 平台整体适配器
export interface IPlatformAdapter {
storage: IStorage;
http: IHttpClient;
share: IShare;
payment: IPayment;
getPlatformType(): 'wechat' | 'douyin' | 'h5' | 'app';
}
3.2 游戏核心逻辑依赖接口,不依赖具体实现
// GameCore.ts —— 平台无关的合成规则
import { IPlatformAdapter } from './platform.interface';
export class GameCore {
private adapter: IPlatformAdapter;
constructor(adapter: IPlatformAdapter) {
this.adapter = adapter;
}
async saveScore(score: number) {
// 使用适配器的存储,完全不知道底层是wx.setStorage还是localStorage
await this.adapter.storage.set('highScore', score);
}
async shareVictory() {
await this.adapter.share.share({ title: '我合成了传说装备!' });
}
}
3.3 为微信小程序实现具体适配器
// wechat.adapter.ts
import { IPlatformAdapter, IStorage, IHttpClient, IShare, IPayment } from './platform.interface';
class WechatStorage implements IStorage {
async set(key: string, value: any): Promise<void> {
return new Promise((resolve, reject) => {
wx.setStorage({ key, data: value, success: resolve, fail: reject });
});
}
async get<T>(key: string): Promise<T | null> {
return new Promise((resolve) => {
wx.getStorage({ key, success: (res) => resolve(res.data as T), fail: () => resolve(null) });
});
}
}
// ... 同样实现 WechatHttp, WechatShare, WechatPayment
export const wechatAdapter: IPlatformAdapter = {
storage: new WechatStorage(),
http: new WechatHttp(),
share: new WechatShare(),
payment: new WechatPayment(),
getPlatformType: () => 'wechat',
};
3.4 入口动态加载对应适配器
// main.ts
import { GameCore } from './GameCore';
import { wechatAdapter } from './wechat.adapter';
import { douyinAdapter } from './douyin.adapter';
import { h5Adapter } from './h5.adapter';
// 根据运行环境选择适配器
let adapter;
if (typeof wx !== 'undefined' && wx.getSystemInfo) {
adapter = wechatAdapter;
} else if (typeof tt !== 'undefined') {
adapter = douyinAdapter;
} else {
adapter = h5Adapter;
}
const game = new GameCore(adapter);
game.start();
四、跨平台发布工作流
✅ 目录结构建议
src/ ├── core/ # 纯TS游戏逻辑(无任何平台API) │ ├── GameRules.ts │ ├── Entity/ │ └── StateMachine/ ├── platform/ # 平台适配层 │ ├── interface.ts │ ├── wechat/ │ ├── douyin/ │ ├── h5/ │ └── app/ # React Native / Flutter 桥接 ├── ui/ # 渲染相关(Pixi.js等,平台无关) └── main.ts # 入口,动态选择适配器
🔁 发布步骤
-
开发阶段:使用
h5Adapter在浏览器调试,热重载快 -
测试微信端:用微信开发者工具打开
dist目录,自动注入wechatAdapter -
测试抖音端:同理替换
douyinAdapter -
打包App:将H5构建产物放入Cordova/WebView容器,使用
appAdapter桥接原生能力
AI辅助:将以上架构描述给Claude或ChatGPT,要求“按此目录结构生成所有接口和模板代码”,10分钟得到完整脚手架。
五、3个最容易踩的坑
⚠️ 坑1:在核心逻辑里直接调用wx或localStorage
// ❌ 错误
if (wx) { wx.setStorageSync('key', value); }
// ✅ 正确
this.adapter.storage.set('key', value);
解决方案:在.eslintrc中禁止全局平台对象,或使用TS的declare隔离。
⚠️ 坑2:平台特性差异不止API,还有交互习惯
微信小程序分享必须用户点按钮触发,抖音支持自动调起。适配器接口IShare.share()在不同平台内部的触发时机不同,不要让核心逻辑假设调用即成功。使用Promise + 超时兜底。
⚠️ 坑3:包体积和各平台限制
微信小程序主包限制2MB,如果TS编译后加上多个适配器可能超标。解决方案:按平台分包加载适配器,AI可以自动生成分包配置文件。
六、总结与行动清单
| 层级 | 责任 | TS技术 |
|---|---|---|
| 核心逻辑 | 纯粹的游戏规则 | 普通类、函数 |
| 适配器接口 | 定义平台契约 | interface |
| 平台实现 | 调用真实API | 实现类 + 环境判断 |
| UI层 | 渲染 + 输入 | 无平台特定代码 |
你现在就可以做的事:
-
在你的TS项目中创建
platform.interface.ts,至少先定义IStorage和IShare -
将现有游戏代码中的所有
wx.setStorage、localStorage替换为adapter.storage.set -
让AI根据微信小程序API文档自动生成
wechat.adapter.ts中缺失的方法实现 -
运行一次H5和微信开发者工具,确保同一份核心代码两端行为一致
最终效果:以后新增一个平台(如快手小游戏),你只需要写一个新的适配器,游戏核心逻辑一行不改。这才是AI时代工程化的正确姿势。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)