Search code examples
iosfor-loopcgpoint

Refactor Help> For loop mapping CGPoints, and SKSpriteNodes


Hi I am new to programming and I have been learning SpriteKit. (although this is a general purpose programming question.) I have hard coded values, and reused the same image over and over. A coding no no from what I understand. Can someone help me learn this by refactoring with loops I assume.

I am creating a row of 20 dashed empty card spots and placing 4 at a time to a screen size centered at the bottom of the screen. I have added these empty spots (just one card image used over and over) as a "child" to the rack.

Side Note: Since this is a general programming question if you are not familiar with SpriteKit my CGPoints are mapped to the racks coordinate system and not to the screen coordinates... if that confused you..

I have attempted to create the refactored code at the bottom but I am stuck because the node.positions are tied to SKSpriteNodes and looping that seems to be puzzling me.

Here is what I have:

-(SKSpriteNode*)createBottomRack
{
    self.rack = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor]   size:CGSizeMake(10240.0, 200)];
    self.rack.position = CGPointMake(0.0,150.0);
    self.rack.zPosition = 0;
    self.rack.name = @"bottomRack";

    // Screen 1
    SKSpriteNode *number0 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number1 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number2 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number3 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    // Screen 1 positions
    number0.position = CGPointMake(212, 0.0);
    number1.position = CGPointMake(412, 0.0);
    number2.position = CGPointMake(612, 0.0);
    number3.position = CGPointMake(812, 0.0);

    // Screen 2
    SKSpriteNode *number4 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number5 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number6 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number7 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];

    // Screen 2 positions
    number4.position =CGPointMake(1236.0, 0.0);
    number5.position =CGPointMake(1436.0, 0.0);
    number6.position =CGPointMake(1636.0, 0.0);
    number7.position =CGPointMake(1836.0, 0.0);

    // Screen 3
     SKSpriteNode *number8 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
     SKSpriteNode *number9 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
     SKSpriteNode *number10 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
     SKSpriteNode *number11 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];

    // Screen 3 positions
    number8.position =CGPointMake(2260.0, 0.0);
    number9.position =CGPointMake(2460.0, 0.0);
    number10.position =CGPointMake(2660.0, 0.0);
    number11.position =CGPointMake(2860.0, 0.0);

    // Screen 4
    SKSpriteNode *number12 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number13 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number14 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number15 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];

    // Screen 4 positions
    number12.position =CGPointMake(3284.0, 0.0);
    number13.position =CGPointMake(3484.0, 0.0);
    number14.position =CGPointMake(3684.0, 0.0);
    number15.position =CGPointMake(3884.0, 0.0);

    // Screen 5
    SKSpriteNode *number16 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number17 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number18 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    SKSpriteNode *number19 = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];

    // Screen 5 positions
    number16.position =CGPointMake(4308.0, 0.0);
    number17.position =CGPointMake(4508.0, 0.0);
    number18.position =CGPointMake(4708.0, 0.0);
    number19.position =CGPointMake(4908.0, 0.0);

    // Add dashedCards in position on screen
    [self.rack addChild:number0];
    [self.rack addChild:number1];
    [self.rack addChild:number2];
    [self.rack addChild:number3];
    [self.rack addChild:number4];
    [self.rack addChild:number5];
    [self.rack addChild:number6];
    [self.rack addChild:number7];
    [self.rack addChild:number8];
    [self.rack addChild:number9];
    [self.rack addChild:number10];
    [self.rack addChild:number11];
    [self.rack addChild:number12];
    [self.rack addChild:number13];
    [self.rack addChild:number14];
    [self.rack addChild:number15];
    [self.rack addChild:number16];
    [self.rack addChild:number17];
    [self.rack addChild:number18];
    [self.rack addChild:number19];

    return self.rack;
}

Here is where I currently am in refactoring...

NSMutableArray *dashesArray = [NSMutableArray arrayWithCapacity:20];
for (int i = 0; i<=20; i++) {
    SKSpriteNode *dash = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
    [dashesArray addObject:dash];

}

This is it because if I make a loop holding generically numbered SKSpriteNodes I don't see how I map those to the positions....?


Solution

  • Calculating the x coordinate for the position of each node is pretty straightforward:

    • x starts at 212
    • Subsequent nodes are 200px to the right of the previous node
    • Every 5th node is 424px (instead of 200px) to the right of the previous node

    The code for that looks like this:

    - (SKSpriteNode *)createBottomRack
    {
        self.rack = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(10240.0, 200)];
        self.rack.position = CGPointMake(0.0,150.0);
        self.rack.zPosition = 0;
        self.rack.name = @"bottomRack";
    
        float x = 212.0, y = 0.0;
        for (NSUInteger i = 0; i < 20; i++) {
            SKSpriteNode *dash = [SKSpriteNode spriteNodeWithImageNamed:@"dashedCard"];
            dash.position = CGPointMake(x, y);
            [self.rack addChild:dash];
    
            // Calculate the next x coordinate
            x += (i % 4 == 3) ? 424.0 : 200;
        }
    
        return self.rack;
    }