user3424586
user3424586

Reputation: 21

Detecting if a sprite was touched on child scene Cocos2d

I have a scene with buttons and node Level in which I load another scene (layer created with Sprite Builder):

-(void) didLoadFromCCB {
//the Gameplay Scene loaded
    // tell this scene to accept touches
    self.userInteractionEnabled = TRUE;
    //load level in gameplay scene
   CCScene *level = [CCBReader loadAsScene:@"Scenes/scene_01"];
   [_levelNode addChild:level];
}

Everything is loading and I have a gameplay scene with common buttons and a scene_01 with sprites added as child.

Now I am trying to detect if a sprite from scene_01 was touched. I can track if touch occurred on _levelNode:

- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint _touchLocation = [touch locationInNode:_levelNode];
    CCLOG(@"levelNode touched");
    // Define which touched Object
    if (CGRectContainsPoint([_part01 boundingBox], _touchLocation))
    {
        _part01.position = _touchLocation;
        _touchingPart01 = YES;
        _touchPoint = _touchLocation;
        CCLOG(@"_part01 touched");
    }
}

But the second part of code above is not working and console says the sprites were not found at all:

[1531:60b] CCBReader: Couldn't find member variable: _part01

My conclusion is - the parent scene has no access to sprites in loaded scene and the questions are:

  1. Is it a good practice to have node where game switches child:levels instead of loading levels as scenes?

  2. If Yes - how do I manage the objects inside that level, do I need more precise selector? (something like:if (CGRectContainsPoint([***level.***_part01 boundingBox], _touchLocation)))

  3. I think I could create .ccb files and create classes to describe these sprites in Cocos but it would be 5 sprites per level and dozens of levels which means I get 50+ classes which I believe isn't a good way to create a game. (I can't create a class for part and change its link to sprite due the lack of skill).

Upvotes: 2

Views: 1116

Answers (1)

user3424586
user3424586

Reputation: 21

After some more digging and modifying the question I did next:

  1. Have my Gameplay scene add the level scene as a child (and the general buttons such as next, prev, back...):

Gameplay.m

-(void) didLoadFromCCB { // tell this scene to accept touches self.userInteractionEnabled = TRUE; //load level CCScene *level = [CCBReader loadAsScene:@"Scenes/scene_01"]; [_levelNode addChild:level];
}

  1. Created Scene_01 class and have all game mechanics happen in that class:

Scene_01.m

@implementation Scene_01 {
CCSprite *_part01;
...}

-(void) didLoadFromCCB {
    // tell this scene to accept touches
    self.userInteractionEnabled = TRUE;
}

- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {

CGPoint _touchLocation = [touch locationInNode:self];
// Define which touched Object
if (CGRectContainsPoint([_part01 boundingBox], _touchLocation))
{
   //some action if _part01 is touched
    CCLOG(@"_part01");
}
}

This is working for me now. The reasons I didn't go this way from the beginning and my steps to it are next:

  1. I had my sprites named _part01,... and assigned to "Doc root var" (in Sprite Builder), to have them accessible for the scene_01 but when I named the root node of that scene my project was crashing on build so I figured this was because named node can't be added as child to other scene (in Xcode).

  2. Changed assignment of variables to "Don't assign" and the error: [1531:60b] CCBReader: Couldn't find member variable: _part01 disappeared from logs, so this was all about linking objects I use, not about accessing them.

  3. Stepped back and repeated creating class for this scene, moved the logic inside that class, added the scene as child to Gameplay scene - voila, it works!

P.S. I'm still not sure why it didn't work the first time if it does now, looking for any comments that may help understand this situation. Thanks.

Upvotes: 0

Related Questions