跳转到内容

Cocos Creator 快速上手

FRVR 提供 Cocos Creator 扩展 —— 一个安装到 Cocos Creator 扩展管理器里的 .zip 包,把 SDK 通过 FRVRSDK.instance.* 暴露给你的 TypeScript 游戏脚本。

本快速上手讲的是 Cocos Creator 3.x 扩展(frvr-sdk-cocos-3.x.zip),适用于 Cocos Creator 3.8.0 及以上版本,构建目标为 web-mobileweb-desktop。如果你用的是 Cocos Creator 2.4.x,请改下载 frvr-sdk-cocos-2.4.zip —— 该包自带 README,下面的安装步骤和 API 都不适用。

FRVR 的发布流水线会接管 Web 构建产物,按平台(Facebook Instant、iOS WebView、Android TWA 等)分别打包。

下载页 下载 frvr-sdk-cocos-3.x.zip

  1. frvr-sdk/ 目录解压到工程的 extensions/ 目录下。
  2. 在 Cocos Creator 中:Extension → Extension Manager → 启用 frvr-sdk
  3. 运行时脚本会自动安装到 assets/frvr-sdk/
  • 第一个场景里必须有一个挂载了 FRVRSDK 组件的节点,否则 SDK 不会初始化。
  • 构建平台必须是 web-mobile(或 web-desktop)。Cocos 的原生 / 移动端导出不受支持。
import { FRVRSDK, AdShowResult } from './frvr-sdk/FRVRSDK';

如果在 Inspector 里给 FRVRSDK 组件勾选了 autoInit,初始化会自动完成。否则:

await FRVRSDK.instance.initSDK();

if (FRVRSDK.instance.isReady) {
  // 此时可安全调用任何 FRVRSDK.instance.* 方法
}

组件也会替你处理加载进度(autoTrackLoading),但你也可以手动驱动:

FRVRSDK.instance.setLoadingProgress(0.5);
// …
FRVRSDK.instance.completeLoading();

所有调用都走单例 FRVRSDK.instance

if (FRVRSDK.instance.isRewardedReady()) {
  const result = await FRVRSDK.instance.showRewarded();
  if (result === AdShowResult.COMPLETED) giveReward();
}

if (FRVRSDK.instance.isInterstitialReady()) {
  await FRVRSDK.instance.showInterstitial();
}
FRVRSDK.instance.levelStart('level_1');
FRVRSDK.instance.levelEnd('level_1');

两者形态一致 —— 出于性能考虑优先使用批量 API:

await FRVRSDK.instance.localStorageSetItem('coins', 100);
const coins = await FRVRSDK.instance.localStorageGetItem('coins');
await FRVRSDK.instance.localStorageRemoveItem('coins');

await FRVRSDK.instance.localStorageSetItems([
  { key: 'score', value: 4200 },
  { key: 'level', value: 5 },
]);
const batch = await FRVRSDK.instance.localStorageGetItems(['score', 'level']);

云端版本:cloudStorageSetItemcloudStorageGetItemcloudStorageRemoveItemcloudStorageSetItemscloudStorageGetItemscloudStorageRemoveItems。调用签名完全一致。

const id    = await FRVRSDK.instance.getPlayerId();
const name  = await FRVRSDK.instance.getPlayerName();
const photo = await FRVRSDK.instance.getPlayerImage();
const png   = await FRVRSDK.instance.loadPlayerImage(photo); // base64 data URL

在 Facebook Instant 上,由于 Meta 的零权限模型,namephoto 可能是 undefined —— 该场景下使用 Shield 覆盖层 来渲染玩家信息。

if (FRVRSDK.instance.isSocialAPISupported('shareMessage')) {
  await FRVRSDK.instance.shareMessage({
    text:     'I hit 10,000!',
    headline: 'High Score',
    cta:      'Play Now',
  });
}

await FRVRSDK.instance.inviteUsers({
  text:     'Join me!',
  headline: 'Game Invite',
});

// FRVR 好友
await FRVRSDK.instance.syncFriends();
const friends = await FRVRSDK.instance.getAllFriends();
await FRVRSDK.instance.addFriend(friendId);
import { SocialEvent } from './frvr-sdk/FRVRSDK';

FRVRSDK.instance.socialLiveConnect();

FRVRSDK.instance.socialLiveOn(SocialEvent.ON_FRIEND_STATUS_UPDATED, e => /* … */);
FRVRSDK.instance.socialLiveOn(SocialEvent.ON_GAME_INVITE,           e => /* … */);

FRVRSDK.instance.socialLiveSendGameInvite(userId, lobbyId, { level: 1 });
FRVRSDK.instance.socialLiveUpdateStatus({ level: 1 });

// 之后
FRVRSDK.instance.socialLiveClose();
const id = await FRVRSDK.instance.createTournament(
  { gameMode: 'classic' },
  {
    title:     'Weekly Challenge',
    sortOrder: 'HIGHER_IS_BETTER',
    endTime:   Date.now() + 7 * 24 * 3600 * 1000,
  }
);
await FRVRSDK.instance.postTournamentScore(id, 1000);

if (FRVRSDK.instance.isPlatformTournamentsSupported()) {
  const current = await FRVRSDK.instance.getCurrentPlatformTournament();
}
if (!FRVRSDK.instance.isIAPReady()) return;

const catalog = FRVRSDK.instance.getIAPCatalog();
const product = FRVRSDK.instance.getIAPProduct('coins_100');

const purchase = await FRVRSDK.instance.purchase('coins_100', { meta: 'shop_click' });
if (purchase) {
  grantItem(purchase.productId);
  await FRVRSDK.instance.consumePurchase(purchase);
}

// 启动时回收购买中崩溃留下的未消耗订单
const unconsumed = await FRVRSDK.instance.getUnconsumedPurchases();
for (const p of unconsumed) {
  grantItem(p.productId);
  await FRVRSDK.instance.consumePurchase(p);
}
if (await FRVRSDK.instance.canScheduleNotifications()) {
  await FRVRSDK.instance.subscribeNotifications();

  await FRVRSDK.instance.scheduleNotification({
    playerId:       await FRVRSDK.instance.getPlayerId(),
    delayInSeconds: 86400,
    imageUrl:       'https://cdn.mygame.com/push.png',
    message:        'Come back and play!',
    buttonTitle:    'Play Now',
  });
}
if (await FRVRSDK.instance.canCreateShortcut()) {
  await FRVRSDK.instance.createShortcut();
}

if (await FRVRSDK.instance.canMoveToMobile()) {
  await FRVRSDK.instance.moveToMobile();
}
const data = await FRVRSDK.instance.getEntrypointData();
const name = await FRVRSDK.instance.getEntrypointName();

if (data?.level) goToLevel(data.level);
if (FRVRSDK.instance.allowsExternalLinks()) openPrivacyPolicy();
if (FRVRSDK.instance.allowsNavigation())    pushLocation();

web-mobile(或 web-desktop)构建。扩展会在 dev 环境自动把 FRVR SDK 脚本注入到 index.html。生产环境的按平台打包由 FRVR 的发布流水线处理 —— 你不用挑选渠道包。