This is what worked for me to support all 4 orientations. There are steps to this I don't prefer. I did a lot of trial and error to get to this. These directions will assume you are starting with the initial template.
Create a container in the layer for everything to be centered in. Also, make it accessible for the RootViewController (I don't like this and would love an alternative)
HelloWorldScene.h
@interface HelloWorld : CCLayer
{
CCNode *container;
}
@property (nonatomic, readonly) CCNode *container;
// returns a Scene that contains the HelloWorld as the only child
+(id) scene;
@end
HelloWorldScene.m (I am only including init)
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {
// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];
float max = (size.width > size.height) ? size.width : size.height;
//center the container
container = [CCNode node];
container.position = ccp(size.width/2,size.height/2);
//add a background
CCColorLayer *layer = [CCColorLayer layerWithColor:ccc4(128,128,128,255) width:max height:max];
layer.position = ccp(-layer.contentSize.width/2,-layer.contentSize.height/2);
[container addChild:layer];
// create and initialize a Label
CCLabel* label = [CCLabel labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];
// position the label on the center of the screen
label.position = ccp(0,0);
// add the label as a child to this Layer
[container addChild: label];
[self addChild:container];
}
return self;
}
From here I want to allow RootViewController to hold a reference to the container
RootViewController.h
@interface RootViewController : UIViewController {
CCNode *container;
}
@property (nonatomic, retain) CCNode *container;
@end
RootViewController.m
@synthesize container;
I want to next allow RootViewController to support all 4 orientations
RootViewController.m (Update the shouldAutorotateToInterfaceOrientation method for kGameAutorotationUIViewController)
#elif GAME_AUTOROTATION == kGameAutorotationUIViewController
//
// EAGLView will be rotated by the UIViewController
//
// Sample: Autorotate only in landscpe mode
//
// return YES for the supported orientations
return YES;
Here is where I do the work to keep the container in sync with the orientation
RootViewController.m
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(container) {
if(((toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) && self.interfaceOrientation != UIInterfaceOrientationPortrait && self.interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown)
||
((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) && self.interfaceOrientation != UIInterfaceOrientationLandscapeLeft && self.interfaceOrientation != UIInterfaceOrientationLandscapeRight))
{
CGSize size = [[CCDirector sharedDirector] winSize];
container.position = ccp(size.height/2,size.width/2);
container.scaleX = size.height/size.width;
container.scaleY = size.width/size.height;
}
[container runAction:
[CCEaseSineOut actionWithAction:
[CCScaleTo actionWithDuration:duration scale:1.0f]
]
];
}
}
Update the AppDelegate to pass the container to the RootViewController
CCScene *scene = [CCScene node];
HelloWorld *layer = [HelloWorld node];
[scene addChild: layer];
viewController.container = layer.container;
// Run the intro Scene
[[CCDirector sharedDirector] runWithScene: scene];
Update Info.plist to support all rotations, this will allow the app to start in the orientation you are holding it. Otherwise, it will start in portrait and rotate to how you are holding it.
UISupportedInterfaceOrientations (Array value type)
Values:
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
From here when you build to the device you should see Hello World in the center and stays in the center as you rotate. I did all of my testing with an iPad. One thing you will notice is that when you rotate from portrait to landscape is a flicker. I don't really understand the cause of it. This is something that @riq might be to answer. For now a workaround:
update EAGLView.m in function layoutSubviews to comment out "[director drawScene];" (line 194). The comment for this says it avoids a flicker, but only seems to cause one for me.
I do see that there are problems with this solution. For example, if you want to change scenes you would have to update the container in RootViewController. I was hoping this could be a starting point to a better solution.