2

I'm trying to make an items scroller of sorts for my game. I decided upon the extension CCMenuAdvanced, and I was able to implement a working menu list with working buttons. However, I don't quite understand how to properly contain my menu inside a boundaryRect. It is clear to me that boundaryRect does not make "out of bounds" part of the menu list disappear - it seems to only be responsible for scrolling. The question then is what else do I have to do to get a self-contained items list using CCMenuAdvanced that becomes invisible and unresponsive when no longer in the boundary? Do I have to schedule an additional update method that tracks the location of individual elements and changes their opacity and visibility or is there a supported solution to this?

    NSArray *menuItems = [self labelsFromInventory];
    CCMenuAdvanced *menu = [CCMenuAdvanced menuWithItems: nil]; 
    for (CCMenuItem *item in menuItems)
        [menu addChild: item];  

    [menu alignItemsVerticallyWithPadding: 10 bottomToTop: NO]; //< also sets contentSize and keyBindings on Mac
    //menu.isRelativeAnchorPoint = YES; 
    menu.position = ccp(30, 40);
    [self addChild:menu z:2 tag:101];

    menu.scale = MIN ((winSize.width / 2.0f) / menu.contentSize.width, 0.75f );
    menu.boundaryRect = CGRectMake(menu.position.x, menu.position.y, 190.0, 20.0);
    [menu fixPosition];

Thanks

Daniel
  • 23,129
  • 12
  • 109
  • 154
Lendo92
  • 139
  • 1
  • 3
  • 11

2 Answers2

3

Unfortunately in Cocos2d, items don't clip to bounds. So when an item escapes its boundaries, it just continues going until a) it leaves the main window boundaries or b) it falls "under" another item in the z-order.

To do what you wish, you can first try to add another sprite to the layer that is an "opacity mask" of sorts that is higher in the z-order than the scrollable portion so that, when the item scrolls beyond the bounds of its container, it will be "hidden" by the higher z-order item.

The alternate route, and the one I took, was using a UIView (in my case, a UITableView) and wrapping it using the CCUIViewWrapper to add it onto the window. In that case, you would have to keep in mind that the UIView item will ALWAYS be placed above everything in your GL view and it doesn't exactly play nicely with things, so it does take a bit of finesse to get working. The good news is that you can use Interface Builder to design your interface and you'll get scroll masking, etc. right out of the box.

Either way is a trade-off; there is really no simple solution to this in Cocos2d currently -- at least, none that I know of.

Daniel
  • 23,129
  • 12
  • 109
  • 154
  • Ahh this is interesting. I considered implementing UIKit in my Cocos2d project early on but the documentation I looked at included way too much overhead to really be worth it. I didn't know about CCUIViewWrapper, though. Looking into it now. Do you know of any sample projects that attempt to implement something similar to what I'm going for using this class? Thanks. – Lendo92 Aug 06 '12 at 02:44
  • In particular, can you morph cocos2d elements with UI elements using this class? Like adding my CCMenuAdvanced to a UIScrollView? Thanks. – Lendo92 Aug 06 '12 at 03:24
  • What do you mean by morph? You can use the wrapper to, for instance, use CCactions on (such as FadeIn, FadeOut, etc.) As for adding CCNodes to the UIView, I'm not particularly sure as I have not tried that. Instinctively, I would like to say that no, that won't work, if only because UIView will ALWAYS be on top of your GL view no matter what, and considering your CCNode stuff is GL... The alternative would be, for instance, using UIImageView, etc. to implement these items as well as using Interface Builder to stylize your UIItem to "fit in" with the GL view. – Christopher Jones Aug 06 '12 at 13:23
  • OK I see... thanks for the input. I may decide to renovate my project and incorporate UIKit at a later stage. – Lendo92 Aug 07 '12 at 03:41
1

I started off with CCMenuAdvanced to create a menu that clamps in a boundary box. Instead of moving the position of the menu, i chose to move the position of the menu items contained in the menu. This gave me the ability to set the visibility and other properties of the menu items if they were going to be outside the boundaries (I added a boundaryBox property to the menu, as well as properties for spacing between menu items, height of a top and bottom buffer zone in points). My scrolling menu also provides a top and bottom buffer zone where i fade out the menu item when nearing the top or bottom.

I determine in the ccTouchMoved method whether a move is possible or not (ie the menu items are already at the maximum Y or minimum Y they could be). If a move is possible, I apply the deltaY to all the menu items and set each menu item's opacity and visibility properties. The hard part was the clamping.

YvesLeBorg
  • 9,070
  • 8
  • 35
  • 48
  • Did you subclass CCMenuAdvanced to accomplish this? Any details or existing examples would be much appreciated. I, like many other unextraordinary programmers, prefer to tinker with existing code than go by scratch. Thank you. – Lendo92 Aug 07 '12 at 03:43
  • Actually, there was too much 'tinkering' to do, i would eventually have had to override a bunch of things in addition to adding my own properties and stuff. I ended up copying the class in my code and rewriting (cautiously :)) some methods. – YvesLeBorg Aug 07 '12 at 03:48
  • Look at my answer here for part of the puzzle. http://stackoverflow.com/questions/10936436/ccadvancedmenu-boundaryrect/10948863#10948863 – YvesLeBorg Aug 07 '12 at 03:50