天天看點

[cocos2dx]2.2到3.1(3.0)更新幫助

[cocos2dx]2.2到3.1(3.0)更新幫助

cocos2dx 是一款優秀的多平台,專為2D遊戲設計的引擎. 在活躍的開源社群的推進下, 越發穩定和強大. 2.x - 3.x的更新幅度很大, 性能的提升和功能的豐富也非常明顯. 但在享受進步的同時,也要承受遷徙之苦. 本文主要是總結自己遷徙的經曆, 以防大家走彎路.

摘要: cocos2dx 是一款優秀的多平台,專為2D遊戲設計的引擎. 在活躍的開源社群的推進下, 越發穩定和強大. 2.x -> 3.x的更新幅度很大, 性能的提升和功能的豐富也非常明顯. 但在享受進步的同時,也要承受遷徙之苦. 本文主要是總結自己遷徙的經曆, 以防大家走彎路.

  • 部落格: http://www.cnblogs.com/jhzhu
  • 郵箱: [email protected]
  • 作者: 知明是以
  • 時間: 2014-06-22
    • 基礎準備
    • 進入正題
      • 文法更新
        • obj-c式命名 ==> c++命名空間式命名
        • include檔案變更
        • std::function作為監聽函數
      • 功能更新
        • 中間層UILayer的去除
        • 鍵盤響應方式變更
        • Armature的陷阱
        • 更加優雅的anchorPoint
        • Sprite的預設GLProgram
        • stl::vector的不穩定排序導緻的層級問題
        • umeng等第三方庫的更新

  1. 我一直把VS當作主開發環境, eclipse和xcode作為特定機型的調試環境. 是以, 偷個懶, 假設你也在用VS開發. 另外兩個平台也也都有正規表達式替換功能, 大同小異.
  2. 在這裡, 假設你已經搭好了3.x的VS開發環境, 能正常運作

    HelloWorld

    示範.
  3. 假設你有一定的正規表達式基礎. 如果沒有的話, 可參考這篇速成教程:正規表達式30分鐘入門教程

cocos2dx 3.1的簡要feature更新介紹可參考這裡, 詳細的

changelog

可參考這裡.在更新之前, 建議掃一遍

changelog

( 否則都不知道要做啥…).

接下來, 進入正題啦:

本文将有非常多字元串替換的步驟, 都在vs2012中進行. vs2012中字元串替換視窗如下:

[cocos2dx]2.2到3.1(3.0)更新幫助

本文将上圖代表的替換表示為:( 以後将不特殊說明 )

//regex-replace
\bUIImageView\b ==> ui::ImageView           

以下是常見的替換:

//regex-replace
//Widget:
\bUIWidget\b                                ==> ui::Widget
\bUIImageView\b                             ==> ui::ImageView
\bUIButton\b                                ==> ui::Button
...                                     
\bUILayout\b                                ==> ui::Layout
\bUILabel\b                                 ==> ui::Text
\bUILayer\b                                 ==> Layer
\bCCObject\b                                ==> Ref
...

\baddTouchEventListener\s*\(\s*(.+)\s*,\s*toucheventselector\s*\((.*)\)\s*\)  ==> addTouchEventListener( CC_CALLBACK_2( $2, $1 ))
\bTouchEventType\b                          ==> ui::Widget::TouchEventType
\bTOUCH_EVENT_([A-Z]+)\b                    ==> ui::Widget::TouchEventType::$1
\baddWidget\b\s*\(                          ==> addChild(           

注釋:

\b

代表單詞的分割符.

()

代表被标記的内容,

$1

代表原始字元串中被标記的内容中的第一段. 具體請參考在 Visual Studio 中使用正規表達式.

因為包結構的變化, 是以有些元件的定義會未被include.

主要用到的head檔案有:

head 描述

cocos2d.h

cocos2dx的基本資料類和Node類都包含在裡面

ui/CocosGUI.h

cocos2dx 絕大部分的UI類都包含在内. 2.x版本中, UI類都包含在

cocos-ext.h

中. 是以絕大部分原來引用

cocos-ext.h

的地方都需要引用此檔案

cocostudio/CocoStudio.h

cocostudio功能相關的類都包含在裡面. 最主要的是各種讀取json檔案的Reader. 其次, 是

Armature

動畫.

cocos-ext.h

相比2.x的

cocos-ext.h

, 此檔案做了非常大的精簡. 現在主要包括

CCScrollView

及其子類, 另外還有

EditBox

雖然, 3.1 的版本仍然支援絕大多數老版本的回調函數方式, 比如:

m_btnSubmit->addTouchEventListener (this,toucheventselector(RewardItemCell::onBtnSubmitClick));

仍然能工作. 但是, 不能保證在将來的3.x版本中仍然如此. 是以, 盡量一次搞定吧. 在obj-c式命名 ==> c++命名空間式命名章節中, 有批量替換的正規表達式,可作為參考.

中間層

UILayer

的去除

在2.x版本,

Widget

需要作為

UILayer

的孩子節點才能響應觸摸事件; 而在3.x版本中取消了這個限制,

Widget

的響應機制變為跟

Menu

類似. 目前, 我也沒有大量的去掉之前的

UILayer

層, 大部分功能仍然正常工作.

在2.x版本中, 鍵盤響應的監聽是用

CCDirector::sharedDirector()->getKeypadDispatcher()->addDelegate(this);

實作的. 在3.x版本中是這樣:

auto keyListener = EventListenerKeyboard::create();
keyListener->onKeyReleased = CC_CALLBACK_2(MainScene::keyBackClicked, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyListener, this);           

監聽的取消, 也要做響應的替換.

在2.x版本中, 一般通過下面的方式來監聽

Armature

的事件. 在監聽到

COMPLETE

的時候, 可以将此

Armature

移出場景.

CCArmature* swf = CCArmature::create(swfName);
swf->getAnimation()->setMovementEventCallFunc(this, movementEvent_selector(OutCardEffectHelper::onAnimationEnd));           

但是在3.x中, 我們不能在監聽事件的回調函數中做任何可能會導緻

release

此對象的操作. 否則, 會導野指針錯誤.

是不是有點雞肋? 我們來看看這種情況是怎麼發生的:

Created with Raphaël 2.1.0

SchedulerScheduler

ArmatureArmature

ArmatureAnimationArmatureAnimation

thisthis

BoneBone

update(t)

告訴監聽者

假設此時觸發了COMPLETE事件this->remove Armature, release Armatureupdate(t)

set `_armatureTransformDirty = false`but now, Armature has been RELEASED!!!

我臨時用定時器來移除

Armature

的. 具體過程如下:

1. 為

ArmatureAnimation

增加一個公開函數:

virtual MovementData *getMovementData() const { return _movementData; }

2. 通過下面的方式來移除: (PS: Lmada 表達式真是好用啊啊啊啊啊 )

auto data = swf->getAnimation()->getMovementData();
float speed = data->scale;
float frames = data->duration;
float delay = frames/60/speed;
string id = FORMAT_TEXT( "%p", swf );
Director::getInstance()->getScheduler()->schedule( [swf](float t){swf->removeFromParent();},this,0,0,delay,false, id);           

如果你加載了cocostudio生成的ui json檔案, 并改動過内部

Widget

的位置的話, 你會發現, 代碼中

x=20

跟cocostudio ui編輯器中

x=20

效果是不一樣的.

問題出在哪裡呢?

簡單來說, 2.x版本中的

anchorPoint

對自己在父親節點的位置和孩子節點在自己中的位置都有影響; 3.x版本中的

anchorPoint

隻對自己在父親節點中的位置有影響.

舉個例子. 假設A是父親節點,B是A的孩子節點. A和B同為10*10的正方形.

A.anchorPoint = Point(0.5,0.5);
A.setSize(Size(10,10))
B.anchorPoint = Point(0.5,0.5);
B.setSize(Size(10,10))
B.setPosition( Point::ZERO );
A.addChild(B);           

在2.x版本中: A和B的位置完全重合

在3.x版本中: B的中心點和A的左下角的點重合.

[cocos2dx]2.2到3.1(3.0)更新幫助

什麼?你沒聽過

GLProgram

, 那恭喜你, 可以跳過這小節了. 因為你肯定不會出現下面的惱人情況.

SHADER_NAME_POSITION_TEXTURE_COLOR

是2.x版本中的預設

GLProgram

. 它對應的vect和frag分别是:

ccPositionTextureColor_vert

ccPositionTextureColor_frag

. vect用來确定位置,frag用來确定色彩.

然而, 在3.x版本中,預設的

GLProgram

SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP

, 對應的vect和frag分别是:

ccPositionTextureColor_noMVP_vert

ccPositionTextureColor_noMVP_frag

.

如果你恰好用過

ccPositionTextureColor_vert

的話, 建議改為

ccPositionTextureColor_noMVP_vert

. 否則會出現莫名的位置偏移問題.

2.x版本中, 如果沒有對孩子設定過

zOrder

的話, 孩子節點的覆寫順序為: 後加的節點在上層, 先加的節點在下層.

3.x版本中, win32環境下, 孩子節點的覆寫層級還能保續. 但是在android平台下,

zOrder

相同的孩子, 層級順序是随機的. 關鍵在下面的代碼:

void Node::sortAllChildren()
{
    if( _reorderChildDirty ) {
        std::sort( std::begin(_children), std::end(_children), nodeComparisonLess );
        _reorderChildDirty = false;
    }
}           

win32和android平台對

stl::sort()

的實作不同, android下的排序算法不是穩定的. 解決方法:

  1. 修改上述代碼, 實作穩定排序
  2. 添加孩子節點的時候手動設定

    zOrder

    來保證層級順序.

第三方庫, 也有很多跟cocos2dx版本相關. 注意更新, 否則會閃退.

Written with StackEdit.

此部落格已遷移至blog.bookbook.in,以後不再更新

繼續閱讀