mcpField
C
crazy-games-js-sdk

crazy-games-js-sdk

github.com/hungify开发016 次安装1 周前更新
代码仓库

关于 crazy-games-js-sdk

这是一份面向游戏开发者的 CrazyGames JavaScript SDK 集成技能,涵盖初始化、游戏生命周期钩子、广告、玩家访问、存储及可选的 Xsolla 支付。

主要功能

  1. 01SDK 加载与初始化指南
  2. 02游戏和加载生命周期钩子
  3. 03插屏广告与激励广告流程
  4. 04玩家授权和资料访问
  5. 05键值存储接入
  6. 06可选的 Xsolla 支付流程

适用场景

  1. 01在游戏中接入 CrazyGames SDK
  2. 02将游戏状态映射到生命周期调用
  3. 03展示插屏广告或激励广告
  4. 04使用 SDK 存储玩家数据

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hungify/playables-skills --skill crazy-games-js-sdk

安装后在 Claude Code 中输入/crazy-games-js-sdk确认已加载。

详细介绍

CrazyGames JavaScript SDK

集成清单

将 SDK 集成到游戏时,请按以下顺序操作:

  1. 加载 SDK — 在游戏启动前添加 CDN <script> 标签
  2. 初始化 — 调用 SDK.init(),并等待其完成后再使用任何 SDK 模块
  3. 生命周期钩子 — 在整个游戏循环中接入 loadingStart/Stop 和 gameplayStart/Stop
  4. 广告 — 在合适的间歇点添加插屏广告和/或激励广告调用
  5. 可选:身份验证与存储 — 根据需要添加登录和持久化键值存储
  6. 可选:支付 — 集成 Xsolla Pay Station(单独事项;不适用时可跳过)

安装

在启动游戏前,从官方 CDN 加载 SDK。

<script src="https://sdk.crazygames.com/crazygames-sdk-v3.js"></script>

如果动态加载,请等待 window.CrazyGames.SDK.init 定义后再调用。如果脚本被拦截(例如,被 CSP 拦截),全局变量 window.CrazyGames 将未定义 — 请将 sdk.crazygames.com 添加到 script-src 指令中。

初始化

调用一次 SDK.init()。SDK 就绪后,该调用会完成。只有在完成后,才能安全地使用 SDK.user、SDK.data、SDK.ad、SDK.banner、SDK.game 和 SDK.analytics。

async function initCrazyGames() {
    if (!window.CrazyGames?.SDK) {
        throw new Error('CrazyGames SDK script not loaded');
    }
    const sdk = window.CrazyGames.SDK;
    try {
        await sdk.init();
    } catch (err) {
        throw new Error(`CrazyGames SDK init failed: ${err.message}`);
    }

    const isUserAccountAvailable = sdk.user.isUserAccountAvailable;

    if (isUserAccountAvailable) {
        const language = sdk.user.systemInfo.countryCode.toLowerCase();
        const deviceType = sdk.user.systemInfo.device.type.toLowerCase(); // 'desktop' | 'mobile' | 'tablet'
        console.log('lang/device', language, deviceType);
    }

    return sdk;
}

验证

调用 initCrazyGames() 后,请先确认 SDK 正常工作,再继续操作:

  • 控制台检查 — 不应出现 CrazyGames SDK init failed 错误;调用 sdk.user.isUserAccountAvailable 应返回布尔值,且不抛出异常。
  • 生命周期钩子 — 打开游戏对应的 CrazyGames 沙盒 URL,并确认 loadingStart / loadingStop / gameplayStart / gameplayStop 调用出现在 CrazyGames 开发者仪表板的事件日志中。
  • 广告回调 — 使用 CrazyGames 沙盒环境(在 URL 后附加 ?crazygames_sandbox=1)触发测试广告,并确认 adStarted 和 adFinished 正常触发。
  • 广告拦截检测 — 在启用广告拦截器的情况下运行时调用 sdk.ad.hasAdblock(),并确认其结果为 true。

玩家/授权

使用 showAuthPrompt() 提示玩家登录,然后使用 getUser() 读取个人资料数据;还可以使用 getUserToken() 获取已签名的 JWT,以便在后端验证。

async function authorizePlayer(sdk, { useUserToken = false } = {}) {
    if (!sdk.user.isUserAccountAvailable) {
        // Guest session — no auth possible on this domain
        return null;
    }

    await sdk.user.showAuthPrompt();

    const user = await sdk.user.getUser();
    if (!user) {
        return null;
    }

    const profile = {
        name: user.username || null,
        photo: user.profilePictureUrl || null,
        extra: user
    };

    if (useUserToken) {
        profile.extra.jwt = await sdk.user.getUserToken();
    }

    return profile;
}

存储

CrazyGames 通过 SDK.data 提供同步键值存储。值均为字符串;请自行序列化 JSON。

function storageSet(sdk, key, value) {
    const data = typeof value === 'string' ? value : JSON.stringify(value);
    sdk.data.setItem(key, data);
}

function storageGet(sdk, key, tryParseJson = true) {
    const raw = sdk.data.getItem(key);
    if (!tryParseJson || raw == null) {
        return raw;
    }
    try {
        return JSON.parse(raw);
    } catch (_) {
        return raw;
    }
}

function storageRemove(sdk, key) {
    sdk.data.removeItem(key);
}

// Batch helpers — just iterate, the SDK has no native multi-key API
function storageSetMany(sdk, keys, values) {
    for (let i = 0; i < keys.length; i++) {
        storageSet(sdk, keys[i], values[i]);
    }
}

广告

插屏广告(midgame)

调用 SDK.ad.requestAd('midgame', callbacks)。广告生命周期推进时,会同步触发回调。

function showInterstitial(sdk) {
    sdk.ad.requestAd('midgame', {
        adStarted: () => {
            // Mute audio and pause the game here
        },
        adFinished: () => {
            // Resume audio and gameplay here
        },
        adError: (error) => {
            console.warn('interstitial failed', error);
        }
    });
}
激励广告

使用相同的 API,将 'rewarded' 作为类型传入。adFinished 表示用户已完整观看广告,应向其发放奖励。

function showRewarded(sdk, onReward) {
    sdk.ad.requestAd('rewarded', {
        adStarted: () => {
            // Pause the game
        },
        adFinished: () => {
            onReward();
        },
        adError: (error) => {
            console.warn('rewarded failed', error);
        }
    });
}
广告拦截检测
async function isAdblockActive(sdk) {
    return sdk.ad.hasAdblock();
}
自适应横幅广告

横幅广告会绑定到具有指定 id 的现有 DOM 容器。CrazyGames 会在容器中渲染广告,并选择合适的尺寸。

async function showBanner(sdk, containerId) {
    // The container must already be in the DOM and visible
    try {
        await sdk.banner.requestResponsiveBanner([containerId]);
    } catch (e) {
        console.warn('banner failed', e);
    }
}

async function showAdvancedBanners(sdk, containerIds) {
    // Request several banners in parallel
    await Promise.all(containerIds.map((id) => sdk.banner.requestResponsiveBanner(id)));
}

function hideBanners(sdk) {
    sdk.banner.clearAllBanners();
}

生命周期/游戏事件

CrazyGames 要求宿主游戏在正确的时机调用游戏和加载钩子 — 这些钩子会影响广告投放节奏、游戏内 UI 遮罩效果和分析数据。

请按以下方式将通用游戏生命周期事件映射到 SDK 调用:

游戏事件SDK 调用
level_started、level_resumed、gameplay_startedsdk.game.gameplayStart()
level_paused、level_completed、level_failed、gameplay_stoppedsdk.game.gameplayStop()
in_game_loading_startedsdk.game.loadingStart()
in_game_loading_stoppedsdk.game.loadingStop()
player_got_achievementsdk.game.happytime()

CrazyGames SDK 没有单独的 audio / pause / visibility 回调 — 请通过广告回调(adStarted / adFinished)和标准的 document.visibilitychange 事件控制音频和暂停状态。

支付(可选,通过 Xsolla Pay Station)

如果你没有 Xsolla 项目 ID,请完全跳过本节。 CrazyGames 本身不销售 IAP;此集成会将 CrazyGames 签发的 Xsolla 用户令牌与 Xsolla Pay Station 小组件和 Xsolla Store API 搭配使用。

关键常量:

const XSOLLA_PAYSTATION_EMBED_URL =
    'https://cdn.xsolla.net/payments-bucket-prod/embed/1.5.0/widget.min.js';
const XSOLLA_SDK_URL = 'https://store.xsolla.com/api/v2/project';

通过 sdk.user.getXsollaUserToken() 获取 Xsolla 用户令牌。将其用作所有 Xsolla Store API 请求的 Bearer 令牌(目录、购买、库存、消耗)。

目录 — GET /{projectId}/items?limit=50

购买流程:

  1. POST /{projectId}/payment/item/{sku} → 返回 { token, order_id }
  2. 如果尚未加载 XSOLLA_PAYSTATION_EMBED_URL,则动态加载
  3. 调用 XPayStationWidget.init({ access_token: token, sandbox: isSandbox }),然后调用 .open()
  4. 监听 XPayStationWidget.eventTypes.STATUS;当 paymentInfo.status 匹配 /done|charged|success/i 时,获取 GET /{projectId}/order/{orderId},并调用 sdk.analytics.trackOrder('xsolla', order) 记录购买
  5. 监听 'close' 事件以处理取消操作

库存 — GET /{projectId}/user/inventory/items

消耗 — 使用 { sku, quantity } 调用 POST /{projectId}/user/inventory/item/consume

所有 fetch 调用都必须包含 Authorization: Bearer <xsollaToken>。非 OK 响应时抛出错误。开发期间使用 isSandbox: true。

评论

支持 Markdown