Cocos2D-x 快速入门

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

必须有 PlayFab 开发者帐户才能调用 PlayFab API。

Cocos2d-x 项目设置

操作系统:本指南适用于 Windows 10(使用 Visual Studio 2015)。 Cocos 适用于大多数新式 OS 和环境。 安装说明类似,但每种组合都有所不同。

如果要为其他平台构建,则所需的文件是相同的,但需要自行进行项目设置。 Visual Studio 2013将具有相同的步骤,但此处提供的屏幕截图看起来与你略有不同。

  1. 下载并安装 Cocos2d-x

  2. 配置 Cocos2d-x 后,使用 Cocos CLI 创建项目:

    • 导航到要在其中存储 Cocos 项目的位置

    • 在父文件夹中打开命令窗口(Cocos CLI 将创建实际的项目目录)

      • 按住 Shift 键,然后右键单击资源管理器窗口的空白区域。

        Cocos CLI - 打开命令窗口

    • 在新的控制台窗口中,输入以下命令:

      • cocos new CocosGettingStarted -l cpp
        • 请确保目标子目录(CocosGettingStarted)不存在 - 如果文件夹已存在,此命令将失败。
        • 如果收到消息"'cocos'未识别为内部或外部命令",则未正确配置 Cocos 安装(返回到 Cocos Windows 安装指南)。
        • 如果成功,将有一个新的文件夹 CocosGettingStarted。 本指南将此目录位置称为 {CocosGettingStarted}
    • 成功的输出应类似于下面提供的示例。

> 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'
  1. 下载 PlayFab Cocos2d-xSdk: Cocos2D-x SDK ( C++ )。 保存并将其提取到临时位置 {PlayFabCocos}

    • 在Windows 资源管理器中打开以下文件夹: {PlayFabCocos}/PlayFabClientSDK
    • 在第二个Windows 资源管理器中打开以下文件夹: {CocosGettingStarted}/Classes
  2. 将所有文件从 {PlayFabCocos}/PlayFabClientSDK 复制到 {CocosGettingStarted}/Classes

  3. 在 Visual Studio 中,加载 {CocosGettingStarted}/proj.win32/CocosGettingStarted.sln

  4. 我们需要将 PlayFab 文件添加到 Cocos 项目中。

  5. 在Visual Studio解决方案资源管理器面板中,展开到"Solution/CocosGettingStarted/src"文件夹

  6. 在 {CocosGettingStarted}/Classes 打开Windows 资源管理器窗口

    • 选择 {CocosGettingStarted}/Classes 中的所有文件,AppDelegate.h、AppDelegate.cpp、HelloWorldScene.h、HelloWorldScene.cpp 除外

    • 将所有这些文件从资源管理器拖放到上面找到的 Visual Studio Solution/CocosGettingStarted/src 文件夹上。 如果遇到问题,您可以一次拖放一个文件, 请小心并获取所有文件

    • VS 项目中应会显示以下文件:

      解决方案资源管理器 - VS 项目文件

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

  • 打开 CocosGettingStarted 项目的属性窗口(如下所示)。

    属性窗口 - Cocos 包括目录

  • 将“附加包含目录”替换为:

    $(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

注意

我们正在添加 curl 和 zlib,它们是 Cocos 附带但默认未启用的库。

您的 CocosGettingStarted 项目现在应该能够正常编译(甚至运行),但我们还未进行任何 PlayFab API 调用。

安装完成!

设置首次 API 调用

本指南提供进行首次 PlayFab API 调用的最小步骤。 确认在应用程序中是可见的。

  1. 在 Visual Studio 中,在 Solution/CocosGettingStarted/src 文件夹中,打开 HelloWorldScene.h 并将内容替换为以下内容:
    • 在 Visual Studio 中的 Solution/CocosGettingStarted/src 文件夹中,打开 HelloWorldScene.h 并将内容替换为下面显示的内容。
#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__
  1. 紧接着打开 HelloWorldScene.cpp,并将内容替换为:
#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();
}

这些文件是在现有 HelloWorldScene(new-Cocos-project 模板的一部分)的基础上修改的,以包含您的第一个 PlayFab API 调用。

完成并执行

  1. 生成和执行 Cocos 项目:下拉列表 -> 调试 -> 开始调试。

  2. 可能会提示您进行构建。 选择“”。

  3. 您可以看到显示以下内容的屏幕:

    Congratulations, you made your first successful API call!

  4. 现在,可以开始进行其他 API 调用并构建游戏。
    有关所有可用客户端 API 调用的列表,请参阅我们的 PlayFab API 引用文档。

编码愉快!

解析此代码

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

  • HelloWorldScene.h

    • 此文件仅在 Cocos 生成的默认 HelloWorldScene.h 的基础上进行了简单的修改。
    • 具体来说,它定义了我们使用的一些 Cocos GUI,以及 OnLoginSuccessOnLoginFail 的原型。
    • 其他都只是标准的 Cocos 引擎函数。
  • HelloWorldScene.cpp

    • createScene() 是标准 Cocos Engine 函数。

    • init()

      • 常用的 Cocos Gui 元素:closeItemtestReportLabel

      • PlayFab::PlayFabSettings::titleId = "xxxx";

        • 每个 PlayFab 开发者都在游戏管理器中创建游戏。 发布游戏时,必须将 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 的异步请求,并在完成时调用 OnLoginSuccessOnLoginFail 函数。
    • update(float delta)

      • 简单地将 statusMsg 变量设置为不更新屏幕文本。
      • 此函数设置 GUI 文本在每个时钟周期匹配 statusMsg 的内容(效率不高)。
    • OnLoginSuccess(result, customData)

      • 调用成功回调时,许多 API 回调的结果对象将包含所请求的信息。
      • LoginResult 包含有关玩家的一些基本信息,但对于大多数用户而言,登录只是在调用其他 API 之前的必要步骤。
    • OnLoginFail(error, customData)

      • 如果调用了错误函数,则 API 调用失败。
      • API 调用可能由于多种原因而失败,应始终尝试处理失败。
      • 为什么 API 调用失败(按可能性顺序)
        • 未设置 PlayFabSettings.TitleId。 如果忘记将 titleId 设置为游戏,则不会进行任何操作。
          • 在 Cocos 中,如果未正确设置 titleId,curl 库很可能会使游戏崩溃。
        • 请求参数。 如果未为特定 API 调用提供正确或必需的信息,则调用将失败。 有关详细信息,请参阅 error.errorMessageerror.errorDetailserror.GenerateErrorReport()
        • 设备连接问题。 手机不断失去/恢复连接,因此在任何时候任何 API 调用都可能随机失败,然后立即恢复运行。 进入隧道将完全断开连接。
        • PlayFab 服务器问题。 与所有软件一样,可能存在问题。 有关更新,请参阅我们的发行说明。
        • 互联网并非 100% 可靠。 有时消息已受损或无法到达 PlayFab 服务器。
      • 如果在调试问题时遇到困难,并且错误回调中的信息不充分,请访问我们的论坛。
    • customData 是一个 void 指针,可以以任何方式使用来建立上下文。

      • 在 C++ 中,维护 API 调用的上下文更加困难,因此我们添加了 customData 参数,此参数可将任意对象中继到回调,您可以以任何所需方式使用它来建立上下文。
      • 因此,如果通过 API 调用来检索物品栏,可以将玩家或物品栏指针作为 customData 传递,并在回调中更新此对象的物品栏。