環境:windows7, VS2010, cocos2d-1.0.1-x-0.12.0, cygwin, eclipse, android sdk4.0.3, ndk r7b
在vs上開發,然後移植到android上.
20120718
CCArray的foreach操作:
cocos2d-x 本地通知調用的問題 CCNotificationCenter
在註冊的postNotification訊息函數中,不能再調用addObserver,可能會引發儲存CCNotificationObserver對象的CCArray擴容,導致CCArray重新new了一塊記憶體位址,CCArray首指標改變,當執行完返回postNotification函數的時候和原來的CCArray首指標不一致,導致記憶體讀取出錯。
observer->performSelector
就是註冊的訊息回呼函數。該函數內不能對再添加或減少自訂訊息。
void CCNotificationCenter::postNotification(const char *name, CCObject *object){ CCObject* obj = NULL; CCARRAY_FOREACH(m_observers, obj) { CCNotificationObserver* observer = (CCNotificationObserver*) obj; if (!observer) continue; if (!strcmp(name,observer->getName())) observer->performSelector(object); }}
20120719
強制類型轉換:
自訂類MainScene繼承自CCLayer,使用手法同HelloWorld,MainScene::scene()直接new了一個scene對象,並將MainScene的對象掛到scene下。
但是後來調用的時候產生錯誤操作:MainScene* pScene = (MainScene*)(pDirector->getRunningScene());scene被強制轉換成CCLayer,對所謂的MainScene對象成員操作,導致記憶體塊異常,現象就是在莫名其妙的地方掛掉,每次都不同,記憶體塊檢測也報過異常。
危險的強制記憶體轉換,切記切記!
20120723
最好不要寫出全域變數初始化順序有依賴關係的代碼。
const CCSize WIN_SIZE = CCDirector::sharedDirector()->getWinSize();
一開始在VS上調試沒事,移植到Android上,初始化的時候就掛了。
查了一下資料,原因是初始化順序的問題。(具體初始化的順序沒搞清楚,⊙﹏⊙b汗,歡迎補充,感激不盡)
PS:找到了幾篇初始化靜態常量順序的文章
1.控制全域變數初始化順序 && #pragma詳解
2.全域變數初始化順序
int get_a(){ static int a = 5; return a;}int get_b(){ static int b = get_a(); return b;}
3.JAVA中初始化順序複習
4.初始化有序常量的一點小技巧
20120726
playEffect
音效播放前要先preloadEffect,否則第一次播放音效沒有聲音。可以一次preloadEffect所有音效,android那邊調用的是HashMap儲存音效存放路徑。
vs端不寫preloadEffect也能正常播放,但是android端必須先preloadEffect才能正常播放,否則第一次播放沒有聲音。背景音樂沒發現這個問題。
20120803
CCTargetedTouchDelegate 的繼承 和 dynamic_cast
想寫個可以響應touch的sprite
類定義成了這個樣子:
class GemBoard : public CCSprite, CCTargetedTouchDelegate
然後註冊touch訊息的時候
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true);
在這掛了,查了一下午,掛在了
-addTargetedDelegate
-CCTargetedTouchHandler::handlerWithDelegate
-initWithDelegate
-CCTouchHandler::initWithDelegate
-dynamic_cast<CCObject*>(pDelegate)->retain();
-void CCObject::retain(void)
跟到這裡,編譯器告訴我CCObject的this指標是0,我暈呀。感覺太詭異了。
原因:CCTargetedTouchDelegate在上面的寫法中是私人繼承,而根據dynamic_cast的作用:(運算子可以在執行期決定真正的類型。如果downcast是安全的(也就說,如果基類指標或者引用確實指向一個衍生類別對象)這個運算子會傳回適當轉型過的指標。如果downcast不安全,這個運算子會傳回null 指標(也就是說,基類指標或者引用沒有指向一個衍生類別對象)。)上面的情況就合情合理了。
今天學到了2個知識點:
1. class B: public A, C 這種情況下A是public繼承,C是private繼承;class B: A 這個A也是private繼承
2.dynamic_cast 除了public 的其他都返回null
所以改成
class GemBoard : public CCSprite, public CCTargetedTouchDelegate
就正確了。發現自己的c++基礎真爛。
20121101
今天不是萬聖節嗎,怎麼變成了愚人節!!!
因為做的項目是VC++下開發,然後編成本地代碼在Android上運行,所以有些地方需要上真機列印log調試。我日哦,我在代碼裡加了N多的log代碼,就是一句也不打出來,在log上糾結了一天,一開始以為是cocos2d的代碼出問題了,難道是自動屏蔽了log輸出?上網查資料,當然什麼也找不到。我就在加log代碼,然後上真機,看不到log,然後繼續加log代碼,往複迴圈。下班的時候,同事看我這麼糾結,就問我,vc上打斷點看程式運行到log代碼處了嗎?結果是程式正常運行,斷點根本不走,靠!原來我一直在一段廢代碼上加log!我的生命呀,就這樣浪費了。我想起了一首神曲,有興趣的同學可以聽一下:Wrong
hole - DJ Lubel
20121103
CCTexture2D::initWithData
bool CCTexture2D::initWithData(const void *data, CCTexture2DPixelFormat pixelFormat, unsigned int pixelsWide, unsigned int pixelsHigh,const CCSize& contentSize)
使用資料建立紋理,我試了無數遍,各種問題都考慮了,就是不知道為啥正常建立出來的紋理顯示不出來。最後發現是contentSize這個最後的參數,我給的是(0,0)當然建立不出來了,一開始還以為是CCTexture2D建立成功後返回給我的產生的紋理大小。事實證明是我想多了……這個參數就是一開始指定要建立紋理的大小的。