Ios 无法获取ChildByTag

Ios 无法获取ChildByTag,ios,objective-c,cocos2d-iphone,Ios,Objective C,Cocos2d Iphone,下面是Lynda.com的iOS游戏开发教程,该教程使用cocos2d(版本2)。讲师使用以下代码在触摸事件时增加精灵图像的大小。下面代码中的log语句正在工作(即触摸事件已启用),但当我单击模拟器时,图像不会变大。这条线的摩尔数是零 CCSprite *mole = (CCSprite *)[self getChildByTag:1]; 这里是整个方法 - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

下面是Lynda.com的iOS游戏开发教程,该教程使用cocos2d(版本2)。讲师使用以下代码在触摸事件时增加精灵图像的大小。下面代码中的log语句正在工作(即触摸事件已启用),但当我单击模拟器时,图像不会变大。这条线的摩尔数是零

CCSprite *mole =  (CCSprite *)[self getChildByTag:1];
这里是整个方法

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView: [touch view]];
    location = [[CCDirector sharedDirector] convertToGL: location ];
    CCLOG(@"touch happened at x: %0.2f y: %0.2f",location.x, location.y );
    CCSprite *mole =  (CCSprite *)[self getChildByTag:1];

    if (CGRectContainsPoint([mole boundingBox], location)) {
        [mole runAction:[CCSequence actions:
                         [CCScaleTo actionWithDuration:.25 scale:1.1],
                         [CCScaleTo actionWithDuration:.25 scale:1.0],
                         nil]];
    }
}
屏幕上显示的鼹鼠使用下面的
init
方法。我假设上面的行
CCSprite*mole=(CCSprite*)[self-getChildByTag:1]
应该在孩子的时候得到鼹鼠的参考,但它显然不起作用

-(id) init
{
    // always call "super" init
    // Apple recommends to re-assign "self" with the "super" return value
    if( (self=[super init])) {
        self.isTouchEnabled = YES;
        CGSize s = [[CCDirector sharedDirector] winSize];
        CCSprite *mole = [CCSprite spriteWithFile:@"mole.png"];
        mole.position = ccp(s.width/2,s.height/2);
        [self addChild:mole];
        mole.tag = 1;

        CCSprite *bg = [CCSprite spriteWithFile:@"bg.png"];
        bg.anchorPoint = ccp(0,0);
        [self addChild:bg z:-1];
    }
    return self;
}
你能从上面的代码看出为什么这里的摩尔数是零吗

 CCSprite *mole =  (CCSprite *)[self getChildByTag:1];
更新

HelloWorldLayer.h

#import <GameKit/GameKit.h>

// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"

// HelloWorldLayer
@interface HelloWorldLayer : CCLayer <GKAchievementViewControllerDelegate, GKLeaderboardViewControllerDelegate>
{
}

// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;

@end
#导入
//导入此文件时,将导入所有cocos2d类
#导入“cocos2d.h”
//HelloWorldLayer
@接口HelloWorldLayer:CCLayer
{
}
//返回包含HelloWorldLayer作为唯一子对象的场景
+(场景*)场景;
@结束
HelloWorldLayer.m

// Import the interfaces
#import "HelloWorldLayer.h"

// Needed to obtain the Navigation Controller
#import "AppDelegate.h"

#pragma mark - HelloWorldLayer

// HelloWorldLayer implementation
@implementation HelloWorldLayer

// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(CCScene *) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];

    // 'layer' is an autorelease object.
    HelloWorldLayer *layer = [HelloWorldLayer node];

    // add layer as a child to scene
    [scene addChild: layer];

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
-(id) init
{
    // always call "super" init
    // Apple recommends to re-assign "self" with the "super's" return value
    if( (self=[super init]) ) {

        self.isTouchEnabled = YES;

        // create and initialize a Label
//      CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];
//
//      // ask director for the window size
//      CGSize size = [[CCDirector sharedDirector] winSize];
//
//      // position the label on the center of the screen
//      label.position =  ccp( size.width /2 , size.height/2 );
//      
//      // add the label as a child to this Layer
//      [self addChild: label];

        CGSize s = [[CCDirector sharedDirector] winSize];
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"moles.plist"];
        CCSprite *mole = [CCSprite spriteWithSpriteFrameName:@"a0010.png"];
//      CCSprite *mole = [CCSprite spriteWithFile:@"mole.png"];
        mole.position = ccp(s.width/2,s.height/2);
        mole.scale = .25;
        //between 0 255
//        mole.opacity = 100;
        NSMutableArray *frames = [[NSMutableArray alloc] init];
        for (int i = 1; i <= 10; i++) {
            NSString *frameName = [NSString stringWithFormat:@"a%04i.png",i];
            [frames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:frameName]];
        }
        CCAnimation *a = [CCAnimation animationWithFrames:frames delay:1.0f/24.0f];
        [mole runAction:[CCAnimate actionWithAnimation:a restoreOriginalFrame:NO]];
        [self addChild: mole];


        CCSprite *bg = [CCSprite spriteWithFile:@"bg.png"];
        //supposed to fill whole screen but not

        //got next three lines from SO
    //stackoverflow.com/questions/12383228/how-to-set-background-image-for-the-entire-scene-in-cocos2d-xcode
        CGSize imageSize = bg.contentSize;
        bg.scaleX = s.width/ imageSize.width;
        bg.scaleY = s.height/ imageSize.height;

        bg.anchorPoint = ccp(0,0);
        [self addChild:bg z:-1];
        //
        // Leaderboards and Achievements
        // *

//      // Default font size will be 28 points.
//      [CCMenuItemFont setFontSize:28];
//      
//      // to avoid a retain-cycle with the menuitem and blocks
//      __block id copy_self = self;
//      
//      // Achievement Menu Item using blocks
//      CCMenuItem *itemAchievement = [CCMenuItemFont itemWithString:@"Achievements" block:^(id sender) {
//          
//          
//          GKAchievementViewController *achivementViewController = [[GKAchievementViewController alloc] init];
//          achivementViewController.achievementDelegate = copy_self;
//          
//          AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
//          
//          [[app navController] presentModalViewController:achivementViewController animated:YES];
//          
//          [achivementViewController release];
//      }];
//      
//      // Leaderboard Menu Item using blocks
//      CCMenuItem *itemLeaderboard = [CCMenuItemFont itemWithString:@"Leaderboard" block:^(id sender) {
//          
//          
//          GKLeaderboardViewController *leaderboardViewController = [[GKLeaderboardViewController alloc] init];
//          leaderboardViewController.leaderboardDelegate = copy_self;
//          
//          AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
//          
//          [[app navController] presentModalViewController:leaderboardViewController animated:YES];
//          
//          [leaderboardViewController release];
//      }];
//
//      
//      CCMenu *menu = [CCMenu menuWithItems:itemAchievement, itemLeaderboard, nil];
//      
//      [menu alignItemsHorizontallyWithPadding:20];
//      [menu setPosition:ccp( size.width/2, size.height/2 - 50)];
//      
//      // Add the menu to the layer
//      [self addChild:menu];

    }
    return self;
}

//- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
//{
//    acceleration.x
//}

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView: [touch view]];
    location = [[CCDirector sharedDirector] convertToGL: location ];
    CCLOG(@"touch happened at x: %0.2f y: %0.2f",location.x, location.y );
    CCSprite *mole =  (CCSprite *)[self getChildByTag:1 ];
    NSLog(@"mole %@", mole);
//    if (CGRectContainsPoint([mole boundingBox], location))
//    {
//        [mole runAction: [CCScaleBy actionWithDuration:.25 scale:1.1]];
//        
//    }
    if (CGRectContainsPoint([mole boundingBox], location)) {
        [mole runAction:[CCSequence actions:
                         [CCScaleTo actionWithDuration:.25 scale:1.1],
                         [CCScaleTo actionWithDuration:.25 scale:1.0],
                         nil]];
    }
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
    // in case you have something to dealloc, do it in this method
    // in this particular example nothing needs to be released.
    // cocos2d will automatically release all the children (Label)

    // don't forget to call "super dealloc"
    [super dealloc];
}

#pragma mark GameKit delegate

-(void) achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
    AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
    [[app navController] dismissModalViewControllerAnimated:YES];
}

-(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
    AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
    [[app navController] dismissModalViewControllerAnimated:YES];
}
@end
//导入接口
#导入“HelloWorldLayer.h”
//需要获取导航控制器
#导入“AppDelegate.h”
#pragma标记-HelloWorldLayer
//HelloWorldLayer实现
@HelloWorldLayer的实现
//帮助器类方法,用于创建将HelloWorldLayer作为唯一子对象的场景。
+(场景*)场景
{
//“场景”是一个自动释放对象。
CCScene*scene=[CCScene节点];
//“层”是一个自动释放对象。
HelloWorldLayer*层=[HelloWorldLayer节点];
//将层作为子层添加到场景中
[场景添加子对象:层];
//返回现场
返回场景;
}
//在“init”中,您需要初始化实例
-(id)init
{
//始终称为“超级”初始化
//苹果建议用“超级”返回值重新分配“自我”
if((self=[super init])){
self.isTouchEnabled=是;
//创建并初始化标签
//CCLabelTTF*label=[CCLabelTTF labelWithString:@“Hello World”fontName:@“Marker Feel”fontSize:64];
//
////向主任询问窗口大小
//CGSize size=[[CCDirector sharedDirector]winSize];
//
////将标签放在屏幕中央
//标签位置=ccp(尺寸宽度/2,尺寸高度/2);
//      
////将标签作为子项添加到此层
//[自添加子项:标签];
CGSize=[[CCDirector sharedDirector]winSize];
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@“moles.plist”];
CCSprite*mole=[CCSprite spritewithpriteframename:@“a010.png”];
//CCSprite*mole=[CCSprite spriteWithFile:@“mole.png”];
摩尔位置=ccp(s.宽度/2,s.高度/2);
摩尔分数=0.25;
//在0到255之间
//摩尔不透明度=100;
NSMUTABLEARRY*帧=[[NSMUTABLEARRY alloc]init];

对于(inti=1;i按KARTHIK RA的话做

或者,您可以将CCSprite子类化,并在子类中添加触摸检测和处理程序。当我有几个可触摸Sprite时,我会这样做,因为:

  • 它消除了在触摸时持续检查场景/层中所有儿童的需要
  • 您可以在sprite类中提前创建动作,并在检测到触摸时运行它
  • 它将动作逻辑与场景分离
  • 当检测到触摸时,您就知道触摸了哪个对象

祝cocos2d好运。这是一个很棒的引擎。如果您迁移到版本3,请记住“tag”不再是CCNode的属性。它已被“name”取代,而“name”实际上是字符串类型。tag是int类型。

按照KARTHIK RA说的做

或者,您可以将CCSprite子类化,并在子类中添加触摸检测和处理程序。当我有几个可触摸Sprite时,我会这样做,因为:

  • 它消除了在触摸时持续检查场景/层中所有儿童的需要
  • 您可以在sprite类中提前创建动作,并在检测到触摸时运行它
  • 它将动作逻辑与场景分离
  • 当检测到触摸时,您就知道触摸了哪个对象

祝cocos2d好运。它是一个很棒的引擎。如果您迁移到版本3,请记住“标记”不再是CCNode的属性。它已被“名称”取代这实际上是一种字符串类型。标记是一种int类型。

你检查过你的
mole
?它是nil吗?而且你给出的动画非常不突出。将比例
1.1
更改为
2.0
@inderkumarrator是的,谢谢,mole是
nil
,但我不知道为什么。刚刚从教程中复制了代码。mole是在屏幕上。您是否看到这行
CCSprite*mole=(CCSprite*)[self-getChildByTag:1]有问题
@inderkumarratore我更改了问题的标题和主体,以反映mole为nil的事实。这里的代码乍一看似乎还可以。您介意发布整个项目吗?我过去在将标记设置为“1”时遇到过问题,因为我没有明确标记的其他视图也有标记“1”。您介意将其更改为“1”吗类似14562的东西,看看它是否仍然有问题?你检查过你的
mole
?它是零吗?而且你给出的动画也不太突出。将比例
1.1
更改为
2.0
@inderkumarratore是的,谢谢,mole是
nil
,但我不知道为什么。只是从教程中复制了代码。mole启动了屏幕。您是否看到这行代码有问题
CCSprite*mole=(CCSprite*)[self-getChildByTag:1]
@inderkumarratore我更改了问题的标题和主体,以反映摩尔为零这一事实。这里的代码乍一看似乎还行。您介意发布整个项目吗?我过去在将标记设置为“1”时遇到了问题,因为
to check null value:

    if(mole!=NULL) //check null value
   {
      if (CGRectContainsPoint([mole boundingBox], location)) 
        {
          [mole stopAllActions];
          [mole runAction:[CCSequence actions:
                     [CCScaleTo actionWithDuration:.25 scale:1.1],
                     [CCScaleTo actionWithDuration:.25 scale:1.0],
                     nil]];
         }

   }
  // set the tag value mole sprite in init method (HelloWorldLayer.m).

   CCSprite *mole = [CCSprite spriteWithSpriteFrameName:@"a0010.png"];
    //      CCSprite *mole = [CCSprite spriteWithFile:@"mole.png"];
    mole.position = ccp(s.width/2,s.height/2);
    mole.scale = .25;
    mole.tag=1;