【cocos2d-x】cocoStdio帧事件

来源:互联网 发布:信达证券交易软件 编辑:程序博客网 时间:2024/05/29 05:02
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 10000void 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);}




                                             
0 0