In a cocos2d iOS game I am currently writing, one of the things I wanted was to display a menu of items using a grid style, display the said menu in a scrollview; so I would have multiple items per page, and then finally — put the items in a clipping node.
Here is a visual representation from my game,
This is a menu of 12 items displayed in a grid of 3×2, that is 6 items per page.
To make this work, I would need to use a CCScrollLayer to paginate between each page, each having 3×2 items on them.
Furthermore, I need to put them in a clipping node. By a clipping node I mean something which clips the viewport in which the grid appears in.
Imagine we have a modal pop-up window, or something where we do not want the visuals to “spill over” a certain boundary; this is what we use the clipping node for.
For all of this to work, you will need the following:
+ cocos2d-iphone v2.x (I did not test for 1.x) (cocos2d website)
+ CCScrollLayer (part of the cocos2d-iphone-extensions in github)
+ CCMenu+Layout.h (Tony Ngo)
+ Viewport (https://gist.github.com/agasiev/3908876) or ClippingNode (via cocos2d website)
+ (Optional) CCMenuAdvanced (See: cocos2d-iphone-extensions)
I used Viewport rather than ClippingNode because I couldn’t quite get it to work, whereas I found Viewport used similar code and seemed to work a bit more straightforwardly.
Anyway, my code now follows. It may not necessarily work for you, but should give you some indications of what I did.
#import "Viewport.h"
#import "CCMenu+Layout.h"
#import "CCMenuAdvanced.h"
#import "CCScrollLayer.h"
// Notes
// Apple is a custom item.
// List would be your array of custom objects ie: Apples or whatever
// Display the items in a grid
NSMutableArray *pageArray = [NSMutableArray array];
CCLayer *page = nil;
CCMenu *itemMenu = nil;
int tag = 0;
int count = 0;
// We want a grid of 3x2, this means count must
// reach 6 before making a new page.
for (Apple *apple in list) {
if (count == 0) {
page = [CCLayer node];
itemMenu=[CCMenu menuWithItems:nil];
[itemMenu setContentSize:CGSizeMake(300, 100)];
[itemMenu setAnchorPoint:CGPointMake(0, 0.5)];
[itemMenu setPosition:CGPointMake(80, 90)];
[page addChild:itemMenu];
[pageArray addObject:page];
}
// Avatar Button
CCSprite *avtButton = nil;
// Get the image from the custom object
NSString *fileName = [NSString stringWithFormat:@"%@.png", apple.filename];
avtButton = [AvatarButton spriteWithSpriteFrameName:fileName];
[avtButton setScale:0.75];
// Create menu item
CCMenuItemSprite *btnWG = [CCMenuItemSprite itemFromNormalSprite:avtButton selectedSprite:nil target:self selector:@selector(menuButtonTapped:)];
[btnWG setTag:tag];
[itemMenu addChild:btnWG];
count++;
if (count == 6) {
[itemMenu alignItemsInGridWithPadding:CGPointMake(15, 2) columns:3];
count=0;
}
tag++;
} // next
// Now create the scroller and pass-in the pages (set widthOffset to 0 for fullscreen pages)
self.scroller = [[[CCScrollLayer alloc] initWithLayers:pageArray widthOffset:250] autorelease];
[self.scroller setShowPagesIndicator:YES];
[self.scroller setPagesIndicatorPosition:CGPointMake(335, 100)];
Viewport *cn = [[Viewport alloc] initWithRect:CGRectMake(75,75, 300, 180)];
[cn setAnchorPoint:CGPointMake(0, 0.5)];
[cn addChild:scroller];
[self addChild:cn z:8];
[cn release];
Because we need a grid of 6 items, the `count` variable must reach 6 before “creating” a new page. Each page has it menu aligned to 3 columns.
The page gets added to the pageArray (a list of pages) which are used by the scroller object.
Finally, we create a clipping node and add the scroller as a child of the clipping node’s object before we add the clipping node to self (or it could be a layer).
I’ve been able to test it for 12 items, 6 per page but if you want a custom amount (say 2-4 per page) you must adjust the numbers in the code above to match your expectations.
I hope this helps in your code development.