kanzi状态机动画打断实现方案

背景,多个动画执行时候,往往遇到动画没有执行完就需要执行下一个动画,谓之动画打断。
需求:上一个动画立即完成,播放下一个动画

1. 设计图

在这里插入图片描述

2. 流程图

在这里插入图片描述

3. 准备demo

在kanzi中创建一个卡片组,创建一个状态机实现卡片上下循环切换
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
按钮可以切换卡片

4. 方案1,kanzi script

4.1 点击UP按钮执行脚本

代码里对NewPropertyTypeA--操作
在这里插入图片描述

var item = node.lookupNode('/RootPage');
//print(item.Name)

var valueA = item.getProperty('StateMachineTest.NewPropertyTypeA')

//simulate
if(valueA>0){
    
    
    valueA--;
}
else{
    
    
    valueA=2;
}


item.setProperty('StateMachineTest.NewPropertyTypeA', valueA)

4.2 RootPage节点绑定属性变更

执行脚本,脚本里用goToState打断上一个动画,再更新NewPropertyTypeLastA,因为状态机绑定了NewPropertyTypeLastA,所以可以执行下一个动画

在这里插入图片描述

var valueA = node.getProperty('StateMachineTest.NewPropertyTypeA')
var valueLastA = node.getProperty('StateMachineTest.NewPropertyTypeLastA')

if(valueA != valueLastA){
    
    
    //立即跳到状态LastA
   
    var node1 = node.lookupNode('#Empty Node 2D');
     print("~~~~~~~~" + valueA + "/" + valueLastA);
    
    if(0 == valueLastA){
    
    
        node1.goToState('StateGroup.State');
    }
    else if(1 == valueLastA){
    
    
        node1.goToState('StateGroup.State_1');
    }
    if(2 == valueLastA){
    
    
        node1.goToState('StateGroup.State_2');
    }
    
    
    node.setProperty('StateMachineTest.NewPropertyTypeLastA', valueA)
}

在这里插入图片描述

5.方案2,c++

5.1 为down按键注册回调函数

virtual void onProjectLoaded() KZ_OVERRIDE
    {
        // Project file has been loaded from .kzb file.

        // Add initialization code here.

        Button2DSharedPtr btn = getScreen()->lookupNode<Button2D>("#Button_Down");
        if (btn) {
            btn->addMessageHandler(Button2D::PressedMessage, bind(&StateMachineTest::onBtnLoadClicked, this, std::placeholders::_1));
        }
    }

5.2 回调函数里对NewPropertyTypeA++操作

   //simulate
   void onBtnLoadClicked(ButtonConcept::PressedMessageArguments& messageArguments)
   {
       (void)messageArguments;
       
       NodeSharedPtr node = getRoot();

       int NewPropertyTypeA = node->getProperty(DynamicPropertyType<int>("StateMachineTest.NewPropertyTypeA"));

       if (NewPropertyTypeA < 2) {
           NewPropertyTypeA++;
       }
       else {
           NewPropertyTypeA = 0;
       }
       node->setProperty(DynamicPropertyType<int>("StateMachineTest.NewPropertyTypeA"), NewPropertyTypeA);

       HandleFunction();
   }

5.3 获取节点的状态机

goToState打断上一个动画,再更新NewPropertyTypeLastA

void HandleFunction()
 {
     NodeSharedPtr node = getRoot();
     Node2DSharedPtr player = getScreen()->lookupNode<Node2D>("#Empty Node 2D");
     if (!player) return;

     ResourceSharedPtr stateManager = player->getStateManager();
     StateManagerSharedPtr stateManagerPtr = static_pointer_cast<StateManager>(stateManager);

     int NewPropertyTypeA = node->getProperty(DynamicPropertyType<int>("StateMachineTest.NewPropertyTypeA"));
     int NewPropertyTypeLastA = node->getProperty(DynamicPropertyType<int>("StateMachineTest.NewPropertyTypeLastA"));

     kzLogDebug(("NewPropertyTypeA({}),NewPropertyTypeLastA({})", NewPropertyTypeA, NewPropertyTypeLastA));

     if (NewPropertyTypeLastA != NewPropertyTypeA) {
         if (0 == NewPropertyTypeLastA) {
             stateManagerPtr->goToState((Node* )&(*player), "StateGroup", "State", true);
         }
         else if (1 == NewPropertyTypeLastA) {
             stateManagerPtr->goToState((Node*)&(*player), "StateGroup", "State_1", true);
         }
         if (2 == NewPropertyTypeLastA) {
             stateManagerPtr->goToState((Node*)&(*player), "StateGroup", "State_2", true);
         }

     }

     node->setProperty(DynamicPropertyType<int>("StateMachineTest.NewPropertyTypeLastA"), NewPropertyTypeA);
 }

猜你喜欢

转载自blog.csdn.net/chen_227/article/details/131868251