2012-03-06 130 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