Search code examples
objective-carrayssprite-kitskspritenodesknode

SKSpriteNode moveTo:X for all in array


        for (int i = 0; i < [playerCards count]; i++) {
            int cardsLaid = i * (cardDisplay.size.width / 3);
            CGPoint forPoint = CGPointMake((0.5 - (self.frame.size.width / 4)) + cardsLaid, 0.0);

            playerCards[i]

            [??? runAction:[SKAction moveTo:forPoint duration:0.6]];
        }

I need some sort of SKSpriteNode withName : X move to point : forPoint;

Not much more to describe, basically that cards move from one position leaving a gap. Then after that card is moved from the Players array, them cards should tighten up as they were before. However, targetting the CardSpriteNodes is proving difficult.

As you can see with the position it will filter through all the cards in the array and i will multiply the gap between them therefore resorting them. But I cannot target the specific cards in the array, they are stored in the array by their .names

-EDIT-

enter image description here

As you can see, after they've moved up, it leaves a gap from where they were taken. Above cards are now cardsPlayed and below cars are playerCards NSMutableArrays

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    if ([node isKindOfClass:[CardSpriteNode class]]) {
        int add = (int)[playerCards count] * (cardDisplay.size.width / 3);
        CGPoint origPos = CGPointMake(-self.frame.size.width/2.8 + add, -218);

        if ([cardsPlayed containsObject:node.name]) {
            //Card is already played, return to original position and remove from array.
            CGPoint point = origPos;

            [node runAction:[SKAction moveTo:point duration:0.6]];

            node.zPosition = zPosCount;
            zPosCount += 1;

            [cardsPlayed removeObject:node.name];
            [playerCards addObject:node.name];

            NSLog(@"this ran");
        } else {
            //Card is not already played, position to add card and add to array.
            amountOfCardsLaid = (int)[cardsPlayed count] * (cardDisplay.size.width / 3);
            CGPoint point = CGPointMake((0.5 - (self.frame.size.width / 4
            )) + amountOfCardsLaid, 0.0);
            [node runAction:[SKAction moveTo:point duration:0.6]];

            node.zPosition = zPosCount;
            zPosCount += 1;

            [playerCards removeObject:node.name];
            [cardsPlayed addObject:node.name];

            for (int i = 0; i < [playerCards count]; i++) {
                int cardsLaid = i * (cardDisplay.size.width / 3);
                CGPoint forPoint = CGPointMake((0.5 - (self.frame.size.width / 4)) + cardsLaid, 0.0);

                playerCards[i]

                [??? runAction:[SKAction moveTo:forPoint duration:0.6]];
            }
        }

        //Hide.Unhide buttons
        if ([cardsPlayed count] == 0) {
            if (addButton.hidden == FALSE) addButton.hidden = true;
            if (cancelButton.hidden == FALSE) cancelButton.hidden = true;
        } else {
            if (addButton.hidden == TRUE) addButton.hidden = false;
            if (cancelButton.hidden == TRUE) cancelButton.hidden = false;
        }
    }
}

So as you can see, when a card is taken from the bottom it goes to the top. When it's at the top, if it's pressed again, it will move to the last position of the bottom cards and be re-added to that array. However, I need to close the gap once the card has been moved upwards.

To achieve this I was going to filter through each playerCards array with contains the CardSpriteNode (SKSpriteNode) .name and move each one with the forloop. But cannot exactly figure out how to select each card in the playerCard by it's name?


Solution

  • I have written a card game in my spare time as well so I know the issue you are looking at. I created a subclass of SKSpriteNode and in it I had keys with the different values the cards had.

    However you don't even need to do that if you want to keep it more basic just set the name property of the SKSpriteNode and then use the enumerateChildNodesWithName: method or a for loop with an if statement like suggested in the comments.