1. 概述

DragonBones 是 Cocos Creator 引擎中用于处理骨骼动画的核心模块。它提供了一套完整的骨骼动画系统,支持复杂的 2D 骨骼动画效果。以下是对 DragonBones 核心功能的详细分析:

2. 骨骼动画工厂 (CCFactory)

CCFactory 是 DragonBones 的核心类,负责创建和管理骨骼动画相关的所有对象。

class CCFactory : public BaseFactory, public cc::middleware::IMiddleware {
    DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(CCFactory)

private:
    static DragonBones *_dragonBonesInstance;
    static CCFactory *_factory;

public:
    static CCFactory *getFactory() {
        if (CCFactory::_factory == nullptr) {
            CCFactory::_factory = new CCFactory();
        }

        return CCFactory::_factory;
    }

    virtual ~CCFactory() {
        clear(false);
    }

protected:
    virtual TextureAtlasData *_buildTextureAtlasData(TextureAtlasData *textureAtlasData, void *textureAtlas) const override;
    virtual Armature *_buildArmature(const BuildArmaturePackage &dataPackage) const override;
    virtual Slot *_buildSlot(const BuildArmaturePackage &dataPackage, const SlotData *slotData, Armature *armature) const override;

public:
    virtual DragonBonesData *loadDragonBonesData(const std::string &filePath, const std::string &name = "", float scale = 1.0f);
    virtual TextureAtlasData *loadTextureAtlasData(const std::string &filePath, const std::string &name = "", float scale = 1.0f);
    virtual CCArmatureDisplay *buildArmatureDisplay(const std::string &armatureName, const std::string &dragonBonesName = "", const std::string &skinName = "", const std::string &textureAtlasName = "") const;
};

这个类实现了以下核心功能:

  • 提供全局工厂实例,确保单例模式
  • 负责创建和管理骨骼动画所需的所有资源
  • 提供加载和解析骨骼动画数据的方法
  • 创建骨架显示对象
  • 管理纹理图集数据

CCFactory.h:31:90 CCFactory.cpp:31:60 CCFactory.cpp:61:90

3. 骨骼动画数据管理

DragonBones 使用高效的资源管理机制来加载和管理骨骼动画数据。

DragonBonesData *CCFactory::loadDragonBonesData(const std::string &filePath, const std::string &name, float scale) {
    if (!name.empty()) {
        const auto existedData = getDragonBonesData(name);
        if (existedData) {
            return existedData;
        }
    }

    const auto fullpath = cc::FileUtils::getInstance()->fullPathForFilename(filePath);
    if (cc::FileUtils::getInstance()->isFileExist(filePath)) {
        const auto pos = fullpath.find(".json");

        if (pos != std::string::npos) {
            const auto data = cc::FileUtils::getInstance()->getStringFromFile(filePath);
            return parseDragonBonesData(data.c_str(), name, scale);
        } else {
            cc::Data cocos2dData;
            cc::FileUtils::getInstance()->getContents(fullpath, &cocos2dData);
            uint8_t *binary = cocos2dData.takeBuffer();
            return parseDragonBonesData(reinterpret_cast<char *>(binary), name, scale);
        }
    }

    return nullptr;
}

这个方法实现了:

  • 检查是否已加载过相同名称的骨骼数据
  • 支持从 JSON 或二进制文件加载骨骼数据
  • 自动处理文件路径和扩展名
  • 返回解析后的骨骼数据对象

CCFactory.cpp:91:120

4. 纹理图集管理

纹理图集是骨骼动画的重要组成部分,CCFactory 提供了专门的方法来处理纹理图集数据。

TextureAtlasData *CCFactory::_buildTextureAtlasData(TextureAtlasData *textureAtlasData, void *textureAtlas) const {
    if (textureAtlasData != nullptr) {
        const auto pos = _prevPath.find_last_of("/");
        if (pos != std::string::npos) {
            const auto basePath = _prevPath.substr(0, pos + 1);
            textureAtlasData->imagePath = basePath + textureAtlasData->imagePath;
        }

        if (textureAtlas != nullptr) {
            static_cast<CCTextureAtlasData *>(textureAtlasData)->setRenderTexture(static_cast<middleware::Texture2D *>(textureAtlas));
        }
    } else {
        textureAtlasData = BaseObject::borrowObject<CCTextureAtlasData>();
    }

    return textureAtlasData;
}

这个方法实现了:

  • 处理纹理图集的路径问题
  • 将纹理图集与实际的渲染纹理关联
  • 创建新的纹理图集对象

CCFactory.cpp:31:60

5. 骨架创建

骨架是骨骼动画的核心元素,CCFactory 提供了创建骨架的方法。

Armature *CCFactory::_buildArmature(const BuildArmaturePackage &dataPackage) const {
    const auto armature = BaseObject::borrowObject<Armature>();
    const auto armatureDisplay = CCArmatureDisplay::create();
    armatureDisplay->addRef();

    armature->init(
        dataPackage.armature,
        armatureDisplay, armatureDisplay, _dragonBones);

    return armature;
}

这个方法实现了:

  • 创建骨架对象
  • 创建骨架显示对象
  • 初始化骨架对象

CCFactory.cpp:61:90

6. 插槽管理

插槽是连接骨骼和显示对象的桥梁,CCFactory 提供了创建插槽的方法。

Slot *CCFactory::_buildSlot(const BuildArmaturePackage &dataPackage, const SlotData *slotData, Armature *armature) const {
    const auto slot = BaseObject::borrowObject<CCSlot>();

    slot->init(
        slotData, armature,
        slot, slot);

    return slot;
}

这个方法实现了:

  • 创建插槽对象
  • 初始化插槽对象

CCFactory.cpp:61:90

7. 骨骼动画显示

CCArmatureDisplay 是骨骼动画的显示容器,负责渲染骨骼动画。

CCArmatureDisplay *CCFactory::buildArmatureDisplay(const std::string &armatureName, const std::string &dragonBonesName, const std::string &skinName, const std::string &textureAtlasName) const {
    const auto armature = buildArmature(armatureName, dragonBonesName, skinName, textureAtlasName);
    if (armature != nullptr) {
        return static_cast<CCArmatureDisplay *>(armature->getDisplay());
    }

    return nullptr;
}

这个方法实现了:

  • 创建骨架
  • 获取骨架的显示对象

CCFactory.cpp:151:180

8. 资源清理

为了防止内存泄漏,CCFactory 提供了资源清理方法。

void CCFactory::removeDragonBonesDataByUUID(const std::string &uuid, bool disposeData) {
    for (auto it = _dragonBonesDataMap.begin(); it != _dragonBonesDataMap.end();) {
        if (it->first.find(uuid) != std::string::npos) {
            if (disposeData) {
                it->second->returnToPool();
            }
            it = _dragonBonesDataMap.erase(it);
        } else {
            it++;
        }
    }
}

这个方法实现了:

  • 根据 UUID 移除骨骼数据
  • 可选地释放骨骼数据占用的资源

CCFactory.cpp:151:180

9. 总结

DragonBones 是 Cocos Creator 引擎中功能强大的骨骼动画系统,其核心功能可以总结为以下几个方面:

  1. 工厂模式:通过 CCFactory 类实现单例模式,统一管理所有骨骼动画资源的创建和生命周期。
  2. 资源管理:支持从 JSON 或二进制文件加载骨骼动画数据,提供高效的资源缓存和清理机制。
  3. 骨骼系统:实现完整的骨骼结构,支持复杂的骨骼动画效果,包括父子骨骼关系、旋转、缩放等变换。
  4. 插槽系统:通过插槽机制连接骨骼和显示对象,实现灵活的动画控制。
  5. 纹理图集:支持纹理图集管理,优化渲染性能,减少 GPU 调用次数。
  6. 动画播放:提供完整的动画播放功能,包括播放、暂停、停止等控制,支持多种动画混合模式。
  7. 显示容器:提供 CCArmatureDisplay 作为骨骼动画的显示容器,集成到 Cocos Creator 的场景系统中。
  8. 跨平台支持:作为 Cocos Creator 的一部分,DragonBones 支持所有 Cocos Creator 支持的平台,包括 iOS、Android、Windows、Mac、Web 等。

这些核心功能共同构成了一个强大而灵活的骨骼动画系统,使开发者能够创建高质量的 2D 动画效果,同时保持良好的性能和跨平台兼容性。

10. Spine、DragonBones与Spriter 对比

在 Cocos Creator 中集成骨骼动画时,SpineDragonBones 都有很好的官方支持,而 Spriter 的集成度相对较弱。下面这个表格清晰地展示了它们的核心差异,可以帮助你快速了解和选择。

特性维度Spine 🚀DragonBones 🐉Spriter
官方支持官方全面支持,持续更新官方全面支持无官方原生支持,需第三方或自研方案
引擎集成组件完善,功能同步及时组件完善社区实现的运行库,可能不稳定且功能不全
性能表现性能优异,支持动画缓存合批优化性能良好,同样支持动画缓存合批依赖于社区实现的运行库,性能优化和维护性存疑
开发便利脚本API丰富,支持挂点、顶点效果、换装等脚本API完整,支持换装等操作需要自行处理资源加载和动画控制,开发成本高
学习与生态资料丰富,社区活跃,有官方技术方案文档和社区资源充足相关资料和解决方案稀少

💎 选择建议

根据你的项目需求和背景,可以参考以下建议做出选择:

  • 追求顶级动画效果、性能和产品化程度,且预算充足 👑
    对于有较高性能要求或计划发布中度至重度商业游戏的项目,Spine 是首选。它能提供更流畅的动画效果,并且在Cocos Creator中获得了持续的功能增强,例如对Spine 4.2版本和物理效果的支持。Spine在Cocos Creator中的支持较好。

  • 追求高性价比、快速原型开发或团队熟悉Flash工作流 💸
    DragonBones 的免费和开源特性对独立开发者、小团队或预算有限的项目极具吸引力。如果团队有Flash制作基础,学习曲线也相对平缓。它非常适合用于制作UI动画、特效和NPC等。

  • 已有Spriter动画资源或进行特定技术探索 🔬
    除非你已有大量Spriter资源亟待复用,或是出于技术研究的目的,否则在新项目中选择Spriter需要慎重评估其技术风险和额外的开发成本。

Logo

为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。

更多推荐