之前写了篇Cocos2d-x 3.X, iOS版添加广点通广告。但是那篇只提到了广告条的集成(有需要的,请戳这里)。不少网友反映出对插屏广告的需求。所以在这里就把插屏广告的集成也写一遍。其实方法是一样的,就是做一个C++类,把它的源文件后缀改成mm,这样就可以把广点通的Objective C指令放里面和C++一起混编。同时它的头文件不含Objective C指令,这样就可以被纯C++文件包含。

本文所用Cocos2d-x为3.9版,Xcode为7.1版,广点通SDK为IOS 4.1版。(插播广告:如需添加安卓版广告请戳这里)

准备工作:

1)进入广点通官网,注册账号。注册时需要上传身份证正反面照片(好像还需要手持身份证照片)以及银行账户。然后等待审核。广点通审核时间略长,大概要一个礼拜。

2)审核通过后就可以创建应用和广告位,并得到应用和广告位ID。这两个ID会被添加到我们的程序当中。

3)下载广点通IOS版SDK。广点通的SDK文件夹里有示例代码和帮助文档Guide 4.1.pdf。可以打开看一看(可以结合本文一起阅读),但是没有针对Cocos2d-x的。

开干正事:

1)新建HelloWorld项目。在搞懂如何添加之前,建议不要直接在自己的工程里面添加,最好新建一个HelloWorld项目用于试验。新建IOS版的HelloWorld项目相对简单。配置好环境变量后,只需一行命令即可完成。这个可以参考Cocos2d-x官方文档。

2)添加广点通SDK。打开下载好的广点通SDK文件夹,将其中libs里面的所有文件都拖入Xcode的HelloWorld项目中(注意libGDTMobSDK.a得放在项目根目录下,如果放在Classes下面链接时会找不到)。

3)添加相应Frameworks。进入Xcode项目的TARGETS部分,选择HelloWorld-mobile,进入Build Phases下的Link Binary With Libraries。往里面添加以下Frameworks:

AdSupport.framework,CoreLocation.framework,QuartzCore.framework (注意官方文档上单词拼写错误,漏了一个t),SystemConfiguration.framework,CoreTelephony.framework,libz.dylib或 libz.tbd,Security.framework,StoreKit.framework

这些都是广点通帮助文档里要求添加的Frameworks。但是这些还不够,还需要往里面添加两个frameworks:GameController.framework和MediaPlayer.framework。具体原因请参考之前的那篇广告条添加(戳这里)。

4)更改导入静态库设置。再次进入Xcode项目的TARGETS部分,选择HelloWorld-mobile,  进入Build Settings下面的Linking部分,往Other Linker Flags里添加两个参数-ObjC和-lstdc++。

以上部分和官方帮助文档Guide 4.1.pdf一致,如有不清楚的地方可以参考官方文档。接下来就不太一样了,请留意。


5)找到RootViewController.h, 令RootViewController继承一个广点通广告条相关协议,以便让RootViewController成为广告的代理。并且为了在测试时监控广告是否加载成功,我们在RootViewController.mm里实现两个协议方法。完整代码如下所示:

RootViewController.h

#import <UIKit/UIKit.h>
#import "GDTMobInterstitial.h"@interface RootViewController : UIViewController<GDTMobInterstitialDelegate> {}
- (BOOL) prefersStatusBarHidden;@end
RootViewController.mm
#import "RootViewController.h"
#import "cocos2d.h"
#import "platform/ios/CCEAGLView-ios.h"static NSString *INTERSTITIAL_STATE_TEXT = @"插屏状态";@implementation RootViewController/***  广告预加载成功回调*  详解:当接收服务器返回的广告数据成功后调用该函数*/
- (void)interstitialSuccessToLoadAd:(GDTMobInterstitial *)interstitial
{NSLog(@"%@:%@",INTERSTITIAL_STATE_TEXT,@"Success Loaded.");
}/***  广告预加载失败回调*  详解:当接收服务器返回的广告数据失败后调用该函数*/
- (void)interstitialFailToLoadAd:(GDTMobInterstitial *)interstitial error:(NSError *)error
{NSLog(@"%@:%@",INTERSTITIAL_STATE_TEXT,@"Fail Loaded." );
}/*// The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {// Custom initialization}return self;
}
*//*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*//*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {[super viewDidLoad];
}*/
// Override to allow orientations other than the default portrait orientation.
// This method is deprecated on ios6
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {return UIInterfaceOrientationIsLandscape( interfaceOrientation );
}// For ios6, use supportedInterfaceOrientations & shouldAutorotate instead
- (NSUInteger) supportedInterfaceOrientations{
#ifdef __IPHONE_6_0return UIInterfaceOrientationMaskAllButUpsideDown;
#endif
}- (BOOL) shouldAutorotate {return YES;
}- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];auto glview = cocos2d::Director::getInstance()->getOpenGLView();if (glview){CCEAGLView *eaglview = (CCEAGLView*) glview->getEAGLView();if (eaglview){CGSize s = CGSizeMake([eaglview getWidth], [eaglview getHeight]);cocos2d::Application::getInstance()->applicationScreenSizeChanged((int) s.width, (int) s.height);}}
}//fix not hide status on ios7
- (BOOL)prefersStatusBarHidden
{return YES;
}- (void)didReceiveMemoryWarning {// Releases the view if it doesn't have a superview.[super didReceiveMemoryWarning];// Release any cached data, images, etc that aren't in use.
}- (void)viewDidUnload {[super viewDidUnload];// Release any retained subviews of the main view.// e.g. self.myOutlet = nil;
}- (void)dealloc {[super dealloc];
}@end

6)新建一个C++类,命名为AdInterC,用来加载和显示广告。注意我们要在Cocos2d-x的场景里生成广告,而Cocos2d-x场景又都是C++代码实现的(主要是因为Cocos2d-x都是以.cpp文件存在,它不支持对Objective C指令的编译),所以必须新建C++类,而非Objective C类。完整代码如下:

AdInterC.h
#ifndef AdInterC_hpp
#define AdInterC_hpp//要被cpp包含,所以不能有任何Objective C指令, 也就是说这里即不能#import GDTMobBannerView.h,
//也不能用@class GDTMobBannerView. 只能通过一个结构体来间接的调用GDTMobBannerView
struct AdInterImpl;class AdInterC
{
public:AdInterC();~AdInterC();void loadAd();//加载广告void showAd();//显示广告private:AdInterImpl* impl;
};
#endif /* AdInterC_hpp */
AdInterC.mm
#include "AdInterC.h"#include "RootViewController.h"struct AdInterImpl
{GDTMobInterstitial * _interObj;
};AdInterC::AdInterC()
{impl = new AdInterImpl();
}
AdInterC::~AdInterC()
{impl->_interObj.delegate=nil;delete impl;
}void AdInterC::loadAd()
{impl->_interObj = [[GDTMobInterstitial alloc] initWithAppkey:@"2211675583" placementId:@"2954362461573316031"];//注意测试的时候就要改成自己申请来的ID,否则很难加载成功auto rootViewController = (RootViewController*) [[[UIApplication sharedApplication] keyWindow] rootViewController];impl->_interObj.delegate = rootViewController; //设置委托impl->_interObj.isGpsOn = NO; //【可选】设置GPS开关 //预加载广告[impl->_interObj loadAd];
}void AdInterC::showAd()
{UIViewController *vc = [[[UIApplication sharedApplication] keyWindow]rootViewController];[impl->_interObj presentFromRootViewController:vc];
}

注意要把app key和placement id改成自己申请来的,否则很难加载成功。另外要把加载方法和显示方法分开。

7)现在就可以愉快的往HelloWorld场景中添加插屏广告了。为了测试,我们在HelloWorld图层里面添加两个菜单项。左边的菜单项按下之后开始加载,右边的菜单项按下之后开始显示。加载需要一定的时间,可以通过观察控制台的输出来监控加载是否成功,然后再去按显示菜单项。否则会报如下错误:[GDTMob::GDTMobInterstitial] Info:Interstitial not ready or already presented!。完整代码如下所示:
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"
#include "AdInterC.h"class HelloWorld : public cocos2d::Layer
{
public:static cocos2d::Scene* createScene();virtual bool init();//加载回调void loadCallback(cocos2d::Ref* pSender);//显示回调void showCallback(cocos2d::Ref* pSender);// implement the "static create()" method manuallyCREATE_FUNC(HelloWorld);AdInterC *ad;
};#endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp
#include "HelloWorldScene.h"USING_NS_CC;Scene* HelloWorld::createScene()
{// 'scene' is an autorelease objectauto scene = Scene::create();// 'layer' is an autorelease objectauto layer = HelloWorld::create();// add layer as a child to scenescene->addChild(layer);// return the scenereturn scene;
}// on "init" you need to initialize your instance
bool HelloWorld::init()
{//// 1. super init firstif ( !Layer::init() ){return false;}//创建一个广告类对象ad=new AdInterC();Size visibleSize = Director::getInstance()->getVisibleSize();Vec2 origin = Director::getInstance()->getVisibleOrigin();/// 2. add a menu item with "X" image, which is clicked to quit the program//    you may modify it.//加载菜单项auto loadItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::loadCallback, this));//显示菜单项auto showItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::showCallback, this));loadItem->setPosition(Vec2(origin.x +  loadItem->getContentSize().width/2 ,origin.y + loadItem->getContentSize().height/2));showItem->setPosition(Vec2(origin.x + visibleSize.width - showItem->getContentSize().width/2 ,origin.y + showItem->getContentSize().height/2));// create menu, it's an autorelease objectauto menu = Menu::create(loadItem, showItem, NULL);menu->setPosition(Vec2::ZERO);this->addChild(menu, 1);/// 3. add your codes below...// add a label shows "Hello World"// create and initialize a labelauto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);// position the label on the center of the screenlabel->setPosition(Vec2(origin.x + visibleSize.width/2,origin.y + visibleSize.height - label->getContentSize().height));// add the label as a child to this layerthis->addChild(label, 1);// add "HelloWorld" splash screen"auto sprite = Sprite::create("HelloWorld.png");// position the sprite on the center of the screensprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));// add the sprite as a child to this layerthis->addChild(sprite, 0);return true;
}void HelloWorld::loadCallback(Ref* pSender)
{ad->loadAd();
}void HelloWorld::showCallback(Ref* pSender)
{ad->showAd();
}

在实际应用过程中,要给加载过程留有一定的时间,比如在游戏过程中就偷偷加载,等到游戏结束时再调用显示插屏方法。
8)编译运行。注意要用真机来运行,否则也是很难加载成功(不知道为啥)。在按下左边的加载按钮时稍等片刻,看到控制台显示加载成功后再去按右边的显示按钮。结果如下所示:

  
已经将横屏调成了竖屏。并且在申请广点通广告位ID时,勾选了小规格和大规格两种插屏广告。如果在运行时遇到如下报错:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
这是因为IOS9新增了App Transport Security特性,默认使用HTTPS协议,如果在IOS9下直接进行HTTP请求就会报错。解决方法就是关闭这个特性: 进入项目TARGETS下的HelloWorld-mobile,找到info下的Cumstom ios Target Properties, 添加App Transport Security Settings,将其下面的Allow Arbitrary Loads设置为Yes。但貌似插屏广告没有这个问题。

水平有限,如有不妥,欢迎指正!

参考资料:

1)广点通官方文档Guide 4.0.pdf

2)  广大网友

Cocos2d-x 3.X, IOS版添加广点通插屏广告相关推荐

  1. Cocos2d-x 3.X, IOS版添加广点通广告平台

    苹果自己的广告平台iAD在中国不好使,获取不到广告,所以必须搞个本土广告平台.首先想到的是广点通.可是广点通官方文档里没有针对Cocos2d-x的版本,所以只好自己摸索.在添加过程中确实遇到了不少问题 ...

  2. Cocos2d-x 3.X, Android Studio版添加广点通广告平台

    考虑到以下两点: 1. Cocos2d-x从3.7版开始优化对Android Studio的支持,相信这一趋势还会继续.可惜目前相关帮助文档还不完善,很多东西需要自己摸索. 2. 广点通广告平台的官方 ...

  3. android广告弹窗插屏,cocos2dx android添加广点通广告平台的---插屏广告

    方式一: 1. 在cocos2dx编译完成的项目(proj.android)加入 GDTUnionSDK.4.8.524.min.jar广点通jar包. 2. 添加权限声明 3.添加activity, ...

  4. unity3d 5.2 添加广点通广告

    今天向项目中添加插屏广告.之前找了一圈,看评论说腾讯的广点通还可以,于是决定放弃有米,试试. 回到正题,之前还没试过用unity3d和java交互.于是先找了一圈的资料.这里先BS下腾讯,你妹的有的是 ...

  5. 腾讯广点通开屏广告错误码

    Android SDK错误码 错误码 错误类型 描述 3XX 具体类型可联系GDT移动联盟排查 初始化错误 403 HTTP_STATUS_ERROR HHTP状态码错误:建议检查网络状态 404 T ...

  6. IOS版添加phonegap-银联支付插件教程

    2019独角兽企业重金招聘Python工程师标准>>> 1.下载插件包,将UPPayPlugin文件里面的拖放到你的xcode的根目录下面,同时选择拷贝到目录下面. 2.拷贝src里 ...

  7. IOS版添加phonegap-视频播放插件教程

    2019独角兽企业重金招聘Python工程师标准>>> 插件集成过程: 1.配置Target链接参数 选择 Build Settings | Linking | Other Link ...

  8. android 腾讯广告接入,cocos2dx 3.x android studio 添加广点通广告

    1,接入广告条 按照官方文档接入的时候遇到个问题,官方文档中是使用的布局文件来显示广告条,但是cocos2dx 没有使用布局文件,所以这里需要我们在代码中手动创建一个布局容器来显示广告条,代码如下: ...

  9. Unity3D使用腾讯广点通广告

    目前,游戏开发平台有很多,今天咱们主要介绍Unity3d开发的Android游戏加广点通广告. 1. 下载广点通SDK 广点通网址:http://e.qq.com/dev/index.html 在 流 ...

最新文章

  1. YOLOS:重新思考Transformer的泛化性能
  2. mysql会话级表_php – MySQL会话表方法
  3. win下手工启停数据库
  4. SAP Spartacus login 页面看不到 UI 控件的问题解决
  5. JS使用XMLHttpRequest对象POST收发JSON格式数据
  6. 神经网络激活函数=生物转换器?
  7. java数值加法null得到什么,fastjson 处理null值,对象为null时返回{},数字为null返回[]...
  8. html-webpack-plugin 中使用 title选项设置模版中的值无效
  9. 一直在构建版本_教你如提升Gradle90%的构建速度
  10. matlab 程序运行报错 调试 不退出函数
  11. Android 网络管理
  12. IT 架构测试之基础架构运维测试简介
  13. 二叉树叶子结点个数统计
  14. 2020 全国省份数据整理
  15. Excel绘制折线图--更新中。。。
  16. 做外贸如何防止邮箱被封?已解决!
  17. canvas画线变粗变模糊的解决办法
  18. ElasticSearch 聚合查询 JavaApi
  19. 淘宝API接口:item_get_app - 获得淘宝app商品详情原数据
  20. Spring Kafka的Offset提交时机

热门文章

  1. 安卓统一推送联盟成立!不卡顿的安卓系统终于来了!
  2. 机顶盒ttl无法输入_连接TTL线后无法输入代码、不跑码乱码的解决方法
  3. Android Studio WiFi 之 获取 WiFi 名称、IP、Mac
  4. 装修项目细节工程队实时监督签到系统有哪些
  5. 数字基本单位及2或10的幂次方
  6. 信息技术的分类方法有哪些?
  7. c++逆天改命进阶--多态
  8. WinForm中新开一个线程操作窗体上的控件(跨线程操作控件)GOOD
  9. 集合长度可变的实现原理(解析为什么集合长度可变)
  10. 什么是 “VLAN” ?