2013-02-20 69 views
1

我已經問過類似的東西,但我無法弄清楚如何調試。這是questionCocos2d和SpriteBatchNode:無法識別哪個精靈幀導致斷言失敗

我加了一些異常處理程序(捕獲所有的Objective-C)例外,這就是什麼,我看到的結果是:

call stack trace

console output

的問題是用的SetTexture方法,它斷言失敗,驗證需要顯示的紋理名稱是否與當前sprite批處理節點中的紋理名稱相同。

發生這種情況時,試圖用另一個替換一個場景,但不會一直髮生。這與新場景有關,因爲我試圖通過從遊戲的另一部分調用替換來「隔離」問題,但它仍然會帶來麻煩。

在遊戲場景中,我有幾個精靈表和精靈批處理節點,但由於我無法隔離精靈表ID,所以我無法理解哪個精靈幀會給我帶來問題,不明白爲什麼這種情況有時只會發生

我想:

  • 瞭解哪些前景幀的名字給我的AssertionFailure
  • 瞭解它屬於哪個精靈表

這會幫助我瞭解,如果它是一個命名問題,或者這是否與其他事情有關。

希望不要是這個問題太蹩腳的..

編輯:我試過了答案,但我不能夠讀取文件名「」的信息,這裏是說,調試什麼「摘要不可用」:

Summary unavailable

這就是我創建的文件名屬性:

/** TMP: Bug solving filename */ 
@property (copy) NSString *fileName; 

-(id) initWithTexture:(CCTexture2D*)texture rectInPixels:(CGRect)rect rotated:(BOOL)rotated offset:(CGPoint)offset originalSize:(CGSize)originalSize 
{ 
    if((self=[super init])) 
    { 
     self.fileName = [NSString stringWithFormat:@"GLUINT texture name: %i", texture.name]; 
     self.texture = texture; 
     rectInPixels_ = rect; 
     rect_ = CC_RECT_PIXELS_TO_POINTS(rect); 
     offsetInPixels_ = offset; 
     offset_ = CC_POINT_PIXELS_TO_POINTS(offsetInPixels_); 
     originalSizeInPixels_ = originalSize; 
     originalSize_ = CC_SIZE_PIXELS_TO_POINTS(originalSizeInPixels_); 
     rotated_ = rotated; 
    } 
    return self; 
} 

-(id) initWithTextureFilename:(NSString *)filename rectInPixels:(CGRect)rect rotated:(BOOL)rotated offset:(CGPoint)offset originalSize:(CGSize)originalSize 
{ 
    if((self=[super init])) 
    { 
     self.fileName = fileName; //TMP 
     texture_ = nil; 
     textureFilename_ = [filename copy]; 
     rectInPixels_ = rect; 
     rect_ = CC_RECT_PIXELS_TO_POINTS(rect); 
     offsetInPixels_ = offset; 
     offset_ = CC_POINT_PIXELS_TO_POINTS(offsetInPixels_); 
     originalSizeInPixels_ = originalSize; 
     originalSize_ = CC_SIZE_PIXELS_TO_POINTS(originalSizeInPixels_); 
     rotated_ = rotated; 
    } 
    return self; 
} 
+1

唯一的'壞'問題是沒有人問。不要擔心這裏的'親密'愛好者太多:很多教條浮動。 – YvesLeBorg 2013-02-20 13:22:06

+0

@ YvesLeBorg謝謝Yves,我感謝你在去年在這個論壇上給予我的幫助和鼓勵。它有很大的幫助:) – mm24 2013-02-22 23:45:37

回答

2

在這種情況下記錄是你的朋友。您創建一個CCAnimate動作(或CCAnimation)每次你應該記錄是這樣的:

// during 'create sprite frames from sprite frame names' loop 
NSLog(@"adding sprite frame name for CCAnimate: %@", spriteFrameName); 

// after CCAnimate was created 
NSLog(@"creating CCAnimate %@ with sprite frames: %@, animate, arrayOfSpriteFrames); 

你可能會想增加更多的細節,比如其前景幀的名稱添加至該CCAnimate。如果您緩存CCAnimations並稍後重新使用它們(重用時記錄每個CCAnimation),則可能還需要添加其他日誌記錄。

現在,當您收到該錯誤時,您應該選擇調用堆棧中的[CCSprite setDisplayFrame:]方法。調試器會顯示你想要設置的CCSpriteFrame的值。尋找指針值,它會讀取像0x254fb22e

在您的日誌中搜索該值,這會使您回到「創建CCAnimate ..」日誌之一。從上面的日誌行可以看到它包含的精靈幀名稱。既然你還記錄了'arrayOfSpriteFrames',你可以得到它們的指針值,將它與導致斷言的CCSpriteFrame的指針值進行比較。

當您有一個匹配項,並且它是精靈幀數組中的第四項時,只需查找添加到CCAnimate中的第四個精靈幀名稱的名稱即可。

根據調試器中可用的信息(以及您在調試中有多熟悉),可能會有一種更快捷的方法來完成此操作,但這是一種方法,一定會導致您遇到有問題的精靈幀名稱時間相對較短。

請注意,指針值不是唯一的 - 有可能使用相同的指針值創建不同的CCAnimate。特別是如果CCAnimate播放和停止的頻率很高,則可能會發生另一個CCAnimate分配在前一個CCAnimate的相同內存位置的情況。因此,如果結果看起來不匹配,請謹慎行事。快速找出方法是在不同的設備或模擬器與設備上進行測試,因爲指針值和分配策略各不相同。

您不需要記錄哪個精靈幀名稱屬於哪個紋理圖集。只需打開每個圖集的plist並搜索精靈框架名稱即可。 plist是一個XML文件。

提示:對於這個問題常見的原因可能是在兩個不同的紋理地圖具有相同前景幀的名字 - cocos2d的,當你請求一個前景幀使用重複名稱可以使用任何紋理。

另一個提示:如果日誌記錄似乎令人生畏,我只需做到以下幾點:

  • 爲CCSpriteFrame類
  • 開放的源代碼添加的NSString *財產「名」與「複製」屬性每次
  • 創建CCSpriteFrame對象,文件名分配給CCSpriteFrame

現在,每當你看到一個CCSprit eFrame在調試器中,它會在調試器視圖中顯示相關的文件名。

+0

謝謝,我會花一些時間在週末嘗試你的答案。 – mm24 2013-02-22 23:46:35

+0

我試過答案,但沒有設法分配文件名..調試器說「不可用的信息」..我添加了一個EDIT文件的屏幕截圖以及如何初始化文件名​​值。另一種方法,即創建動畫的登錄不適用於我,因爲它會記錄所有信息,而不僅僅是我需要的信息。 – mm24 2013-03-04 17:29:10

1

好吧,看起來像你之前一直在那裏...評論第一個NSAssert,取消註釋如果塊。然後在新註釋的NSAssert上放置一個斷點。執行將暫停之前的異常,你應該檢查調用堆棧中的每個類實例的iVars(至少我可以用AppCode,希望xCode允許)。也許你會得到足夠的暗示來找出哪個紋理/動畫/ batchnode給你一個難的時間。

另外... fyi。每當我用cocos2d(任何版本)開始一個項目時,我都會應用一些'標準'修正,這樣我的生活將更容易進行調試。一個標準的「補丁」是爲CCNode添加一個名稱,我設置了一些有意義的值:始終。我也重寫descpription方法來返回我的名字。分配有意義的名字對我有很多幫助,尤其是在走下(或向上)節點層次結構以找出錯誤時。我也使用了許多NSAsserts,並且儘可能(特別是在ctors中)返回nil並記錄錯誤消息。根據Stefen的建議,如果一個cocos2d ctor返回給我一個零,我會發出一條錯誤日誌消息。然後,我可以打破這個日誌語句並深入研究這個問題。

+1

謝謝伊夫,我從來沒有聽說過AppCode,我會定義檢查它。來自Java背景我習慣了Eclipse,我經常感到需要與XCode不同的東西(不過我認爲它最近有點改進了)。你對CCNode的建議非常好,我將把它應用到遊戲的主要類。這樣的任何其他提示對我來說都很有價值。我提出了問題並接受了Steffen,因爲它提供了一些關於如何記錄問題的更具體的提示,但這兩個答案都包含對我非常有價值的幫助,謝謝! – mm24 2013-02-22 23:51:54

+1

AppCode是一個'產品',具有名義許可費用,由jetbrains構建。然後是Java的製造商IntelliJ,Java最喜歡的IDE。不是免費的,所以如果你下載版本2.0 EAP版本(免費),確保你不會上癮,如果你還沒有準備好支付許可證:) – YvesLeBorg 2013-02-23 00:55:20

+0

我試過但並沒有真正的幫助,它一直停留在那裏。我嘗試了一些變化以及..我有點卡住:( – mm24 2013-03-04 17:55:55