Wednesday, August 1, 2012

Getting AdMob ads to work with cocos2D Part 2: Handling Autorotation

In the first part of this series, we talked about integrating AdMob ads in a cocos2d application without diminishing performance. However, we conveniently overlooked how you’d go about handling device reorientation. This blog post will outline the two steps necessary for getting autorotation to work using v0.99.5b3 or higher of the cocos2d framework.




Step One: Setting UIKit Autorotation

cocos2d allows you to handle autorotation in two different ways (UIKit and cocos2d). Since we’re working with both UIKit views as well as Open GL views, we want to rely on UIKit autorotation. If not, we’d have to transform our GADBannerView manually. To make sure you’re using UIKit autorotation, set the GAME_AUTOROTATION directive on your platform of choice to kGameAutorotationUIViewController.



Once you’ve done this, check RootViewController.m to make sure shouldAutorotateToInterfaceOrientation: returns YES for all of the orientations that you support. cocos2d produces skeleton code that handles this method differently depending on the autorotation method you’re using, so make sure that you modify the code block where GAME_AUTOROTATION == kGameAutorotationUIViewController.




Step Two: Modifying View Layout

The final step is to modify our resizeViews: method so that it takes the orientation of the device into account when laying out the views. Rewrite resizeViews: as resizeViewForOrientation:, using the orientation parameter to lay out your GADBannerView. The code below, similar to the first blog post, assumes you’re laying out your banner at the top of the screen.




- (void)resizeViewsForOrientation:(UIInterfaceOrientation)toInt {
// If the banner hasn't been created yet, no need for resizing views.
if (!bannerView_) {
return;
}

BOOL adIsShowing = [self.view.subviews containsObject:bannerView_];
if (!adIsShowing) {
return;
}

// Frame of the main RootViewController which we call the root view.
CGRect rootViewFrame = self.view.frame;
// Frame of the main RootViewController view that holds the cocos2d view.
CGRect glViewFrame = [[CCDirector sharedDirector] openGLView].frame;
CGRect bannerViewFrame = bannerView_.frame;
CGRect frame = bannerViewFrame;
// The updated x and y coordinates for the origin of the banner.
CGFloat yLocation = 0.0;
CGFloat xLocation = 0.0;

// Move the root view underneath the ad banner.
glViewFrame.origin.y = bannerViewFrame.size.height;
// Center the banner using the value of the origin.
if (UIInterfaceOrientationIsLandscape(toInt)) {
// The superView has not had its width and height updated yet so
// use those values for the x and y of the new origin respectively.
xLocation = (rootViewFrame.size.height -
bannerViewFrame.size.width) / 2.0;
} else {
xLocation = (rootViewFrame.size.width -
bannerViewFrame.size.width) / 2.0;
}

frame.origin = CGPointMake(xLocation, yLocation);
bannerView_.frame = frame;

if (UIInterfaceOrientationIsLandscape(toInt)) {
// The super view's frame hasn't been updated so use its width
// as the height.
glViewFrame.size.height = rootViewFrame.size.width -
bannerViewFrame.size.height;
glViewFrame.size.width = rootViewFrame.size.height;
} else {
glViewFrame.size.height = rootViewFrame.size.height -
bannerViewFrame.size.height;
}
[[CCDirector sharedDirector] openGLView].frame = glViewFrame;

}


Now that you’re handling rotation, you’re going to have to resize your views in two different places. We’ve already covered this in initGADBanner: in the first post (simply use the interfaceOrientation property of UIViewController to call resizeViewsForOrientation: instead of resizeViews:). Here, we also have to call resizeviewsForOrientation: in willRotateToInterfaceOrientation:duration: as well. You can add this call after the skeleton code that cocos2d provides.



Ads inside your cocos2d application should now stay docked in place whenever device rotations occur. You can check out a full example from this blog post here. As always, feel free to direct any questions you have to our forum or join us for our upcoming hangout.





No comments:

Post a Comment