1. 程式人生 > >Cocos2d-x中替換動畫(Armature)中的節點與粒子

Cocos2d-x中替換動畫(Armature)中的節點與粒子

     Cocos2d-x遊戲開發中常用到骨骼動畫Armature,Armature不僅佔用資源不大(相對於幀動畫來說),而且還能新增幀事件,它還自帶有動畫的播放、停止、迴圈事件等。

     廢話少說,直入主題。拿到一個骨骼動畫的時候,我們往往會有這樣的需求:在情況A下,動畫的骨骼a需要顯示為樣式1,當發生情況B時,這個動畫的骨骼a需要顯示為樣式2。有一種方法,就是將骨骼a單獨作為一個動畫,這樣在使用時可以隨意替換,這裡不討論這種方法。

情景需求:
進行角色動畫處理時,當玩家裝備不同的武器時,我們需要在動畫上顯示出玩家裝備的這個武器(假設所有的武器都只是外觀不同)。所以我們需要將動畫中表示武器

的這個骨骼進行外觀的替換。同理,如果武器有發光、移動時拖尾等(用粒子系統實現的)效果,我們同樣需要替換這個粒子資源。

需要用到的API

首先來說,替換Armature中的節點常用到以下幾個函式:

  • virtual Bone *getBone(const std::string& name) const; //獲得骨骼節點
  • void changeDisplayWithIndex(int index, bool force); //根據索引改變顯示內容
  • void changeDisplayWithName(const std::string& name, bool force); //根據名稱改變顯示內容
  • void addDisplay(DisplayData *displayData, int index); //新增一個顯示內容
  • void addDisplay(cocos2d::Node *display, int index); //新增一個顯示內容
  • void removeDisplay(int index); //移除一個顯示內容
  • cocos2d::Node *getDisplayRenderNode(); // 獲得Display實際顯示的Node
  • DisplayType getDisplayRenderNodeType(); //查詢顯示內容的型別
  • virtual DisplayManager *getDisplayManager() const { return _displayManager; } //獲取Display的管理器

<1>替換骨骼(Bone)的顯示內容(Display)的方法

因為在實際拿到動畫的時候可能有多種情況,這裡我們分情況解釋。

舉例中所使用的動畫資源是使用Cocos Studio 1.6版本資源

動畫中已經包含了多個Display

專案中是直接使用.csb來建立Armature,不過可以開啟.ExportJson檔案來看一個Name為btn_icon的Bone所包含的Display資料:

bone_data下面有一個name名稱是"btn_icon"的骨骼節點。


上面看到"bone_data":後面就是動畫中包含的骨骼了,然後可以看到"bone_data"下面第一行就是一個Bone的Name屬性。跳過中間一堆位置、迴圈等屬性,往下可以看到一個"display_data"的標籤,它所代表的就是當前這個Bone中包含的所有的Display。這裡可以看到放置了3個Display,分別名為icon1.png、icon2.png、icon3.png。因為"display_data"所指的值是一個json陣列,所以自然我們也知道對應三個Display的Index分別為0、1、2.
在使用這個動畫檔案生成Armature物件時,Name屬性為btn_icon的這個Bone預設顯示的是索引為0的Display。
此時,如果我們需要改變這個Bone的顯示內容,只需要如下語句即可:

auto pArm = cocostudio::Armature::create("myArmatureName"); //生成Armature物件
auto pBone = pArm->getBone("btn_icon"); //獲取Bone物件指標
pBone->changeDisplayWithIndex(1, true); //修改Bone的Display為索引1的Display

這是在動畫中已經包含了多個Display的情況下,進行Bone的Display的切換。如果美術沒有在Bone中新增好所有需要的Display怎麼辦呢?我們可以自己新增。

動畫中沒有包含需要的Display

也就是對應的骨骼節點上所提供的display並不是自己所需的,所以得手動新增一個display,假設上面Name為btn_icon的Bone中只包含了3個Display,而我們需要顯示另外一個樣式,怎麼辦呢?我們可以手動新增一個Display。程式碼如下:

auto pArm = cocostudio::Armature::create("myArmatureName"); //生成Armature物件
auto pBone = pArm->getBone("btn_icon"); //獲取Bone物件指標
auto pSprite = Sprite::create("icon4.png"); //生成需要顯示的Node
pBone->addDisplay(pSprite, 3); //將新生成的Node新增到Bone中
pBone->changeDisplayWithIndex(3, true); //修改Bone的Display為索引3的Display

在上面兩種方式中,都有出現Index引數,這個引數有點講究。例如當新增一個Display時,Index引數值如果為0、1、2,就會導致新的Display覆蓋原來的Display,如果為3,則正好新增一個Display,如果超過3,則會在addDisplay這一行報錯,原因是被斷言:Assert failed: the _index value is out of range
還有上面changeDisplayWithIndex中的第二個引數force,測試後再詳細來寫。

<2>替換骨骼(Bone)的粒子效果(Particle)的方法

看過上面方法,替換Bone上的Display就很容易了。如果某個Bone的顯示內容就是粒子,使用上面的兩種方法也是可以達到解決問題的效果。這裡再列出另外一種替換Bone上的粒子效果的方法。

Display是一個粒子

遇到這種情況,再放一張圖好了:


Bone-particle.jpeg

同樣是在上面提到的.ExportJson動畫檔案中,這裡可以看到Bone的Name屬性為pr1,它的"display_data"所表示的不是圖片名,而是一個plist檔案,這裡就是粒子系統(ParticleSystem)檔案。
將這張圖中"display_data"的內容與上一張圖(Bont-btn_icon)中的進行對比,可以看到"displayType"的值不同。
我們看看原始碼中的這個屬性:

/**
* DisplayType distinguish which type your display is.
*/
enum DisplayType
{
    CS_DISPLAY_SPRITE,                //! display is a single Sprite
    CS_DISPLAY_ARMATURE,         //! display is a Armature
    CS_DISPLAY_PARTICLE,            //! display is a CCParticle.

    CS_DISPLAY_MAX
};

可以瞭解到,Display是包含三種屬性的,一是精靈(Sprite),資源就是png圖片;二是動畫(Armature);三是粒子(Particle),也就是我們現在遇到的。它們的列舉值分別為0、1、2,所以上圖中的"displayType"值為2,表示資源是粒子檔案。

然後粒子檔案要如何來替換呢?其實可以直接獲得這個Display顯示的Node,然後來修改Node的內容。看下面程式碼:

auto pBone = pArm->getBone("pr1"); //獲得Bone
auto pDisplayNode = (ParticleSystem*)(pBone->getDisplayRenderNode()); //獲得Bone的Display的Node,並強轉為ParticleSystem(因為已知了它是粒子系統)
pDisplayNode->initWithFile("my_particle.plist"); //使用新的粒子檔案重新初始化粒子系統

這樣在播放動畫時,我們看到的就是新的粒子系統的效果了。

其實這種方式,對於上面所說的Sprite類的Display也適用。

細節問題:
  • 如果在Armature剛剛生成好,還沒有播放任何動畫時,去切換Display,如果force引數填true,則這個Bone會強行顯示出來,如果填false,則根本切換不過來。不知道這裡會不會有我操作失誤,待測。
  • 在更換粒子效果時,如果粒子效果在當前幀還沒有顯示,此時使用getDisplayRenderNode獲取到的值為nullptr。
再次感謝原作者的辛勤整理

相關推薦

Cocos2d-x替換動畫(Armature)節點粒子

     Cocos2d-x遊戲開發中常用到骨骼動畫Armature,Armature不僅佔用資源不大(相對於幀動畫來說),而且還能新增幀事件,它還自帶有動畫的播放、停止、迴圈事件等。      廢話少說,直入主題。拿到一個骨骼動畫的時候,我們往往會有這樣的需求:在情況A

cocos2d-x-3.3rc2-003 cocos的引用計數和自己主動釋放池

all post clas popu https -o git 打開鏈接 自己 點擊打開鏈接 cocos2d-x-3.3rc2-003 cocos中的引用計數和自己主動釋放池

CSS3動畫功能——Transitions 功能Animations 功能

1 Transitions功能 (1)瀏覽器支援: 到目前為止:Safari3.1以上、Chrome8以上、Firefox4以上、Opera10以上、IE11以上瀏覽器支援該功能。  (2)功能 在CSS3中,Transitions功能通過將元素的某個屬性從一個屬性值在指定

cocos2d-x通過zOrder來控制每個節點顯示出來的順序原理

       我們為了控制一個節點的顯示層級關係,通常會用到設定zOrder來控制,那麼,其中的原理又是怎樣的呢?下面來探究一下。        先上一段測試程式碼跟資源以及效果 #include "HelloWorldScene.h" #include "cocostu

Excel替換單元格的換行符

替換前內容: 按ctrl+H進入替換介面,點選查詢內容輸入框,讓游標在輸入框中,按ctrl+J,在替換內容中輸入要替換為的內容: 點選全部替換即替換成功 注意:ctrl+J輸入的內容只能通過delete鍵刪除,如果替換不成功,可以嘗試delete刪除後再輸入ct

Quick-cocos2d-x播放幀動畫

本文介紹Quick幀動畫執行步驟,C++專案和幀動畫原理請參考: http://blog.csdn.net/ellis1970/article/details/79124686 和C++專案相比,Quick播放幀動畫有些限制條件:無法以離散的圖片檔案播放幀動畫,只支援pli

cocos2d-x 3.0 動畫觸控事件總結

動畫與觸控 動畫 動畫分為兩部分  animation   與 animate   將動畫類比為連環畫,則 animation相當於造書的過程而 animate則為快速翻書的動作通常會再新增一個repeateForever的動作,確保動畫一直繼續下去 1️⃣animatio

cocos2d-x 切換骨骼動畫時殘影問題

最近在做的一個專案,NPC的動畫是用Spine來做的。遊戲中隨著不同的狀態變化,會導致NPC在“待機”、“準備進攻”、“進攻“、”眩暈“、”死亡“等等多種狀態之間來回切換,NPC每切換一種狀態,隨之就要立刻播放該狀態對應的動畫。 遊戲中播放spine動畫是用Skele

androidAnimation動畫的連續播放播放完畢後停留在最後的狀態

我們做安卓應用的苦逼程式設計師們常常會需要用到Animation也就是動畫。比如做地圖功能的時候。我們在手機旋轉時需要根據手機重力感應來調整地圖的角度,讓它上面的“北”一直指向地球的北面。。。 好多人做動畫的時候會遇到這麼兩個難題(我也曾經遇到過): 1:動畫執行完了一遍後

cocos2d-x 使用骨骼動畫

// 新增骨骼動畫快取 ArmatureDataManager::getInstance()->addArmatureFileInfo(“HeroAnimation/boy.ExportJson”); m_armature = Armature::cr

cocos2d-x 利用CCLabelTTF製作文字描邊陰影效果的實現方法

感謝點評與關注,歡迎轉載與分享。勤奮努力,持之以恆! 方法一: cocos2d-x 已經為我們封裝好了,方法就在類CCLabelTTF裡面。 /** enable or disable shadow for the label */ void enableS

Cocos2d-x 3.0心得(02)-粒子的位置型別(PositionType)

cocos2dx的粒子系統有三種位置型別,對我來說最常用的算是FREE了,因為這種粒子,一旦發射,位置就不會再跟隨粒子系統的Node(包括其父Node),移動粒子系統的話,可以形成所謂的“拖尾”,看起來更自然。 free粒子的位置,仍然是在粒子系統下的本地空間座標(雖然從

cocos2d-x 旅程開始--(實現單擊長按)

    if (turnLeftx->boundingBox().containsPoint(pTouch->getLocation()))   //點選處座標在左轉按鈕區域中(這裡末尾加分號的話,會導致點哪裡都左移的情況)     {         turnLeft->setVisibl

Cocos2d-x 3.0 開發(十二)在CocoStudio使用粒子掛載曲線動畫

1、概述    最新版本的CocoStudio在修復之前Bug的同時,加入了新功能,粒子掛載和曲線動畫就是其中的亮點。下面我們就動手做個例子,先上圖:    2、粒子掛載    執行CocoStudio

Cocos2d-x 載入骨骼動畫資源

Cocos Studio是一套基於Cocos2d-x的免費遊戲開發工具集,它能幫助開發者快速建立遊戲資源,將大部分繁瑣的遊戲開發工作使用編輯器來快速製作,進一步幫助遊戲開發者減短開發週期、提高開發效率。 Cocos Studio本身不光只是針對骨骼動畫的編輯而設計的,它還提供了UI、場景和資料等資訊的編

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

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

Cocos2d-xVector&lt;T&gt;容器以及實例介紹

top 宋體 hello 操作符 模板類 log ins bsp main Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容納的是Ref及子類所創建的對象指針,其中的T是模板,表示能夠放入到容器中的類型,在Cocos2d-x 3.x

Cocos2d-x優化關於背景圖片優化

指針 text .cpp 互動出版網 沒有 tde white 實現 origin 因為背景圖片長時間在場景中保存,並且圖片非常多,我們能夠對其進行一些優化。我們通過例如以下幾個方面考慮優化:1、不要Alpha通道背景圖片的特點是不須要透明的,所以紋理格式能夠採用不帶有A

cocos2d-x XML解析數據存儲

lba false 網上 unsigned failed popu new ccm cfile 一不小心就玩了一周的遊戲了。哎。玩的時候時間過得總是這麽快。。。 於是今天決定看一下之前不怎麽非常熟悉的XML;(之前做遊戲時數據的儲存用到過XML,但這塊是還有一個同事在做

linux下開發,解決cocos2d-x編譯出現的一個小問題, undefined reference to symbol &#39;pthread_create@@GLIBC_2.2.5&#39;

water span x86 code bject data- ace 技術分享 inux 解決cocos2d-x中編譯出現的一個小問題 對於cocos2d-x 2.×中編譯中,若頭文件裏引入了#include "cocos-ext.h",在進行C++編譯的時候會遇到例