Xcode Cocos2d基于不同层中的菜单填充层

Xcode Cocos2d基于不同层中的菜单填充层,xcode,cocos2d-iphone,ccsprite,cclayer,Xcode,Cocos2d Iphone,Ccsprite,Cclayer,我正在开发一个物种ID应用程序,并希望根据您在主层上选择的动物用精灵填充一个层。我已经将每种动物都设置为菜单项,按下按钮时可以显示我的信息层,但是如何设置它,使层根据您选择的动物显示正确的数据?信息层不是一个全屏层,而是一个覆盖层,只占屏幕的75%,这就是为什么我要用一个层而不是一个场景。我知道我可以为每只动物创建一个新的图层(大约50个),并对其进行编码,这样每个按钮都会调用自己的图层,但我认为根据按下哪个按钮进行填充会使代码更清晰。如果按下FlamingButton,sprite将填充fla

我正在开发一个物种ID应用程序,并希望根据您在主层上选择的动物用精灵填充一个层。我已经将每种动物都设置为菜单项,按下按钮时可以显示我的信息层,但是如何设置它,使层根据您选择的动物显示正确的数据?信息层不是一个全屏层,而是一个覆盖层,只占屏幕的75%,这就是为什么我要用一个层而不是一个场景。我知道我可以为每只动物创建一个新的图层(大约50个),并对其进行编码,这样每个按钮都会调用自己的图层,但我认为根据按下哪个按钮进行填充会使代码更清晰。如果按下FlamingButton,sprite将填充flamingo.png,标签将填充flamingo信息。如何让我的信息层收听主层上的按钮

MainLayer.m代码:

-(id) init
{
    if( (self=[super init])) 
    {        
        CCMenuItemImage *flamingoButton = [CCMenuItemImage itemFromNormalImage:@"Explore-sign.png" selectedImage:@"Explore-sign.png" target:self selector:@selector(showSecondLayer:)];
        flamingoButton.position = CGPointMake(0, 60);
        flamingoButton.tag = 101;
        CCMenu *menu = [CCMenu menuWithItems:flamingoButton, nil];
        [self addChild:menu];
    }
    return self;
}

-(void) showSecondLayer: (id) sender
{    
    CCMenuItemImage *item = (CCMenuItemImage *) sender;
    int itemID = item.tag;

    secondLayer = [SecondLayer node];
    secondLayer.position = CGPointMake(0, 700);
    [self addChild:secondLayer];
    CCMoveTo *moveLayer = [CCMoveTo actionWithDuration:1.0 position:CGPointMake(0, 0)];
    [secondLayer runAction:moveLayer];
}
SecondLayer.m(信息层)


为每个菜单项指定一个唯一的id。在点击按钮时调用的方法中,可以引用发件人的id。使用此id使用唯一信息填充新图层

- (void) buttonPressed: (id) sender
{
    MenuItem* item = (MenuItem*) sender;
    int itemID = item.tag;

    // Get unique data based on itemID and add new layer
}
编辑:根据您的代码更新

-(void) showSecondLayer: (id) sender
{    
    CCMenuItemImage *item = (CCMenuItemImage *) sender;
    int itemID = item.tag;

    secondLayer = [SecondLayer node];
    [secondLayer setItem: itemID]; // ADDED
    secondLayer.position = CGPointMake(0, 700);
    [self addChild:secondLayer];
    CCMoveTo *moveLayer = [CCMoveTo actionWithDuration:1.0 position:CGPointMake(0, 0)];
    [secondLayer runAction:moveLayer];
}
SecondLayer.m(信息层)

好的,这可能有用:

//MainLayer:
-(id) init
{
    if( (self=[super init])) 
    {        
        CCMenuItem *flamingoButton = [CCMenuItemImage itemFromNormalImage:@"Explore-sign.png" 
                                                            selectedImage:@"Explore-sign.png" 
                                                                   target:self 
                                                                 selector:@selector(showSecondLayer:)];
        flamingoButton.position = ccp(0, 60);
        flamingoButton.tag = 1;
        CCMenu *menu = [CCMenu menuWithItems:flamingoButton, nil];
        [self addChild:menu];
    }
    return self;
}

-(void) showSecondLayer: (CCMenuItem*) sender
{    
    secondLayer = [SecondLayer layerWithTag:[sender tag]];
    secondLayer.position = ccp(0, 700);
    [self addChild:secondLayer];
    CCMoveTo *moveLayer = [CCMoveTo actionWithDuration:1.0 position:ccp(0, 0)];
    [secondLayer runAction:moveLayer];
}

//Second Layer.h
+(id)layerWithTag:(NSInteger)aTag;
-(id) initWithTag:(NSInteger)aTag;

//Second Layer.m:
+(id)layerWithTag:(NSInteger)aTag {
    return [[[SecondLayer alloc] initWithTag:aTag] autorelease];
}

-(id) initWithTag:(NSInteger)aTag
{
    if( (self=[super init])) 
    {

        //Change this sprite image based on button from main layer. I don't have it coded in yet, but I understand the concept of putting a variable in the file string using %@ or %d

        CCSprite *infoCard = [CCSprite spriteWithFile:[NSString stringWithFormat:@"species%d.png", aTag]];
        infoCard.anchorPoint = ccp(0.5, 0);
        infoCard.position = ccp(512, 0);
        [self addChild:infoCard];    
    }
    return self;
}

编辑:
尽管前面的解决方案有效,但它并不直观,我觉得我打破了一些面向对象的概念。最重要的是,它只有在您的动物信息可以使用单个int!检索的情况下才可用。。这样使用会更好一些,完全由您决定:

嗯,所以,我建议您首先设置一个实体类:


好的,这个概念对我来说很有意义,但我不确定如何实现它。我的第二层代码怎么知道FlamingButton被按下了?我已经在上面添加了我的代码。对不起,我对Cocos2d还很陌生,我仍在尝试一些概念。感谢您的快速回复!您将在buttonPressed方法中添加第二层。您需要以某种方式存储“flamingo”数据,只需给它一个唯一的id,并确保要显示flamingo数据的按钮具有表示“flamingo”的id。如果您现在演示如何操作,则可以更轻松地演示如何更改方法。我已将您的代码添加到我的代码中,但由于我使用的是CCMenuItemImage而不是CCMenuItem,因此我将
item.id
替换为
item.tag
。如何让SecondLayer读取itemID?我现在正试图解决您的问题。。但是,作为一个快速提示:使用cocos2d的开发人员通常使用ccp(x,y)宏来创建CGPoints,而不是CGPointMake@Mazyod为什么呢?我的大部分代码都是通过几十个论坛、博客和书籍以及复制/粘贴/编辑等方式编写的,我已经看到了这两种方式,甚至是在相同的代码集中。是有优势还是有美感?我是Cocos2d的新手,我注意到了很多这样的重复。嗯,到目前为止,我认为这只是一个方便的问题。但是,如果您使用它而不是CGPointMake,则有一个优势:如果cocos2d员工决定使用另一个积分系统,您不必担心。他们会将ccp宏更改为其他内容,您的代码也会遵守。(NSInteger也有同样的想法。它被定义为int,但将来肯定会变为long。因此,我们不使用int,而是使用NSInteger)。这似乎是可行的。当我添加第二个标记为2的按钮时,它至少会替换掉species.png文件。我在
secondLayer=[secondLayer layerWithTag:[sender tag]]上收到警告表示
类方法'+layerWithTag:'未找到(返回类型默认为'id')
,第二层代码中有相同的警告。我可以用这个标签从plist打电话,上面有我的物种数据吗?我不是要求你解释它(但请随意),但如果这是一种合适的方法,而不是将其编码到层中,则需要更多。关于警告,你必须将方法签名添加到头文件(.h):+(id)layerWithCardName:(NSString)name。。或者如果你选择了标记的方式。关于打电话给警察,你当然可以!但是,我建议您添加某种映射器(字典),将标记(int)映射到文件信息,以减少耦合。好的,您输入的第二组代码的问题是,它只指定了.png文件。我想我应该澄清一下,第二层将显示动物的照片、动物的文字、与该物种相关的图表,如果有mutlimedia文件,这些文件也将显示出来。我的第二层需要阅读更多关于
的内容,如果atag=1,则显示photo1 label1 video1
等。显然,这不是真正的代码。我希望我的最终目标是合理的。也许我误读了你编辑的代码。一点也不!你的观点是响亮的并且被听到(如果这有意义的话)。我只是假设它只是一个图像显示。好吧,让我再更新一次我的答案,因为我要改变很多东西。哦!错过了代码中清除该警告的第二层.h部分。现在一切都好了。与物种问题相关的多个项目是我认为我应该研究走普利斯特路线的原因。我将研究如何实现这一点,并编写一本字典。
-(id) init
{
    if( (self=[super init])) 
    {
        // Removed
    }
    return self;
}

-(void) setItem: (int) item
{
    CCSprite *infoCard = [CCSprite spriteWithFile:[NSString stringWithFormat:@"species%d", item]];
    infoCard.anchorPoint = CGPointMake(0.5, 0);
    infoCard.position = CGPointMake(512, 0);
    [self addChild:infoCard]; 
}
//MainLayer:
-(id) init
{
    if( (self=[super init])) 
    {        
        CCMenuItem *flamingoButton = [CCMenuItemImage itemFromNormalImage:@"Explore-sign.png" 
                                                            selectedImage:@"Explore-sign.png" 
                                                                   target:self 
                                                                 selector:@selector(showSecondLayer:)];
        flamingoButton.position = ccp(0, 60);
        flamingoButton.tag = 1;
        CCMenu *menu = [CCMenu menuWithItems:flamingoButton, nil];
        [self addChild:menu];
    }
    return self;
}

-(void) showSecondLayer: (CCMenuItem*) sender
{    
    secondLayer = [SecondLayer layerWithTag:[sender tag]];
    secondLayer.position = ccp(0, 700);
    [self addChild:secondLayer];
    CCMoveTo *moveLayer = [CCMoveTo actionWithDuration:1.0 position:ccp(0, 0)];
    [secondLayer runAction:moveLayer];
}

//Second Layer.h
+(id)layerWithTag:(NSInteger)aTag;
-(id) initWithTag:(NSInteger)aTag;

//Second Layer.m:
+(id)layerWithTag:(NSInteger)aTag {
    return [[[SecondLayer alloc] initWithTag:aTag] autorelease];
}

-(id) initWithTag:(NSInteger)aTag
{
    if( (self=[super init])) 
    {

        //Change this sprite image based on button from main layer. I don't have it coded in yet, but I understand the concept of putting a variable in the file string using %@ or %d

        CCSprite *infoCard = [CCSprite spriteWithFile:[NSString stringWithFormat:@"species%d.png", aTag]];
        infoCard.anchorPoint = ccp(0.5, 0);
        infoCard.position = ccp(512, 0);
        [self addChild:infoCard];    
    }
    return self;
}
//AnimalResources.h
#import "Blahblahblah"

//Give it a good name, I was always bad at Science:
@interface AnimalResources {
    //load all your properties:
    NSString* info;
    CCSprite* sprite;
    ...
}

//set the properties as needed:
//Make sure you properly manage this!! It is retained!
@property (nonatomic, retain) CCSprite* sprite;
...

//method prototype (signature.. am not sure)
//Now, we shall build on the fact that it will be easy for you to map an integer to the right resources:
+(id)animalResourcesWithTag:(NSInteger)aTag;
-(id)initAnimalResourcesWithTag:(NSInteger)aTag;

//AnimalResources.m:'

@synthesize sprite, ... ;

+(id)animalResourcesWithTag:(NSInteger)aTag {
    [[[AnimalResources alloc] initAnimalResourcesWithTag:aTag] autorelease];
}
-(id)initAnimalResourcesWithTag:(NSInteger)aTag {
    if ((self = [super init])) {
        //use tag to retrieve the resources:
        //might use the stringFormat + %d approach, or have a dictionary/array plist, that maps an int to a dictionary of resource keys.

        //string way of doing things:
        self.sprite = [CCSprite spriteWithFile:[NSString stringWithFormat:@"species%d.png", aTag]];
        ...

        //Dictionary: dict/array is an NSDictionary/NSArray read from disk sometime. Don't read it here, since it 
        //will read the file from disk many times if you do --> BAD. I could explain a rough way to do that if you 
        //need help
        animalDict = [dict objectForKey:[NSString stringWithFormat:@"species%d.png", aTag]];
        //OR...
        animalDict = [array objectAtIndex:aTag];
        //better to have @"spriteNameKey" defined in a macro somewhere: #define kAnimalResourceKeySprite @"SpriteKey"
        self.sprite = [CCSprite spriteWithFile:[animalDict objectForKey:@"SpriteNameKey"]];
        ....
    }
    return self;
}

Phew! Then .. you guessed it!

    -(void) showSecondLayer: (CCMenuItem*) sender
    {    
        secondLayer = [SecondLayer layerWithAnimalResources:[AnimalResources animalResourcesWithTag:[sender tag]]];
        secondLayer.position = ccp(0, 700);
        [self addChild:secondLayer];
        CCMoveTo *moveLayer = [CCMoveTo actionWithDuration:1.0 position:ccp(0, 0)];
        [secondLayer runAction:moveLayer];
    }

    //Second Layer.h
    +(id)layerWithAnimalResources:(AnimalResources*)resource;
    -(id)initWithAnimalResources:(AnimalResources*)resource;

    //Second Layer.m:
    +(id)layerWithAnimalResources:(AnimalResources*)resource {
        return [[[SecondLayer alloc] initWithAnimalResources:aTag] autorelease];
    }

    -(id) initWithAnimalResources:(AnimalResources*)resource
    {
        if( (self=[super init])) 
        {

            //Change this sprite image based on button from main layer. I don't have it coded in yet, but I understand the concept of putting a variable in the file string using %@ or %d

            CCSprite *infoCard = [resource sprite];
            infoCard.anchorPoint = ccp(0.5, 0);
            infoCard.position = ccp(512, 0);
            [self addChild:infoCard];    
        }
        return self;
    }