Kanzi state machine animation interruption implementation scheme

Background, when multiple animations are executed, it is often necessary to execute the next animation before the animation is executed, which is called animation interruption.
Requirement: The previous animation is completed immediately, and the next animation is played

1. Design drawing

insert image description here

2. Flowchart

insert image description here

3. Prepare the demo

Create a deck of cards in kanzi, and create a state machine to realize the cycle switching of cards up and down.
insert image description here
insert image description here
insert image description here
The button can switch cards

4. Scheme 1, kanzi script

4.1 Click the UP button to execute the script

NewPropertyTypeADo --operations in code
insert image description here

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 RootPageChange of node binding properties

Execute the script. In the script goToState, interrupt the previous animation and then update it NewPropertyTypeLastA. Because the state machine is bound NewPropertyTypeLastA, the next animation can be executed.

insert image description here

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)
}

insert image description here

5. Scheme 2, c++

5.1 Register a callback function for the down button

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 Operations in the callback NewPropertyTypeAfunction++

   //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 Get the state machine of the node

Use to goToStateinterrupt the previous animation, and then updateNewPropertyTypeLastA

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);
 }

Guess you like

Origin blog.csdn.net/chen_227/article/details/131868251