📌 摘要

很多开发者用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               # 入口,动态选择适配器

🔁 发布步骤

  1. 开发阶段:使用h5Adapter在浏览器调试,热重载快

  2. 测试微信端:用微信开发者工具打开dist目录,自动注入wechatAdapter

  3. 测试抖音端:同理替换douyinAdapter

  4. 打包App:将H5构建产物放入Cordova/WebView容器,使用appAdapter桥接原生能力

AI辅助:将以上架构描述给Claude或ChatGPT,要求“按此目录结构生成所有接口和模板代码”,10分钟得到完整脚手架。


五、3个最容易踩的坑

⚠️ 坑1:在核心逻辑里直接调用wxlocalStorage

// ❌ 错误
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层 渲染 + 输入 无平台特定代码

你现在就可以做的事

  1. 在你的TS项目中创建platform.interface.ts,至少先定义IStorageIShare

  2. 将现有游戏代码中的所有wx.setStoragelocalStorage替换为adapter.storage.set

  3. 让AI根据微信小程序API文档自动生成wechat.adapter.ts中缺失的方法实现

  4. 运行一次H5和微信开发者工具,确保同一份核心代码两端行为一致

最终效果:以后新增一个平台(如快手小游戏),你只需要写一个新的适配器,游戏核心逻辑一行不改。这才是AI时代工程化的正确姿势。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐