2012-03-06 195 views
1

所以我正在開始減少我的意大利麪代碼。如何從NSMutableArray設置實例變量?

所以現在,我有11個不同的恐龍圖像,我已經使用「for」循環放入NSMutableArray。我還宣佈了CCSprite實例變量,我希望我可以設置每個恐龍圖像,以便我可以檢查邊界框,設置位置等。所以我將每個對象從數組指向一個實例變量。到目前爲止,我已經驗證碼:

.h文件中:

CCSprite *dinosaur1_c; 
CCSprite *dinosaur2_c; 
CCSprite *dinosaur3_c; 
CCSprite *dinosaur4_c; 
CCSprite *dinosaur5_c; 
CCSprite *dinosaur6_c; 
CCSprite *dinosaur7_c; 
CCSprite *dinosaur8_c; 
CCSprite *dinosaur9_c; 
CCSprite *dinosaur10_c; 
CCSprite *dinosaur11_c; 

.m文件

NSMutableArray *dinoSprites = [[NSMutableArray alloc] init]; 

for(int i = 1, j = 0; i <= 11 && j <= 10; i++, j++) 
{ 
    id dino = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"dinosaur%d-c.png", i]]; 
    [dinoSprites addObject:dino]; 
    [sceneSpriteBatchNode addChild:dino]; 
} 


dinosaur1_c = (CCSprite *)[dinoSprites objectAtIndex:0]; 
dinosaur2_c = (CCSprite *)[dinoSprites objectAtIndex:1]; 
dinosaur3_c = (CCSprite *)[dinoSprites objectAtIndex:2]; 
dinosaur4_c = (CCSprite *)[dinoSprites objectAtIndex:3]; 
dinosaur5_c = (CCSprite *)[dinoSprites objectAtIndex:4]; 
dinosaur6_c = (CCSprite *)[dinoSprites objectAtIndex:5]; 
dinosaur7_c = (CCSprite *)[dinoSprites objectAtIndex:6]; 
dinosaur8_c = (CCSprite *)[dinoSprites objectAtIndex:7]; 
dinosaur9_c = (CCSprite *)[dinoSprites objectAtIndex:8]; 
dinosaur10_c = (CCSprite *)[dinoSprites objectAtIndex:9]; 
dinosaur11_c = (CCSprite *)[dinoSprites objectAtIndex:10]; 

這段代碼的工作,但我敢肯定,它可以減少。我將如何使用「for」循環來設置這些實例變量中的每一個?

我使用這些實例變量的其它方法,設置位置,檢查碰撞/相交,淡入等

我把等效代碼更好地解釋我想要做的事:

NSMutableArray *dinoSprites = [[NSMutableArray alloc] init]; 

for(int i = 1, j = 0; i <= 11 && j <= 10; i++, j++) 
{ 
    id dino = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"dinosaur%d-c.png", i]]; 
    [dinoSprites addObject:dino]; 
    [sceneSpriteBatchNode addChild:dino]; 

    // Set instance variables 
    dinosaur%i_c = (CCSprite *)[dinoSprites objectAtIndex:j]; 
} 

有沒有辦法實現我所要求的?經過2.5個小時的搜索,我仍然沒有任何東西。只需找到動畫幀的解決方案。

我是否缺少一些小東西或者我應該有不同的方法來指向數組中的每個圖像來設置它們的位置,淡入淡出,檢查包圍盒等?

任何想法/輸入非常感謝!感謝您抽時間閱讀! :D

+0

使用CCSprites的數組而不是不同的變量.. – Nilesh 2012-03-06 10:53:49

回答

3

而不是有11個CCSprite實例變量,你應該只有一個NSArray

因此,在您的.h:

@property (strong) NSArray *dinoSprites; 

在您的m,做一個

@synthesize dinoSprites; 

,然後從你的問題與替換代碼:

NSMutableArray *newDinoSprites = [[NSMutableArray alloc] init]; 

for(int i = 1, j = 0; i <= 11 && j <= 10; i++, j++) 
{ 
    id dino = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"dinosaur%d-c.png", i]]; 
    [newDinoSprites addObject:dino]; 
    [sceneSpriteBatchNode addChild:dino]; 
} 

self.dinoSprites = [newDinoSprites copy]; 

然後,只要你需要參考你曾經打過電話的話,比如說dinosaur8_c,你可以用(CCSprite *)[dinoSprites objectAtIndex:7]

+0

哇,這是一個快速響應!當你迴應時,我幾乎沒有刷牙。我只是試了一下,它的工作!謝謝!!我不知道(CCSprite *)[dinoSprites objectAtIndex:0]仍然可以用於設置位置,檢查交互內容等。再次,非常感謝你! – rizzlerazzle 2012-03-06 11:20:47

+0

你不知道這對我有多大幫助。再次感謝你! – rizzlerazzle 2012-03-06 11:27:26

2

有沒有辦法實現我所要求的?經過2.5小時的搜索,我仍然沒有任何東西。只需爲動畫幀找到解決方案 即可。

您似乎想要一個變量,其值是另一個變量,以便您可以遍歷一組ivars。我可以想出兩種方法來做你喜歡的事情。

第一種方法是使用每個變量的地址,即指向每個變量的指針。由於指針本身是標值,而不是對象,你需要使用C數組:

CCSprite *ivars[] = {&dinosaur1_c, &dinosaur2_c, &dinosaur3_c, &dinosaur4_c}; 
for (int i = 0; i < 4; i++) { 
    *(ivars[i]) = [dinoSprites objectAtIndex:i]; 
} 

第二種方法是使用鍵值編碼。構建每個伊娃以字符串形式的名稱,然後將其用作鍵調用-setValue:forKey:這樣的:

NSString *name; 
for (int i = 0; i < [dinoSprites count]; i++) { 
    name = [NSString stringWithFormat:@"dinosaur%d_c", i]; 
    [self setValue:[dinoSprites objectAtIndex:i] forKey:name]; 
} 

所有這一切說,我會強烈建議您不採取任何前面的兩種方法到你的問題。對於你的問題,很有可能有更好的解決方案,而不需要爲每隻恐龍分開一個ivar。你已經有了一個陣列中的恐龍,所以不需要爲每個恐龍創建一個單獨的ivar。作爲一般規則,如果你發現自己創建了這樣的編號變量,你應該退後一步,重新考慮你在做什麼 - 編號你的變量是一個強烈的信號,你應該使用數組。

所以,就你的情況而言,我看不到任何理由,你不能使用你已經在你的代碼中到處都有的數組。而不是dinosaur6_c,你顯然可以使用[dinoSprites objectAtIndex:6]。但是如果你想到用相同的代碼來對待所有恐龍的方法,那麼你真的會清理你的代碼,這樣你就永遠不會將特定的痕跡硬編碼到你的數組中。例如,如果您需要將每隻恐龍設置到不同的位置,至少有兩種好方法可以解決它。一個是如果可能的話,根據指數來計算頭寸。你可以做到這一點,如果你在一個普通的方式鋪設的恐龍,像一個3 XN格:

for (int i = 0; i < [dinoSprites count]; i++) { 
    int row = i/DINOS_PER_ROW; 
    int column = i % DINOS_PER_ROW; 
    CGPoint position = CGPointMake(row * rowHeight, column * columnWidth); 
    [[dinoSprites objectAtIndex:i] setPosition:position]; 
} 

如果每個恐龍的位置不是來自其在數組中的索引可計算的,那麼你目前可能正在對你的代碼中的職位進行硬編碼。您至少可以通過將位置移動到數組來清理它,也可以通過從數據文件中讀取數組。這將使你的代碼更短,更容易理解,更容易維護:

NSArray *positions = [NSArray arrayWithContentsOfURL:someURL]; // read positions from a property list 
NSAssert([positions count] >= [dinoSprites count], @"Not enough positions!"); 
for (int i = 0; i < [dinoSprites count]; i++) { 
    CGPoint position = [[positions objectAtIndex:i] pointValue]; 
    [[dinoSprites objectAtIndex:i] setPosition: position; 
} 

當然,我只是用精靈的位置做爲一個例子。你可以用任何你想要應用於恐龍的屬性來做同樣的事情,你甚至可以一次完成所有的屬性。您可以加載一個字典數組,其中每個字典包含許多屬性(顏色,最喜歡的食物,速度,飢餓水平等),而不是從屬性列表中加載的positions數組。

+0

非常好的觀點你在這裏。這些想法絕對會幫助我清理我的代碼。此外,這些恐龍的位置不對稱或在網格上。他們根據給我的背景放置。我不想讓你知道你提到的這些方法的細節。有沒有一個教程/鏈接可以解釋你更詳細地提到的這些想法?像使用plists,數據文件,數組等存儲對象信息以及如何將它們連接在一起?感謝您的精彩投入。 :D – rizzlerazzle 2012-03-06 12:36:07

+1

@rizzlerazzle您可以從Apple的[* Property List Programming Guide *](https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/PropertyLists/Introduction/Introduction.html)開始。更一般地說,排除任何操作的共同部分(如設置恐龍的位置)並將可變部分轉換爲數據的想法是編程中的一個基本概念。我不知道你會發現任何教程,但這是每一種編程語言都支持循環,函數和數據結構等功能的原因。 – Caleb 2012-03-06 12:56:45