cocos2dx 添加admob广告错误
在游戏开发中,为游戏添加广告是常见的操作。然而,在使用Cocos2d-x添加AdMob广告时,可能会遇到各种错误。本文将详细介绍这些错误及相应的解决方案。
1. 依照官方教程添加文件及其Framework后运行报错
错误信息
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_ASIdentifierManager", referenced from:
objc-class-ref in libGoogleAdMobAds.a(GADIdentifierUtilities.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_SKStoreProductViewController", referenced from:
objc-class-ref in RevMobAds(RevMobStoreController.o)
"_SKStoreProductParameterITunesItemIdentifier", referenced from:
-[RevMobStoreController openStoreWithITunesItemId:] in RevMobAds(RevMobStoreController.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
解决方案
最终通过添加以下Framework解决问题:
- StoreKit.framework
- AdSupport.framework
- CoreData.framework
2. 继续运行报错
错误信息
ld: duplicate symbol _OBJC_CLASS_$_AppDelegate in /Users/AbhilashReddy/Library/Developer/Xcode/DerivedData/santabantaa-bykvybsbvqshqshfqxdlsxiqhehc/Build/Intermediates/santabantaa.build/Debug-iphonesimulator/santabantaa.build/Objects-normal/i386/AppDelegate-C7A14BE43C5E8C81.o and /Users/AbhilashReddy/Library/Developer/Xcode/DerivedData/santabantaa-bykvybsbvqshqshfqxdlsxiqhehc/Build/Intermediates/santabantaa.build/Debug-iphonesimulator/santabantaa.build/Objects-normal/i386/AppDelegate-A37C3709371E4892.o for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
解决方案
原来是将demo文件夹也包含进来了,删除demo的文件夹Add-ons即可。
3. 再次报错
错误信息
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GADObjectPrivate changeState:]: unrecognized selector sent to instance 0x95c17d0'
解决方案
在应用程序目标的构建设置的Other Linker Flags中添加-ObjC。
4. 全屏AdMob广告显示问题
问题描述
使用以下代码创建全屏AdMob广告时报错:
[[GADBannerView alloc] initWithFrame:self.view.bounds];
错误信息为:errors = "Ad size will not fit on screen"。
将代码改为以下形式可以显示:
[[GADBannerView alloc] initWithFrame:CGRectMake(0,0,320,480)];
但同时使用下半屏的CGRect时,半屏的frame显示不完全,左右被严重压缩,只显示了一个图标和一个按钮,目前尚未找到解决办法。
5. 添加广告的方法
步骤
先添加上述提到的Framework和进行相应的错误处理,然后在AppController.mm中添加以下代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]
pixelFormat: kEAGLColorFormatRGBA8
depthFormat: GL_DEPTH_COMPONENT16
preserveBackbuffer: NO
sharegroup: nil
multiSampling: NO
numberOfSamples:0 ];
// Use RootViewController manage EAGLView
viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
viewController.wantsFullScreenLayout = YES;
viewController.view = __glView;
//------------------- Add Admob
GADBannerView * bannerView_ = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
bannerView_.rootViewController = viewController;
bannerView_.adUnitID = @"a1517648ecd9c44";
GADRequest *request = [GADRequest request];
request.testing = NO;
// request.testDevices = [NSArray arrayWithObjects:
//
// GAD_SIMULATOR_ID,
//
// @"YOU IPAD IDF",
//
// nil];
//----------------------------
// Set RootViewController to window
if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
// warning: addSubView doesn't work on iOS6
[window addSubview: viewController.view];
}
else
{
// use this method on ios6
[window setRootViewController:viewController];
}
[viewController.view addSubview: bannerView_];
[viewController.view bringSubviewToFront:bannerView_];
[window makeKeyAndVisible];
[[UIApplication sharedApplication] setStatusBarHidden: YES];
[bannerView_ loadRequest: request];
cocos2d::CCApplication::sharedApplication()->run();
return YES;
}
添加上述代码后,广告即可显示。
6. 不同Scene切换广告位置的实现方式
实现步骤
定义一个OC类MyAdManager
// MyAdManager.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface MyAdManager : NSObject
{
}
+(void)showAddAtTop;
+(void)showAddAtBottom;
@end
// MyAdManager.m
#import "MyAdManager.h"
#import "myoc.h"
@implementation MyAdManager
+ (void)showAddAtTop {
if (view && size.width > 0) {
[view setFrame:CGRectMake(0, -13, 320, 50)];
}
}
+ (void)showAddAtBottom {
if (view && size.width > 0) {
[view setFrame:CGRectMake(0, size.height - 50, 320, 50)];
}
}
@end
添加全局变量
在myoc.h中添加一个全局的UIView* view和CGSize size:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
UIView* view;
CGSize size;
#endif
创建中间类AdBridge
为了避免修改需要添加广告的Scene的文件后缀(方便Android编译),创建一个中间类AdBridge:
// AdBridge.h
#include <iostream>
class AdBridge{
public:
static void showAdAtTop();
static void showAdAtBottom();
};
// AdBridge.cpp
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#include "MyAdManager.h"
#endif
void AdBridge::showAdAtTop(){
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
[MyAdManager showAddAtTop];
#endif
}
void AdBridge::showAdAtBottom(){
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
[MyAdManager showAddAtBottom];
#endif
}
将AdBridge.cpp后缀改为mm,然后将其添加到需要广告的Scene中。
通过以上步骤,我们可以在Cocos2d-x项目中添加AdMob广告,并实现不同场景下广告位置的切换。然而,全屏和半屏广告显示的问题仍有待进一步解决。