我正在开发一个物种ID应用程序,并希望根据您在主图层上选择的动物填充一个带有精灵的图层。我已经将每只动物设置为菜单项,并且可以在按下按钮时显示我的信息图层,但是如何设置它以使图层根据您选择的动物显示正确的数据?信息图层不是全屏图层,而是一个仅占据屏幕大约75%的重叠图层,这就是为什么我要使用图层而不是场景。我知道我可以为每只动物创建一个新图层(大约50个)并对其进行编码,以便每个按钮调用自己的图层,但我认为基于按下哪个按钮进行填充会使代码更清晰。如果按下flamingoButton,sprite会填充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;
}
答案 0 :(得分:1)
为每个菜单项指定唯一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(信息层)
-(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];
}
答案 1 :(得分:1)
好的,这可能有效:
//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;
}
<小时/> 即使先前的解决方案有效,但它并不直观,我觉得我打破了一些OOP概念。 最重要的是,只有你可以使用单个int检索关于动物的信息才能使用它! ..使用它这种方式比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;
}