【cocos2d-x】cocoStdio帧事件

class TestFrameEvent : public ArmatureTestLayer
{
public:
    virtual void onEnter() override;
    virtual std::string title() const override;
    void onFrameEvent(cocostudio::Bone *bone, const std::string& evt, int originFrameIndex, int currentFrameIndex);
    void checkAction(float dt);
protected:
    NodeGrid* _gridNode;
};

ArmatureDataManager::getInstance()->addArmatureFileInfoAsync("armature/HeroAnimation.ExportJson", this, schedule_selector(TestAsynchronousLoading::dataLoaded));




#define  FRAME_EVENT_ACTION_TAG 10000

void TestFrameEvent::onEnter()
{
    ArmatureTestLayer::onEnter();
    _gridNode = NodeGrid::create();
    armature = Armature::create("HeroAnimation");//创建一套骨骼
    
    armature->getAnimation()->play("attack");//得到一个动作
    //
//    armature->getAnimation()->gotoAndPlay(0);
    armature->getAnimation()->setSpeedScale(0.5);//设置播放速度
    //设置位置
    armature->setPosition(Point(VisibleRect::center().x - 50, VisibleRect::center().y -100));

    /*
     * Set armature's frame event callback function
     * To disconnect this event, just setFrameEventCallFunc(nullptr);
     2、用途与原理
     首先介绍一下帧事件。正如其名:一个与帧相关联的事件。
     为什么要这么做呢?首先没人想做一大堆碎动画,然后一点一点拼着播放吧。另外,有时候流程与事件控制最好关联到帧。比如一个攻击动作,有出刀和收刀两部分。伤害自然是在刀所触到敌人时候产生的。做成两个动画比较麻烦,程序要管理大量的动画,而且美工也会很郁闷:不但给你们切图,还要给你们切动画。如果用固定时间来做,也是会有问题。比如机器卡了,帧数就会下降。这个时候,时间就不准确了。用帧事件的方式就会比较好,到了“触刀”那帧,就会有事件,能较好的处理这种情况。
     
     它的原理是监听。当运行到事件所在的帧时,会触发回调。我们要做的就是在回调函数中操作,判断这一帧是不是我们想要的,标记的方式是Tag字符串。
     3、设置帧事件
     
     打开项目,运行动画编辑器,切换到动画模式。
     将时间轴拖动到相应帧处,选择一个对象,这里我选择的是左手。然后在它的属性中设置帧事件。
     */
    armature->getAnimation()->setFrameEventCallFunc(CC_CALLBACK_0(TestFrameEvent::onFrameEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
    
    _gridNode->addChild(armature);
    addChild(_gridNode);//添加到场景树上
    //开启更新函数checkAction
    schedule( schedule_selector(TestFrameEvent::checkAction) );
}
std::string TestFrameEvent::title() const
{
    return "Test Frame Event";
}
void TestFrameEvent::onFrameEvent(Bone *bone, const std::string& evt, int originFrameIndex, int currentFrameIndex)
{
    CCLOG("(%s) emit a frame event (%s) at frame index (%d).", bone->getName().c_str(), evt.c_str(), currentFrameIndex);
    
    Action * getTempAct = _gridNode->getActionByTag(FRAME_EVENT_ACTION_TAG);
    //如果动作不存在 或者 动作完成
    if (!getTempAct || getTempAct->isDone())
    {
        _gridNode->stopAllActions();//停止精灵的所有动作
        //使用 范围、是否 shatter(粉碎)z顶点、grid 的尺寸、duration  创建一个 网格action
        /** creates the action with a range, whether of not to shatter Z vertices, a grid size and duration */
//        static ShatteredTiles3D* create(float duration, const Size& gridSize, int range, bool shatterZ);
        ActionInterval *action =  ShatteredTiles3D::create(0.2f, Size(16,12), 5, false);
        action->setTag(FRAME_EVENT_ACTION_TAG);
        //_gridNode->runAction(action);
    }
}
void TestFrameEvent::checkAction(float dt)
{
    if (armature==nullptr) {
        return;
    }
//    int mm_movementList = armature->getAnimation()->getMovementCount();
//    for (int i=0; i<mm_movementList; i++) {
//        armature->getAnimation()->playWithIndex(i);
//    }
    
    if ( _gridNode->getNumberOfRunningActions() == 0 && _gridNode->getGrid() != nullptr)
        _gridNode->setGrid(nullptr);
}








   

你可能感兴趣的:(动画,cocos2d-x,cocostudio)