开发者

Aligning CCMenu to a grid

开发者 https://www.devze.com 2023-03-12 13:25 出处:网络
Does anybody know the best practice approach to getting an array of CCMenuItems to align to a grid?This is a cocos2d question

Does anybody know the best practice approach to getting an array of CCMenuItems to align to a grid? This is a cocos2d question

For exa开发者_StackOverflowmple :

int levelCount = 10;

CCMenu *menuArray = [CCMenu menuWithItems:nil];

for (int x = 1; x<=levelCount; x++) {
    CCLOG(@"Creating level icon for Level %i", x);     
    [menuArray addChild:[CCMenuItemImage itemFromNormalImage:@"Button2n.png" 
                                               selectedImage:@"Button2s.png" 
                                                      target:self 
                                                    selector:@selector(onPlay:)]];

}

[menuArray alignToGridWouldbeGreat????!!!!];
[self addChild:menuArray];

I can align vertically, horizontally, in columns or rows however cannot wrap a column or row configuration.

Thanks in advance!


You just have to call one of the overloaded alignItemsInColumns or alignItemsInRows methods. For example if you have 15 menu items and you want 3 rows of 5 columns, do this:

CCMenu* menu = [CCMenu menuWithItems:...];
NSNumber* itemsPerRow = [NSNumber numberWithInt:5];
[menu alignItemsInColumns:itemsPerRow, itemsPerRow, itemsPerRow, nil];

The only down side is that there doesn't seem to be a way to set padding when aligning to a grid.


Ok, while not as flexible as I would like, I've got a decent enough solution for my purposes. Anyone else can feel free to use this code if they too find it useful.

//////// Put images (or whatever) for all levels in an array /////////        

    int levelCount = 15;
    NSMutableArray* menuArray = [NSMutableArray arrayWithCapacity:levelCount];
    for (int x = 1; x<=levelCount; x++) {

        CCLOG(@"Creating level icon for Level %i", x);

        CCMenuItemImage* item = [CCMenuItemImage itemFromNormalImage:@"Button2n.png" 
                                                       selectedImage:@"Button2s.png" 
                                                              target:self 
                                                            selector:@selector(onPlay:)];
        [menuArray addObject:item];                        
    }

//////// arrange in a grid with specific number of columns /////////

    CGSize screenSize = [CCDirector sharedDirector].winSize;

    int columns = 5;

    int spaceBetweenColumns = columns + 1;

    int spacing = screenSize.width / spaceBetweenColumns;

    CCLOG(@"screenWidth (%f) / columnsWithEdges (%i) = spacing = %i, ", screenSize.width, spaceBetweenColumns, spacing);

    CGPoint currentDrawPoint = CGPointMake(0, screenSize.height - spacing);  // start at the top 

    for (CCMenuItem *item in menuArray) {

        currentDrawPoint.x = currentDrawPoint.x + spacing;

        if (currentDrawPoint.x > (columns * spacing)) {
            // start a new line as we have reached the end of the previous one
            currentDrawPoint.x = spacing;
            currentDrawPoint.y = currentDrawPoint.y - spacing;
        }

        item.position = currentDrawPoint;
        [self addChild:item];

    }


Here is my solution, i hope it helps.

First define this struct somewhere:

typedef struct
{
 int cols;
}RowInfo;

Then:

-(void)layoutMenu:(CCMenu *)menu rowInfo:(RowInfo[])inf rows:(int)rows padding:(CGPoint)padding     
{
CCMenuItem *dummy = (CCMenuItem *)[menu.children objectAtIndex:0];
int itemIndex = 0;

float w = dummy.contentSize.width;
float h = dummy.contentSize.height;

CGSize screenSize = [[CCDirector sharedDirector]winSize];
CCArray *items = [menu children];

float startX;

for (int i = rows - 1; i >=0; i--)
{
    int colsNow = info[i].cols;

    startX = (screenSize.width - (colsNow * w + padding.x * (colsNow - 1)))/2;
    float y = i * (padding.y + h);

    for (int j = 0; j < colsNow; j++)
    {
        CCMenuItem *item = (CCMenuItem *)[items objectAtIndex:itemIndex];
        item.anchorPoint = ccp(0,0);
        item.position = ccp(startX, y);
        startX += padding.x + w;
        itemIndex++;
    }
}
}

The call goes like this(a custom keyboard):

//create custom keyboard
NSArray *captions = [NSArray arrayWithObjects:
@"Q", @"W", @"E", @"R", @"T", @"Y", @"U", @"I", @"O", @"P",
   @"A", @"S", @"D", @"F", @"G",@"H", @"J", @"K", @"L",
     @"Z", @"X", @"C", @"V", @"B", @"N", @"M", nil];

CCMenu *menu = [CCMenu menuWithItems:nil];

[self addChild:menu];

for (NSString *caption in captions)
{
    CCLabelTTF *label = [CCLabelTTF labelWithString:caption fontName:@"Courier" fontSize:25];
    CCMenuItemLabel *item = [CCMenuItemLabel itemWithLabel:label target:self selector:@selector(callDelegate:)];
    [menu addChild:item];
}

RowInfo info[3] = {{7}, {9}, {10}}; //inverse order

[self layoutMenu:menu withRowInfo:info rows:3 padding:ccp(15, 15)];


May be you can try this....

[menuArray alignItemsVerticallyWithPadding:20.0];

or

[first_menu alignItemsHorizontallyWithPadding:20.0];


To the best of my knowledge Anish's answer is your best course of action. It would be the same as aligning to a grid and it is what I personally use. Just set your menu position and alignment padding and you should have what you are looking for.

0

精彩评论

暂无评论...
验证码 换一张
取 消