> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cocos2D-x 快速入门

> 在 Windows 上的 Visual Studio 中设置 Cocos2d-x 项目，并使用 PlayFab Cocos2d-x 客户端库进行首次 PlayFab API 调用。

本快速入门可帮助你在 Cocos2d-x 引擎中进行首次 PlayFab API 调用。

在调用任何 PlayFab API 之前，你必须拥有一个 [PlayFab 开发者帐户](https://developer.playfab.com)。

## Cocos2d-x 项目设置

操作系统：本指南针对 Windows 10 编写，使用 Visual Studio 2015。Cocos 可在大多数现代操作系统和环境中运行。安装说明相似，但每种组合各有不同。

如果你在为其他平台构建，所需文件相同，但你需要自行完成项目设置。Visual Studio 2013 的步骤相同，但此处提供的屏幕截图看起来可能与你的略有不同。

1. 下载并安装 Cocos2d-x
   * [https://www.cocos2d-x.org/download](https://www.cocos2d-x.org/download)
   * 设置 Cocos2d-x 需要一定的熟悉度。请查看其文档站点：
     * [https://docs.cocos2d-x.org/cocos2d-x/en/en/](https://docs.cocos2d-x.org/cocos2d-x/v3/en/)
     * 注意 [Cocos 先决条件](https://docs.cocos2d-x.org/cocos2d-x/v3/en/installation/prerequisites.html)
     * 还需要 Visual Studio 2013 或 2015。

2. 配置好 Cocos2d-x 后，使用 Cocos CLI 创建项目：
   * 导航到你希望存储 Cocos 项目的位置

   * 在父文件夹中打开命令窗口（Cocos CLI 将创建实际的项目目录）
     * 按住 **Shift** 键，在资源管理器窗口的空白处右键单击。

       <img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/cocos2d-x/cmd-exe2.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=2aaffd549547102d237a6f33a56e7187" alt="Cocos CLI - 打开命令窗口" width="615" height="453" data-path="images/playfab/sdks/cocos2d-x/cmd-exe2.png" />

   * 在新的控制台窗口中输入以下命令：
     * `cocos new CocosGettingStarted -l cpp`
       * 请确保目标子目录（**CocosGettingStarted**）尚不存在——如果该文件夹已存在，此命令将失败。
       * 如果收到消息 "'cocos' isn't recognized as an internal or external command"，说明你未正确配置 cocos 安装（请返回 Cocos Windows 安装指南）。
       * 如果成功，将会有一个新文件夹 **CocosGettingStarted**。本指南将该目录位置称为 `{CocosGettingStarted}`。

   * 成功输出应类似于下面提供的示例。

```output theme={null}
> Copy template into C:\dev\CocosGettingStarted
> Copying Cocos2d-x files...
> Rename project name from 'HelloCpp' to 'CocosGettingStarted'
> Replace the project name from 'HelloCpp' to 'CocosGettingStarted'
> Replace the project package name from 'org.cocos2dx.hellocpp' to 'org.cocos2dx.CocosGettingStarted'
> Replace the Mac bundle id from 'org.cocos2dx.hellocpp' to 'org.cocos2dx.CocosGettingStarted'
> Replace the iOS bundle id from 'org.cocos2dx.hellocpp' to 'org.cocos2dx.CocosGettingStarted'
```

3. 下载 PlayFab Cocos2d-xSdk：[Cocos2D-x SDK (C++)](https://aka.ms/playfabCsharpsdkdownload)。保存并解压到临时位置 \{PlayFabCocos}
   * 在 Windows 资源管理器中打开以下文件夹：\{PlayFabCocos}/PlayFabClientSDK
   * 在另一个 Windows 资源管理器中打开以下文件夹：\{CocosGettingStarted}/Classes

4. 将 \{PlayFabCocos}/PlayFabClientSDK 中的所有文件复制粘贴到 \{CocosGettingStarted}/Classes

5. 在 Visual Studio 中，加载 `{CocosGettingStarted}/proj.win32/CocosGettingStarted.sln`。

6. 我们希望将 PlayFab 文件添加到 Cocos 项目中。

7. 在 Visual Studio 的解决方案资源管理器面板中，展开到以下文件夹：Solution/CocosGettingStarted/src

8. 在 \{CocosGettingStarted}/Classes 处打开一个 Windows 资源管理器窗口

   * 选择 \{CocosGettingStarted}/Classes 中的所有文件，但不包括 AppDelegate.h、AppDelegate.cpp、HelloWorldScene.h、HelloWorldScene.cpp

   * 将所有这些文件从资源管理器拖放到上面找到的 Visual Studio Solution/CocosGettingStarted/src 文件夹中。如果遇到问题，可以一次拖放一个文件，*但请务必小心并将它们全部拖过去*。

   * 你应该能在 VS 项目中看到这些文件：

     <img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/cocos2d-x/sln-src.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=7e227ca9d1a183f183db018209757770" alt="解决方案资源管理器 - VS 项目文件" width="317" height="580" data-path="images/playfab/sdks/cocos2d-x/sln-src.png" />

PlayFab 使用了几个 Cocos 库，必须手动添加到依赖项列表中。

* 打开 CocosGettingStarted 项目的 **属性** 窗口（如下所示）。

  <img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/cocos2d-x/cocos-include.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=69b2d7b8a07f433dfbad2c945b48ed93" alt="属性窗口 - Cocos 包含目录" width="1359" height="1070" data-path="images/playfab/sdks/cocos2d-x/cocos-include.png" />

* 将附加包含目录替换为以下内容：

  `$(ProjectDir)..\cocos2d\external\zlib\include;$(ProjectDir)..\cocos2d\external\curl\include\win32;$(EngineRoot)cocos\audio\include;$(EngineRoot)external;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)extensions;..\Classes;..;%(AdditionalIncludeDirectories);$(_COCOS_HEADER_WIN32_BEGIN);$(_COCOS_HEADER_WIN32_END);..\cocos2d`

<Note>
  我们添加的是 curl 和 zlib，它们是 Cocos 附带的库，但默认未启用。
</Note>

你的 CocosGettingStarted 项目现在应该可以编译（甚至可以运行），但我们还没有进行任何 PlayFab API 调用。

安装完成！

## 设置你的第一次 API 调用

本指南提供进行首次 PlayFab API 调用的最低步骤。在应用中可以看到确认信息。

1. 在 Visual Studio 中，在 Solution/CocosGettingStarted/src 文件夹内，打开 HelloWorldScene.h 并将内容替换为以下内容：
   * 在 Visual Studio 中，在 **Solution/CocosGettingStarted/src** 文件夹内，打开 `HelloWorldScene.h`，将其内容替换为下面显示的内容。

```cpp theme={null}
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include "PlayFabClientDataModels.h"
#include "PlayFabError.h"

class HelloWorld : public cocos2d::Layer
{
public:
    static std::string statusMsg;
    static cocos2d::Scene* createScene();
    static cocos2d::Label* testReportLabel;
    virtual bool init();
    void update(float) override;
    void menuCloseCallback(cocos2d::Ref* pSender);
    CREATE_FUNC(HelloWorld);

    static void HelloWorld::OnLoginSuccess(const PlayFab::ClientModels::LoginResult& result, void* customData);
    static void HelloWorld::OnLoginFail(const PlayFab::PlayFabError& error, void* customData);
};

#endif // __HELLOWORLD_SCENE_H__
```

2. 紧接着打开 `HelloWorldScene.cpp`，并将其内容替换为以下内容：

```cpp theme={null}
#include "HelloWorldScene.h"
#include "PlayFabClientAPI.h"
#include <PlayFabSettings.h>

USING_NS_CC;

std::string HelloWorld::statusMsg;
cocos2d::Label* HelloWorld::testReportLabel;

Scene* HelloWorld::createScene()
{
    auto scene = Scene::create(); // 'scene' is an autorelease object
    auto layer = HelloWorld::create(); // 'layer' is an autorelease object
    scene->addChild(layer); // add layer as a child to scene
    return scene; // return the scene
}

bool HelloWorld::init()
{
    if (!Layer::init())
        return false;

    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width / 2, origin.y + closeItem->getContentSize().height / 2));

    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);
    this->scheduleUpdate();

    testReportLabel = Label::createWithTTF("", "fonts/Marker Felt.ttf", 14);
    this->addChild(testReportLabel, 1);

    statusMsg = "Login pending...";
    PlayFab::PlayFabSettings::titleId = "144";
    PlayFab::ClientModels::LoginWithCustomIDRequest request;
    request.CustomId = "GettingStartedGuide";
    request.CreateAccount = true;
    PlayFab::PlayFabClientAPI::LoginWithCustomID(request, OnLoginSuccess, OnLoginFail, nullptr);

    return true;
}

void HelloWorld::menuCloseCallback(Ref* pSender)
{
    Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

void HelloWorld::update(float delta)
{
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    testReportLabel->setPosition(Vec2(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2));
    testReportLabel->setString(statusMsg);
}

void HelloWorld::OnLoginSuccess(const PlayFab::ClientModels::LoginResult& result, void* customData)
{
    statusMsg = "Congratulations, you made your first successful API call!";
}

void HelloWorld::OnLoginFail(const PlayFab::PlayFabError& error, void* customData)
{
    statusMsg = "Something went wrong with your first API call.\n";
    statusMsg += "Here's some debug information:\n";
    statusMsg += error.GenerateErrorReport();
}
```

这些文件采用了作为新 Cocos 项目模板一部分的现有 HelloWorldScene，并对其进行修改以包含你的第一次 PlayFab API 调用。

## 完成并执行

1. 构建并执行你的 Cocos 项目：下拉菜单 -> 调试 -> 开始调试。

2. 这将提示你构建。选择 **是**。

3. 你应该会看到显示以下内容的屏幕：

   **Congratulations, you made your first successful API call!**

4. 现在，你可以开始进行其他 API 调用并构建你的游戏。
   有关所有可用客户端 API 调用的列表，请参阅 [PlayFab API 参考](/services/playfab/api-references) 文档。

祝你编程愉快！

## 代码解构

这个可选的最后一节详细描述了上面源代码的每一部分。

* `HelloWorldScene.h`
  * 这仅在 Cocos 生成的默认 `HelloWorldScene.h` 上做了少量修改。
  * 具体来说，它定义了我们使用的一些 Cocos GUI，以及 `OnLoginSuccess` 和 `OnLoginFail` 的原型。
  * 其他一切都是标准的 Cocos 引擎函数。

* `HelloWorldScene.cpp`
  * `createScene()` 是标准的 Cocos 引擎函数。

  * `init()`
    * 普通的 Cocos GUI 内容：`closeItem` 和 `testReportLabel`。

    * `PlayFab::PlayFabSettings::titleId = "xxxx";`
      * 每个 PlayFab 开发者都会在 Game Manager 中创建一个 title。当你发布游戏时，必须将该 titleId 编入游戏代码中。这样可以让客户端知道如何访问 PlayFab 中的正确数据。对大多数用户而言，只需将其视为使 PlayFab 正常工作的必要步骤即可。

    * `PlayFab::ClientModels::LoginWithCustomIDRequest request;`
      * 大多数 PlayFab API 方法都需要输入参数，这些输入参数被打包到请求对象中。
      * 每个 API 方法都需要一个唯一的请求对象，其中混合了可选和必填参数。
        * 对于 `LoginWithCustomIDRequest`，有一个必填参数 `CustomId`，用于唯一标识玩家；以及 `CreateAccount`，它允许通过此调用创建新帐户。
      * 对于登录，大多数开发者会希望使用更合适的登录方法。
        * 有关所有登录方法和输入参数的列表，请参阅 PlayFab 登录文档。常见选择包括：
          * `LoginWithAndroidDeviceID`
          * `LoginWithIOSDeviceID`
          * `LoginWithEmailAddress`

    * `PlayFab::PlayFabClientAPI::LoginWithCustomID(request, OnLoginSuccess, OnLoginFail, nullptr);`
      * 这将开始对 `LoginWithCustomID` 的异步请求，并在完成时调用 `OnLoginSuccess` 或 `OnLoginFail` 函数。

  * `update(float delta)`
    * 仅设置 `statusMsg` 变量并不会更新屏幕上的文本。
    * 此函数在每个 tick 将 GUI 文本设置为与 `statusMsg` 的内容匹配（效率不高）。

  * `OnLoginSuccess(result, customData)`
    * 当调用成功回调时，许多 API 回调的 result 对象将包含请求的信息。
    * `LoginResult` 包含玩家的一些基本信息，但对大多数用户来说，登录只是调用其他 API 之前的必要步骤。

  * `OnLoginFail(error, customData)`
    * 如果调用了错误函数，则表明你的 API 调用失败。
    * API 调用可能因多种原因失败，你应始终尝试处理失败。
    * API 调用失败的原因（按可能性排序）
      * `PlayFabSettings.TitleId` 未设置。如果你忘记为你的 title 设置 titleId，那么一切都无法正常工作。
        * 在 Cocos 中，如果你未能正确设置 titleId，curl 库可能会直接使游戏崩溃。
      * 请求参数。如果你未为特定 API 调用提供正确或必需的信息，则该调用将失败。有关更多信息，请参阅 `error.errorMessage`、`error.errorDetails` 或 `error.GenerateErrorReport()`。
      * 设备连接问题。手机会不断丢失/恢复连接，因此任何时候的任何 API 调用都可能随机失败，随后又立即成功。进入隧道可能会让你完全断开连接。
      * PlayFab 服务器问题。就像所有软件一样，可能会有问题。请参阅我们的发行说明以获取更新。
      * 互联网并非 100% 可靠。有时消息会损坏或无法到达 PlayFab 服务器。
    * 如果你在调试问题时遇到困难，且错误回调中的信息不够充分，请到我们的论坛与我们联系。

  * customData 是一个 void 指针，可以以任何方式用于建立上下文。
    * 在 C++ 中，维护 API 调用的上下文比较困难，因此我们添加了 `customData` 参数，它可以将任何对象中继到回调，可以按你喜欢的任何方式使用它来建立上下文。
    * 因此，如果你进行 API 调用以检索库存，可以将玩家或库存指针作为 `customData` 传递，并在回调中更新该对象上的库存。


## Related topics

- [PlayFab 支持的游戏引擎](/zh-CN/services/playfab/sdks/game-engines/index.md)
- [Cocos2D-x (C++) SDK](/zh-CN/services/playfab/sdks/cocos2d-x/index.md)
- [Cocos2d-x SDK 许可证](/zh-CN/services/playfab/sdks/cocos2d-x/license.md)
- [快速入门](/zh-CN/services/playfab/economy-monetization/economy-v2/quickstart.md)
- [Android 快速入门](/zh-CN/services/playfab/sdks/c/quickstart-android.md)
