Overview

概述 阅读本文档,您可以了解如何使用Cocos2d运行库。该运行库使用C++和Objective-C语言。我们将通过一个示例来说明如何加载导出的JSON文件并在场景中进行播放。

请注意,因同时使用C++Objective-C,调用该运行库的文件扩展名应为**.mm。您只需将.m文件重命名为.mm**即可。

获取运行库

您可以直接从Creature游戏运行库窗口下载运行库,或点击 这里从版本库获取运行库。

所含标头

应包括以下标头:

#include "CreatureModule.h"
#import "CCreatureRender.h"

加载和初始化

假设已导出一个名为dragonTest.json的龙动画文件,及其相应的纹理图谱character-dragon.png。 首先加载文件资源:

NSString * jsonPath = [[NSBundle mainBundle] pathForResource:@"dragonTest" ofType:@"json"];
std::string realPath([jsonPath UTF8String]);

CCTexture * inputTexture = [CCTexture textureWithFile:@"character-dragon.png"];

CreatureModule::CreatureLoadDataPacket json_data;
CreatureModule::LoadCreatureJSONData(filename, json_data);

上述操作将从磁盘加载JSON数据并进入内存。然后,创建可以使用这些加载的资源的实际对象:

auto cur_creature = std::shared_ptr<CreatureModule::Creature>(new CreatureModule::Creature(json_data));

creature_manager = new CreatureModule::CreatureManager(cur_creature);
creature_manager->CreateAnimation(json_data, "default");
creature_manager->CreateAnimation(json_data, "second");    

在上述示例中,JSON文件有2个动画剪辑:默认剪辑和第二剪辑。因此,您需要从Creature管理器对象创建2个动画,使它们可以播放。

已完成加载,可以设置活动状态的动画用于播放:

creature_manager->SetActiveAnimationName("default");

上述操作将默认剪辑设置为当前活动的动画。现在继续创建对象来渲染角色动画:

creature_render = [[CCreatureRender alloc] initWithData:creature_manager andTexture:inputTexture];
creature_render.scale = 12;
creature_render.position = CGPointMake(300, 100);

最后,将对象添加到场景:

[self addChild:creature_render];

上述过程即为将您的角色集成到Cocos2d的基本说明!

完整代码示例

以下为完整的代码布局。大多数代码是从默认的Cocos2dX项目启动器模板生成的。请注意**loadModel()**方法,该方法执行了大部分工作:

CCLOG(@"Loading Creature");

NSString * jsonPath = [[NSBundle mainBundle] pathForResource:@"dragonTest" ofType:@"json"];
std::string realPath([jsonPath UTF8String]);

CCTexture * inputTexture = [CCTexture textureWithFile:@"character-dragon.png"];

// 加载Creature
CreatureModule::CreatureLoadDataPacket json_data;
CreatureModule::LoadCreatureJSONData(realPath, json_data);

auto cur_creature = std::shared_ptr<CreatureModule::Creature>(new CreatureModule::Creature(json_data));
creature_manager = new CreatureModule::CreatureManager(cur_creature);

// 创建和加载动画
auto new_animation_1 = std::shared_ptr<CreatureModule::CreatureAnimation>(
                                                                          new CreatureModule::CreatureAnimation(json_data,
                                                                                                                "default"));

creature_manager->AddAnimation(new_animation_1);
creature_manager->SetActiveAnimationName("default");
creature_manager->SetIsPlaying(true);
creature_manager->SetTimeScale(82.0);

creature_render = [[CCreatureRender alloc] initWithData:creature_manager andTexture:inputTexture];
creature_render.scale = 12;
creature_render.position = CGPointMake(300, 100);

[self addChild:creature_render];

自定义时间/帧范围

您可以为当前活动的动画设置自定义时间/帧范围。假设您想将播放限制在10到20的帧范围内,您可以执行以下操作:

creature_manager->SetUseCustomTimeRange(true);
creature_manager->SetCustomTimeRange(10, 20);

动画混合(Animation Blending)

您可以执行以下操作来混合2个动画剪辑:

creature_manager->SetBlending(true);
creature_manager->SetBlendingAnimations("default", "second");
creature_manager->SetBlendingFactor(0.5); // 在混合时,可选数值为从0到1

覆盖、修改骨骼位置

某些情况下,您需要直接修改角色的骨骼位置。例如,为了添加布娃娃物理效果,您可能希望骨骼位置与若干由弹簧或关节连接在一起的刚体保持一致。在这种情况下,您需要为自己的自定义要求设置骨骼位置,您可以执行以下操作。首先,编写自定义骨骼覆盖方法。在下面的例子中,修改了骨骼y方向上的位置:

// 这是一个如何使用回调函数修改您角色中的骨骼位置的示例
// 在这个例子中,我们将所有的骨骼在y方向上移动一个固定的量。
void
HelloWorld::bonesModifyCallback(std::unordered_map<std::string, meshBone *>& bones_map)
{
    for(auto& bone_data : bones_map)
    {
        auto cur_bone = bone_data.second;
        auto cur_start_pos = cur_bone->getWorldStartPt();
        auto cur_end_pos = cur_bone->getWorldEndPt();
    
        cur_start_pos.y -= 5;
        cur_end_pos.y -= 5;
    
        cur_bone->setWorldStartPt(cur_start_pos);
        cur_bone->setWorldEndPt(cur_end_pos);
    }
}

您还需要告诉Creature管理器使用您的自定义骨骼修改回调,如下所示:

// 如何注册回调函数来修改骨骼的示例
std::function<void (std::unordered_map<std::string, meshBone *>&) > cur_callback =
    std::bind(&HelloWorld::bonesModifyCallback, this, std::placeholders::_1);
creature_manager_2->SetBonesOverrideCallback(cur_callback);

角色实例和内存

如需实例一个角色的多个副本(如2条龙),您可以创建这样的动画:

// 创建和加载动画
auto new_animation_1 = std::shared_ptr<CreatureModule::CreatureAnimation>(
                                                                        new CreatureModule::CreatureAnimation(json_data,
                                                                                              "default"));

auto new_animation_2 = std::shared_ptr<CreatureModule::CreatureAnimation>(
                                                                          new CreatureModule::CreatureAnimation(json_data,
                                                                                                                "pose2"));

然后,您可以继续创建一个新的Creature对象、一个新的Creature管理器对象和一个新的Creature渲染器对象。您可以添加创建的动画到您新创建的Creature管理器对象中,如下所示:

// 第二个Creature实例示例。这将告诉你如何加载第二个Creature。
// 因为第一和第二个生物共享动画数据,您能够
// 节省内存。
auto creature_2 = std::shared_ptr<CreatureModule::Creature>(new CreatureModule::Creature(json_data));

CreatureModule::CreatureManager * creature_manager_2 = new CreatureModule::CreatureManager(creature_2);
creature_manager_2->AddAnimation(new_animation_1);
creature_manager_2->AddAnimation(new_animation_2);
creature_manager_2->SetActiveAnimationName("pose2");
creature_manager_2->SetIsPlaying(true);
creature_manager_2->SetUseCustomTimeRange(true);
creature_manager_2->SetCustomTimeRange(10, 60);

auto creature_renderer_2 = CreatureRenderer::Renderer::create(creature_manager_2,
                                                             CCTextureCache::getInstance()->addImage("character-dragon.png"));
creature_renderer_2->setColor(cocos2d::Color3B(255, 255, 255));
creature_renderer_2->setScale(30.0);
creature_renderer_2->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y - 200));

this->addChild(creature_renderer_2, 1);

该示例和之前示例的区别在于:先创建动画,后将其添加到各自的Creature管理器中。这就意味着为动画分配的内存(最昂贵的)存储在标准位置。多个Creature管理器对象将从Creature动画对象的公共池添加动画。

使用点缓存提高播放性能

如果您希望提高动画播放速度,也不想占用引擎资源,您可以在特定的动画上启用点缓存。

点缓存实际上直接存储动画的顶点,可以使播放绕过占用引擎。在具有非常复杂的骨架和变形的角色绑骨上使用点缓存将非常高效。

要对特定动画启用点缓存,请执行以下操作:

my_creature_manager->MakePointCache("myAnimationName");

上述即为创建缓存的所有操作。请注意:缓存适用于特定的动画,而不是角色。这就意味着如果您实例化了多个角色,也只需使用该动画的单个缓存。即可节省内存并提升播放性能