【问题标题】:Aligning CCMenu to a grid将 CCMenu 与网格对齐
【发布时间】:2011-06-14 08:30:53
【问题描述】:

有人知道让 CCMenuItems 数组与网格对齐的最佳实践方法吗?这是一个cocos2d的问题

例如:

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];

我可以在列或行中垂直、水平对齐,但不能换行列或行配置。

提前致谢!

【问题讨论】:

标签: objective-c cocos2d-iphone


【解决方案1】:

您只需调用重载的 alignItemsInColumns 或 alignItemsInRows 方法之一。例如,如果您有 15 个菜单项并且想要 3 行 5 列,请执行以下操作:

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

唯一的缺点是在对齐网格时似乎没有设置填充的方法。

【讨论】:

  • 这里填充问题的一个解决方案是在方法中添加一个“tightness”变量,如下所示: -(void) alignItemsInColumns: (NSNumber *) columns vaList: (va_list) args andTightness: (浮动)密封性。您在设置项目位置的行中使用“紧密度”:w = winSize.width / (1 + rowColumns)/tightness;它对我很有效:)
  • Padding 在这个 cocos2d-x 帖子中管理,对我很有用:github.com/cocos2d/cocos2d-x-for-xna/issues/20
【解决方案2】:

好的,虽然不像我希望的那样灵活,但我有一个足够体面的解决方案来满足我的目的。如果其他人也觉得有用,可以随意使用此代码。

//////// 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];                        
    }

//////// 排列在具有特定列数的网格中 /////////

    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];

    }

【讨论】:

    【解决方案3】:

    这是我的解决方案,希望对您有所帮助。

    首先在某处定义这个结构:

    typedef struct
    {
     int cols;
    }RowInfo;
    

    然后:

    -(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++;
        }
    }
    }
    

    调用是这样的(自定义键盘):

    //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)];
    

    【讨论】:

      【解决方案4】:

      也许你可以试试这个....

      [menuArray alignItemsVerticallyWithPadding:20.0];
      

      [first_menu alignItemsHorizontallyWithPadding:20.0];
      

      【讨论】:

      • 我认为这些选项不允许超过一行或一列,这就是我所追求的。例如,如果我有 16 个项目,则为 4x4 网格。该问题已被其他人在提供的链接中提出,但答案链接已失效cocos2d-iphone.org/forum/topic/8310
      【解决方案5】:

      据我所知,Anish 的回答是您最好的做法。这与对齐网格相同,这是我个人使用的。只需设置你的菜单位置和对齐填充,你应该有你正在寻找的东西。

      【讨论】:

      • 我认为这些选项不允许超过一行或一列,这就是我所追求的。例如,如果我有 16 个项目,则为 4x4 网格。该问题已被其他人在提供的链接中提出,但答案链接已失效cocos2d-iphone.org/forum/topic/8310
      • 哦,好吧……那还不完全确定。如果您在遵循论坛主题“3194”中讨论的方法时遇到问题,那么您始终可以创建多个菜单,每个菜单一个项目。然后,您可以将菜单放置在任何您喜欢的位置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-22
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多