0
votes

I am putting together a simple board game in cocos2d to get my feet wet. To track user clicks I intend to listen for click on game squares, not the game pieces to simplify tracking game pieces. It would be 8x8 board.

Is it more efficient to:

A. Make an array of CGRects to test against and need to put the struct in an NSObject before adding to array. Seams simple but looks like a lot of work going into access the CGRects every time they are needed.

or

B. Make actual CCSprites and test against their bounding rectangle. Simple to code, but that there are an extra 64 unneeded visual objects on the screen, bloating memory use.

or even

C. Some other method, and I am fundamentally misunderstanding this tool.

1

1 Answers

1
votes

I agree it seems unnecessary to create a sprite for each game square on your board if your board is totally static.

However CGRect is not an object type so it can not be added to an NSMutableArray, and I will also assume that at some point you will want to do other things with your game square, such as highlighting them and other stuff. What I suggest you do is that you create a class called GameSquare that inherits from CCNode and put them into an array:

// GameSquare.h

@interface GameSquare : CCNode {
    //Add nice stuff here about gamesquares and implement in GameSquare.m
}

After that, you can create gamesquares as nodes:

// SomeLayer.h
@interface SomeLayer : CCLayer {
    NSMutableArray *myGameSquares;
    GameSquare *magicGameSquare;
}

@property (nonatomic, strong) GameSquare *magicGameSquare;

// SomeLayer.m

/* ... (somewhere in the layer setup after init of myGameSquares) ... */

GameSquare *g = [[GameSquare alloc] init];
g.position = CGPointMake(x,y); //replace x,y with your coordinates
g.size = CGSizeMake(w,h); //replace w,h with your sizes

[myGameSquares addObject:g];

self.magicGameSquare = [[GameSquare alloc] init];
magicGameSquare.position = CGPointMake(mX,mY); //replace with your coordinates
magicGameSquare.size = CGSizeMake(mW,mH); //replace with your sizes

After that, you can do hit test against the gamesquares like this (in your CCLayer subclass):

// SomeLayer.m
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    CGPoint location = [self convertTouchToNodeSpace: touch];

    // Example of other objects that user might have pressed
    if (CGRectContainsPoint([magicSquare getBounds], location)) {
        // User pressed magic square!
        [magicSquare doHitStuff];
    } else {
        for (int i=0; i<myGameSquares.count; i++) {
            GameSquare *square = [myGameSquares objectAtIndex:i];    

            if (CGRectContainsPoint(square.boundingBox, location)) {
                // This is the square user has pressed!
                [square doHitStuff];
                break;
            }
        }
    }     

    return YES;
}

Yes, you will have to look through the list, but unless the player can press many squares in one touch, you can stop the search as soon as the right one is found, as demonstrated in the example.

(Assumed use of ARC)

PS. If you at some point need to add a any sprite for the GameSquare, simply add a CCSprite member in your GameSquare class and refer to that.