Aligning CCMenu to a grid

前端 未结 5 1449
星月不相逢
星月不相逢 2021-01-14 07:38

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

For example :

int lev         


        
相关标签:
5条回答
  • 2021-01-14 08:10

    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.

    0 讨论(0)
  • 2021-01-14 08:19

    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)];
    
    0 讨论(0)
  • 2021-01-14 08:19

    May be you can try this....

    [menuArray alignItemsVerticallyWithPadding:20.0];
    

    or

    [first_menu alignItemsHorizontallyWithPadding:20.0];
    
    0 讨论(0)
  • 2021-01-14 08:37

    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];
    
        }
    
    0 讨论(0)
  • 2021-01-14 08:37

    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 讨论(0)
提交回复
热议问题