1. 程式人生 > >Cocos2d-x 3.0 開發(七)在程式中處理cocoStudio匯出動畫

Cocos2d-x 3.0 開發(七)在程式中處理cocoStudio匯出動畫

1、概述

    使用cocoStudio可以方便的製作動畫,接下來的工作就是在我們的程式中使用製作的動畫。這篇中,我將使用程式將兩個動畫連線起來。有圖有真相:


2、製作動畫

    承接上一篇,我們再製作一個動畫。製作動畫的方法與之前沒有差別,不太熟悉的同學可以看:Cocos2d-x 3.0開發(六)使用cocoStudio建立一個骨骼動畫。在“動作列表”中右擊,“新增動畫”然後編輯就成。

    我們新制作的動畫的結束點,要與上一篇中製作動畫的開始點重合,這樣在連線的時候,畫面就不會跳動。


    製作好後我們將動畫匯出。

3、製作UI

    既然能夠方便的製作UI,我就順手做了一個控制動畫播放的UI。製作方法之前也提到過。沒有什麼差別。使用UI編輯器製作UI,並將其匯出。



4、關聯到專案

    執行指令碼建立我們的專案,將匯出的動畫、UI放到Resource資料夾中。

    然後重寫init方法:

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

	auto ui = dynamic_cast<Layout*>(CCUIHELPER->createWidgetFromJsonFile("ControlUI.ExportJson"));
	ui->getChildByTag(UI_BUTTON_PLAY1)->addTouchEventListener(this, toucheventselector(HelloWorld::touchCallBack));
	ui->getChildByTag(UI_BUTTON_PLAY2)->addTouchEventListener(this, toucheventselector(HelloWorld::touchCallBack));
	ui->getChildByTag(UI_BUTTON_CONN)->addTouchEventListener(this, toucheventselector(HelloWorld::touchCallBack));
	ui->getChildByTag(UI_BUTTON_DISCONN)->addTouchEventListener(this, toucheventselector(HelloWorld::touchCallBack));

	auto uiLayer = UILayer::create();
	uiLayer->addWidget(ui);
	this->addChild(uiLayer);

    return true;
}

void HelloWorld::touchCallBack(Object* obj,TouchEventType type)
{
	//will play 
}

5、載入動畫

    動畫的匯出檔案也是一個json。載入後被封裝到一個Armature物件中。Armature是NodeRGBA的子類,所以它可以直接被addChild到父節點中。載入所用的是ArmatureManager中的方法。它是一個單例,管理整個場景中的Armature。我們在編輯器中編輯的動畫是Animation,它被封裝在Armature中了。因此這是一個三層的結構。ArmatureManager最大,然後是Armature,最後是Animation。我們播放動畫用的都是Animation中的方法。

    說完了原理,我們來看看程式碼。首先在init中新增載入Armature。


ArmatureDataManager::getInstance()->addArmatureFileInfo("MyAnimation.ExportJson");
Armature* armature = Armature::create("MyAnimation");
armature->setTag(AM_MYANIMATION);	

armature->setPosition(Point(origin.x + visibleSize.width/2 ,
                                origin.y + visibleSize.height/2));
this->addChild(armature);

    然後重寫touchCallback方法控制播放動畫。


void HelloWorld::touchCallBack(Object* obj,TouchEventType type)
{
	auto uiBt = dynamic_cast<UIButton*>(obj);
	if(!uiBt)
	{
		return;
	}
	int tag = uiBt->getTag();
	auto armature = (Armature*)getChildByTag(AM_MYANIMATION);
	switch (type)
	{
	case TouchEventType::TOUCH_EVENT_ENDED:
			if(tag == UI_BUTTON_PLAY1)
			{
				armature->getAnimation()->play("hit");
			}
			else if(tag ==UI_BUTTON_PLAY2)
			{
				armature->getAnimation()->play("fall");
			}
			else if(tag == UI_BUTTON_CONN)
			{
				//will conn
			}
			else if(tag == UI_BUTTON_DISCONN)
			{
				//will dis conn
			}
			break;
	default:
		break;
	}
}

6、處理動畫事件

    在Animation中有動畫事件的概念,每一個動畫開始和結束都會事件。我們需要做的就是監聽這個事件併為其寫好響應函式。

    所以接下來我們完善touchCallback函式,並新增一個監聽函式。

//......
else if(tag == UI_BUTTON_CONN)
{
	armature->getAnimation()->setMovementEventCallFunc(this,movementEvent_selector(HelloWorld::movementCallback));
}
else if(tag == UI_BUTTON_DISCONN)
{
	armature->getAnimation()->setMovementEventCallFunc(this,nullptr);
}
//......

void HelloWorld::movementCallback(Armature * armature, MovementEventType type, const char * name)
{
	if (type == COMPLETE)
	{
		if (strcmp(name,"fall") == 0)
		{
			Armature* arm = (Armature*) getChildByTag(AM_MYANIMATION);
			arm->getAnimation()->play("hit");
		}
	}
}


    編譯執行,就可以看到動畫連線起來了。

7、總結

    通過ArmatureDataManager單例來載入動畫,將其關聯到程式中。動畫事件的監聽,對動畫的行為進行處理。使用這些方法我們可以靈活的使用cocoStudio建立的動畫了。

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