Question

I am having some trouble getting the userData values from my object. I know the userData is being set for the objects because else where in my code I am able to access it without any problems.

I created a SKNode *column3 to hold all the buttons that are in that column. which was added to scene like so:

    column3 = [SKNode node];
    [self addChild:column3];
    column3.name = @"column3";

when I create the buttons I assign them to the appropriate column like so:

    [column3 addChild:newButton];

Later in my code I need to loop through the column3 node group and get the @"buttonRow" userData from each object in that group. For some reason it only gives me "NULL" for the values. The NSLog's are just what I was using to test, they have no real importance to me.

I need to get this userData in order to shift all my buttons down to take up any empty spaces on screen when any button is deleted/removed from that column. Game will shift buttons down and add new ones to top to fill column back up.

I tried changing column3.children to self.children and it game me all the column nodes IE/column1, column2, column3 etc.. so I am not really sure why it does not work. Been reading and trying to figure out for a while now.

 for(SKNode * child in column3.children) { //loop through all children in Column3.

                SKSpriteNode* sprite = (SKSpriteNode*)child;
                NSString* name = sprite.name;
                NSLog(@"child name %@", name);

                NSString *childRowTmp = [child.userData objectForKey:@"buttonRow"];
                NSLog(@"child row %@", childRowTmp);

                int childRowNumber = [childRowTmp intValue];
                NSLog(@"child row # %i", childRowNumber);
            }

Any help or tips would be great, thank you.

UPDATE: here is how I create the button using my button class file I created.

    //Create Blue Button.
    NSString *rand = [self genRandStringLength:10];
    newButton = [[ButtonNode alloc] initWithButtonType:1 column:3 row:i uniqueID:rand];
    newButton.name = rand;

    [column3 addChild:newButton];   //add the button to correct column
    [column3Array addObject:newButton];

    blueTotal++;
    totalButtons++;
    column3Total++;

here is the custom class file where the Object is created.

-(id)initWithButtonType:(int)buttonType column:(int)buttonColumn row:(int)buttonRow uniqueID:(NSString *)uniqueID {
    self = [super init];

    uniqueStr = uniqueID;

    rowNumber = buttonRow;

    columnNumber = 3;   //this is just hard coded for testing

     buttonNumber = 1;
     [self addButtonBlue];
}

here is the part of the class that creates and adds the button

- (void) addButtonBlue {

    SKSpriteNode *button;

        //button type 1
        button = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:kBoxSize];

        button.name = uniqueStr;

        button.physicsBody.categoryBitMask = blueCategory;
        button.physicsBody.contactTestBitMask = blueCategory;
        button.physicsBody.collisionBitMask = blueCategory | redCategory | yellowCategory | greenCategory | orangeCategory;

        NSString *tmpColumn = [NSString stringWithFormat:@"%i",columnNumber];
        NSString *tmpType = [NSString stringWithFormat:@"%i",buttonNumber];
        NSString *tmpRow = [NSString stringWithFormat:@"%i",rowNumber];

        button.userData = [NSMutableDictionary dictionary];
        [button.userData setValue:uniqueStr forKey:@"buttonID"];
        [button.userData setValue:tmpType forKeyPath:@"buttonType"];
        [button.userData setValue:tmpColumn forKeyPath:@"buttonColumn"];
        [button.userData setValue:tmpRow forKey:@"buttonRow"];

        button.position = CGPointMake(xPos , yPos );

        [self addChild:button];
}
Was it helpful?

Solution

I am having the same issue, see below the code which generates a green or red sprite. Attempting to give it the colour value within the SKSpriteNode.userData. In my log output the userData is (null)!

+(SKSpriteNode *)randomSprite {
    SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"green.png"];
    [sprite setUserData:[NSMutableDictionary dictionary]];

    if ((arc4random() %(2)-1) == 0){
        sprite = [SKSpriteNode spriteNodeWithImageNamed:@"green.png"];
        [sprite.userData setValue:@"GREEN" forKey:@"COLOR"];
    }else {
        sprite = [SKSpriteNode spriteNodeWithImageNamed:@"red.png"];
        [sprite.userData setValue:@"RED" forKey:@"COLOR"];
    }

    NSLog(@"user data = %@",sprite.userData);

    sprite.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:sprite.size.width/2];
    sprite.physicsBody.dynamic = YES;

    return sprite;
}

For a workaround I guess we could create a reference dictionary where the SKSpriteNode instances are the keys and a NSDictionary of data are the values.

//----- * UPDATE ** -------

And theres no wonder, after the userData was initialised, another sprite was being initialised in its place, leaving the userData nil!

+(SKSpriteNode *)randomSprite {
    SKSpriteNode *sprite;

    if ((arc4random() %(2)-1) == 0){
        sprite = [SKSpriteNode spriteNodeWithImageNamed:@"green.png"];
        [sprite setUserData:[NSMutableDictionary dictionary]];
        [sprite.userData setValue:@"GREEN" forKey:@"COLOR"];
    }else {
        sprite = [SKSpriteNode spriteNodeWithImageNamed:@"red.png"];
        [sprite setUserData:[NSMutableDictionary dictionary]];
        [sprite.userData setValue:@"RED" forKey:@"COLOR"];
    }

    NSLog(@"user data = %@",sprite.userData);

    sprite.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:sprite.size.width/2];
    sprite.physicsBody.dynamic = YES;

    return sprite;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top