1. 程式人生 > >Cocos2d-x 3.0開發(十三)使用CocoStudio編輯幀事件並關聯到程式

Cocos2d-x 3.0開發(十三)使用CocoStudio編輯幀事件並關聯到程式

1、概述

    幀事件也是新加入的功能。這篇中我們將看到如何使用它。我們將上篇中製作的動畫稍加修改。有圖為證:


2、用途與原理

    首先介紹一下幀事件。正如其名:一個與幀相關聯的事件。

    為什麼要這麼做呢?首先沒人想做一大堆碎動畫,然後一點一點拼著播放吧。另外,有時候流程與事件控制最好關聯到幀。比如一個攻擊動作,有出刀和收刀兩部分。傷害自然是在刀所觸到敵人時候產生的。做成兩個動畫比較麻煩,程式要管理大量的動畫,而且美工也會很鬱悶:不但給你們切圖,還要給你們切動畫。如果用固定時間來做,也是會有問題。比如機器卡了,幀數就會下降。這個時候,時間就不準確了。用幀事件的方式就會比較好,到了“觸刀”那幀,就會有事件,能較好的處理這種情況。

    它的原理是監聽。當執行到事件所在的幀時,會觸發回撥。我們要做的就是在回撥函式中操作,判斷這一幀是不是我們想要的,標記的方式是Tag字串。

3、設定幀事件

    開啟專案,執行動畫編輯器,切換到動畫模式。

    將時間軸拖動到相應幀處,選擇一個物件,這裡我選擇的是左手。然後在它的屬性中設定幀事件。


4、建立新工程

    執行指令碼建立testFrameEvt,編譯執行確保原始工程正確。

    將CocoStudio匯出的資源複製到Resource目錄下。

5、載入動畫

    更改init:

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Point origin = Director::getInstance()->getVisibleOrigin();

	ArmatureDataManager::getInstance()->addArmatureFileInfo("changeShape.ExportJson");
	Armature* arm =Armature::create("changeShape");
	arm->getAnimation()->play("frameSingle");
    arm->getAnimation()->setSpeedScale(0.5);
	arm->setPosition(Point(visibleSize.width/2,visibleSize.height/2));

	this->addChild(arm);
    return true;
}

    執行,可見動畫播放。

6、監聽幀事件

    在類中新增一個函式:

void onFrameEvent(Bone *bone, const string& evt, int originFrameIndex, int currentFrameIndex);

    並在cpp中實現:

void HelloWorld::onFrameEvent(Bone *bone, const string& evt, int originFrameIndex, int currentFrameIndex)
{
    if(strcmp(evt,"110") == 0)
    {
        ActionInterval *action =  ShatteredTiles3D::create(0.8f, Size(30,30), 5, false); 
        this->runAction(action);
    }
}

    可以看出,事件是由一個字串來標記的。

    最後在init中註冊:

arm->getAnimation()->setFrameEventCallFunc(this,frameEvent_selector(HelloWorld::onFrameEvent));

    幀事件我們用了一個效果來表現,所以還要恢復Grid,這裡我們加入一個schedule函式。當然,這裡也可以用幀事件來標記恢復點。


//宣告
	void checkAction(float dt);

//實現
    void HelloWorld::checkAction(float dt)
{
    if ( this->getNumberOfRunningActions() == 0 && this->getGrid() != nullptr)
        this->setGrid(nullptr);
}
//註冊
schedule( schedule_selector(HelloWorld::checkAction) );

    編譯執行,就能看到效果了。

7、總結

    通過在cocoStudio中設定Tag的方式來標記幀事件,在程式中設定回撥。然後根據tag名來判斷是否是需要的幀事件。這裡我有兩個擔心,首先是效率問題,不知當幀事件多的時候,監聽執行起來效率如何。第二是當效率低自動抽幀時,會不會將事件幀抽掉,導致沒有事件出現。但願我的擔心是多餘的。

    Demo 下載:http://download.csdn.net/detail/fansongy/6621423