Cocos2d заполнить слой на основе меню в другом слое - PullRequest
1 голос
/ 01 марта 2012

Я работаю над приложением ID вида и хотел бы заполнить слой спрайтами в зависимости от того, какое животное вы выбрали на основном слое.Я сделал для каждого животного пункт меню и могу ли он отображать информационный слой при нажатии кнопки, но как я могу настроить его так, чтобы слой отображал правильные данные в зависимости от того, какое животное вы выбрали?Информационный слой - это не полноэкранный слой, а наложенный слой, который занимает всего около 75% экрана, поэтому я использую слой, а не сцену.Я знаю, что могу создать новый слой для каждого животного (около 50) и закодировать его так, чтобы каждая кнопка вызывала свой собственный слой, но я думаю, что заполнение, основанное на том, какая кнопка нажата, сделает код более чистым.Если нажать кнопку flamingoButton, спрайт заполняется flamingo.png, а метка заполняется информацией о фламинго.Как получить информационный слой для прослушивания кнопок на основном слое?

Код 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) init
{
    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:@"species1.png"];
        infoCard.anchorPoint = CGPointMake(0.5, 0);
        infoCard.position = CGPointMake(512, 0);
        [self addChild:infoCard];    
    }
    return self;
}

Ответы [ 2 ]

1 голос
/ 02 марта 2012

Хорошо, это может сработать:

//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;
}

РЕДАКТИРОВАТЬ:

Хотя предыдущее решение работает, оно не интуитивно понятно, и я чувствую, что нарушаю некоторые концепции ООП. Самое главное, это применимо только с учетом того, что ваша информация о животном может быть получена с помощью единственного целого числа! .. Используя его таким образом, BIT лучше, вам решать:

Эмм, поэтому я бы посоветовал вам сначала установить класс сущностей :

//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;
    }
1 голос
/ 01 марта 2012

Дайте каждому пункту меню уникальный идентификатор.В методе, который вы вызываете при нажатии кнопки, вы можете ссылаться на идентификатор отправителя.Используйте этот идентификатор для заполнения нового слоя уникальной информацией.

- (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 (информационный слой)

-(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]; 
}
...