如何在Cocos2d中移动CCMenu?

时间:2012-08-05 10:01:29

标签: objective-c ios cocos2d-iphone

我有两个项目的菜单 - 新游戏和积分。 它们垂直对齐,如下所示:

New Game
Credits

当你点击新游戏时,我希望信用减少并打开两个新菜单项,如:

New Game
  Player vs Player
  Player vs AI
Credits

我该怎么做?在我的代码菜单中只是覆盖自己,所以我将这些项目放在彼此之上。

- (id) init
{
    if ([super init])
    {
        CCLayerColor *bg = [CCLayerColor layerWithColor:ccc4(0, 0, 0, 255)];
        [self addChild:bg z:-1];


        CCMenuItemFont  *menu1 = [CCMenuItemFont itemFromString:@"New Game" target:self selector:@selector(callSecondMenu)];
        [menu1 setColor:ccc3(255, 255, 255)];

        CCMenuItemFont  *menu2 = [CCMenuItemFont itemFromString:@"Credits"];
        [menu2 setColor:ccc3(255, 255, 255)];

        CCMenu *menu = [CCMenu menuWithItems:menu1, menu2, nil];
        [menu alignItemsVerticallyWithPadding:10];
        [self addChild:menu z:10];



    }
    return self;
}

- (void) callSecondMenu
{
    CCMenuItemFont *menu1 = [CCMenuItemFont itemFromString:@"Player vs Player" target:self selector:@selector(callGame)];
    CCMenuItemFont *menu2 = [CCMenuItemFont itemFromString:@"Player vs AI" target:self selector:@selector(callGame)];
    CCMenu *menu = [CCMenu menuWithItems:menu1, menu2, nil];
    [menu alignItemsVerticallyWithPadding:5];
    [self addChild:menu];
}

1 个答案:

答案 0 :(得分:3)

将menuItems视为游戏中的角色。

我在游戏中移动菜单的方法是在其自己的单独CCMenu中创建每个菜单项,并将每个CCMenu设置在位置0,0。

然后我在他们的起始位置使用他们的位置属性手动定位CCMenuItemSprite / CCMenuItemFont菜单项(不是CCMenu),然后使用CCMoveTo动作在需要时移动菜单项。这当然适用于任何CCMenuItem子类,例如您正在使用的CCMenuItemFont。

这种方法的缺点是你失去了自动对齐菜单项的能力,它们作为单独的菜单,但这是一个很小的成本,能够以任何方式移动菜单项创建有趣的效果。

您还可以使用CCFadeIn,CCSkewTo,CCScaleBy等任何其他操作对单个菜单项执行炫酷效果。

1)创建拥有menuItems的节点时,我创建了所有菜单项。然后,当需要每个菜单项时,我通过移动或淡化它来为其设置动画。

2)我避免使用标签。这只是我的偏好。我更喜欢创建两个NSMutableDictionary作为实例变量,一个名为menuButtons,另一个名为menuButtonActions。然后我使用辅助函数来创建menuItems和actions并将它们存储在可变字典中。然后为buttonNamed:runActionNamed:和buttonNamed:setPosition:等一般事物创建方法。然后,这些方法使用两个可变字典来检索所需的menuItem和action(在需要时),然后应用所需的效果。

这似乎更有效,但如果您的游戏有几种不同的情况,您想要显示常用的菜单按钮,那么您的代码可以更具可读性和可重用性,因为您只需要创建菜单系统未来使用这样的代码:

-(void) showNewGameMenuExpanded:(BOOL)isExpanded {

    if(isExpanded){
        [menuNode buttonNamed:@"credits" runActionNamed:@"creditsSlideDown"];
        [menuNode buttonNamed:@"playerVsPlayer" runActionNamed:@"playerVsPlayerShow"];
        [menuNode buttonNamed:@"playerVsAi" runActionNamed:@"playerVsAiShow"];
    }else{
        [menuNode buttonNamed:@"credits" runActionNamed:@"creditsSlideUp"];
        [menuNode buttonNamed:@"playerVsPlayer" runActionNamed:@"playerVsPlayerHide"];
        [menuNode buttonNamed:@"playerVsAi" runActionNamed:@"playerVsAiHide"];
    }

}

这种在菜单节点的init上构建按钮和操作并将其存储在字典中以供使用的技术非常适用于暂停菜单或从屏幕侧面滑入以允许选择不同武器等的菜单。


修改

以下是Mazyod添加的一些代码,展示了如何通过使用标签访问菜单项来移动菜单项。

首先,将tag属性设置为CCMenuItem s:

    CCMenuItemFont  *menu1 = [CCMenuItemFont itemFromString:@"New Game" target:self selector:@selector(callSecondMenu)];
    [menu1 setColor:ccc3(255, 255, 255)];
    [menu1 setTag:1];

    CCMenuItemFont  *menu2 = [CCMenuItemFont itemFromString:@"Credits"];
    [menu2 setColor:ccc3(255, 255, 255)];
    [menu2 setTag:2];

    CCMenu *menu = [CCMenu menuWithItems:menu1, menu2, nil];
    [menu alignItemsVerticallyWithPadding:10];
    // add tag for the menu, or use instance variables:
    [self addChild:menu z:10 tag:kMenuTag];

然后,在你的另一种方法中:

CCMenuItem* credits = [[self getChildByTag:kMenuTag] getChildByTag:2];
// apply the action ... It has been ages since I touched cocos2d:
[credits runAction:[CCMoveBy actionWithDuration:0.5f position:ccp(0, 40)]];

CCMenuItemFont *menu1 = [CCMenuItemFont itemFromString:@"Player vs Player" target:self selector:@selector(callGame)];
CCMenuItemFont *menu2 = [CCMenuItemFont itemFromString:@"Player vs AI" target:self selector:@selector(callGame)];
CCMenu *menu = [CCMenu menuWithItems:menu1, menu2, nil];
[menu alignItemsVerticallyWithPadding:5];
[self addChild:menu];