一.环境准备

1.coco2dx 版本:3.17.2

2.Xcode   版本:14.0.1

3.python  版本 :2.7.14

4. cocos2dx 引擎代码重写部分。 将相应的改动代码,找到代码行,在对应的mac 上新下载的引擎库中一一对应修改。(最好不要直接替换引擎框架,会引起编译失败等奇怪问题。最好具体修改部分,定向重新修改即可。)

5.创建新的项目工程。

a.在终端 cd 打开   /Applications/cocos2d-x-3.17.2/tools/cocos2d-console/bin 该路径。 路径下对应cocos 文件等。 如下:

b.在此文件夹下,执行创建项目命令:./cocos new gameName -p cn.game.package -l cpp -d ~/Desktop

对应含义。 项目名字-p 包名 -l cpp(指定的语言类型,也可以是lua) -d ~/(目标项目的路径,生成位置)

c.运行项目。如下:

4.预览项目。注意,此时,在Mac平台预览运行,会各种报错。可以百度解决。

一个关键错误,当我们在调用SimpleAudioEngine 初始化单利时。会提示,文件不存在,此时需要引入 命名空间 using namespace CocosDenshion;

继续运行时,会发现,无法找到一些关键函数,该函数均在引擎框架之中,但是运行时,无法编译通过。(怀疑时Mac 环境,不是很支持SimpleAudioEngine.h等相关音频操作)。如下:不支持

4.1 此时,需要考虑的是换一个预览环境,所以想到的是模拟器运行,以及真机运行。

a.模拟器运行。如下:模拟机型选择

b.模拟器关键环境配置:如下

c.真机预览调试 如下选择:

真机预览调试时,如果可以正常运行在手机上的空工程,则证明,环境基本OK了。

二:项目移植

1.框架移植。

如果如上一之中,已经在根目录之中将需要重写的部分修改过了,则新构建的项目,会直接copy根目录的框架,无需二次改动。

如果根目录为修改引擎框架,则需要在构建的心的工程之中,将对应需要改动的引擎框架,一并改掉。

2.工程移植。

资源目录,直接替换掉Resources文件夹即可。

Class目录,稳妥的方法,需要在工程之内,Classes目录下,新建group 如下:

根据自己需要的目录结构,新建分组。此时,会在本地文件Classes目录下,生成对应的文件夹。且,目录路径也会被系统自动添加的配置之中。

下一步,在本地目录中,将需要用到的类文件,全部对应的copy到相应的Classer下的文件目录之中。

在Xcode项目中,事先建好的分组中,将对应的本地文件,全部导入到项目中,此时,类文件的配置,会被系统自动配置到项目之中。如下:

导入完以后,在项目的build phases 中可以发现,所有需要用的类文件,已配置到项目中。如下:

下一步:将资源文件,导入到项目之中。上面提到,Resource目录替换过后,还需要导入到项目中,不然,会找不到对应的资源。最好先将已经在项目中的文件先移除,再重新导入。如下:

注意:移除是一定要选中间选项,此时只移除引用,不会删除本地资源。第一个选项,会直接删除本地资源。

经过以上操作之后,Resource中的资源,会被直接引用到项目中,即可直接使用了。如下配置信息:

以上操作之后,基本上,算是移植成功了。现在,可以在模拟器上先运行一下,如果有什么报错信息,可以具体问题,具体修改即可。不出意外,是可以正常在模拟器上运行起来了。

三。真机调试。

真机调试,需要配置对应的版本号,包名,开发这账号,以及启动屏等。如下:

以上配置完整,即可在真机上,进行预览与测试。

四:AppIcon 与 background启动屏。

AppIcon 需要很多不同尺寸的文件,此时,可以找美术拿到一张1024*1024的大图,然后,通过网站,生成各种icon尺寸,选择大图,是防止压缩后失真。

压缩网站:App Icon Maker - Resize App Icon to all sizes for iOS/Android projects.https://appiconmaker.co/Home/Index/d98b81b0-da5c-4dd3-96fe-b4f468d28191

上传一张大图,获取如下效果: 

将压缩后的icon文件下载后,在下图目录中,将资源按照图片大小和名字,替换掉即可。

如上图,右侧为替换后的icon,打包后,在手机上即可看到icon已经替换为我们想要的效果图。

启动屏的替换:

1.根据系统默认的启动屏,我们可以做一个相同尺寸的启动图,替换掉原来的。

2.自定义启动屏。可以如上右图,在启动屏配置信息中,自定义启动图的布局信息等。原理,即:在一个背景底为纯白色的(或者别的颜色)view中,view可以使用gl渲染为白色,白色正中间,加上一个自己需要的logo,然后调整logo的适配位置,通过锚点,左右边距等,设置weight布局等信息。

五:打包

1.如上操作都准备好以后,即可一键打包。如下:

 

打包之后,需要导出ipa 包。到next之时,可以直接一路next。最后,上传ipa包到相应的位置即可。

六:OBject - C 与 C++ 的相互调用,以及混编

1.OC 调用 C++时,只需要将OC的后缀改成.mm 即可像C++一样调用C++ 方法。

2.C++ 调用OC时,只需要将C++的 .cpp 文件后缀改成 .mm后缀 即可在原来C++类文件中使用OC语法调用 OC的方法。

如下案例:

1.需要四个类,分别是C++ 类的 .h 和.mm文件。 头文件和原本的.cpp实现文件 改了后缀名的 .mm文件。   然后是 OC的 .h 和 .m(或者是 .mm) 文件。 如下实现简单的调用关系:

以下是两个C++类

#ifndef EquipmentCtrl_h
#define EquipmentCtrl_hclass EquipmentCtrl : public Ref
{
public:static EquipmentCtrl* getInstance() {static EquipmentCtrl instances;return &instances;}EquipmentCtrl();~EquipmentCtrl();void showStore();//调用app store的评分弹窗private:CC_SYNTHESIZE(std::string, mJavaClassName, JavaClassName);
};#endif // EquipmentCtrl_h
/***************iOS环境中,文件后缀名要改成.mm****************/
/***************android环境中,文件后缀名要改成.cpp****************/
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
#include "CIosTools.h"
CIosTools * gIosTools = [CIosTools getInstance];
#endif#include "EquipmentCtrl.h"
EquipmentCtrl::EquipmentCtrl()
{mLowMemoryEquipment = false;mJavaClassName = "ore/publics/tools/EquipmentData";
}EquipmentCtrl::~EquipmentCtrl()
{
}void EquipmentCtrl::showStore()
{
#if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID//android 环境下需要使用jni调用Android的APIJniHelper::callStaticVoidMethod(mJavaClassName, "showStore");
#elif CC_TARGET_PLATFORM==CC_PLATFORM_IOS//iOS环境下,使用OC语法,调用iOS的API[gIosTools showStore];
#else#endif
}

以下两个是OC文件

//
//  CIosTools.h
//  Created by Racing on 2023/4/23.
//
#ifndef CIosTools_h
#define CIosTools_h
#import<SystemConfiguration/SCNetworkReachability.h>
#import "RootViewController.h"@interface CIosTools : NSObject {int mAppId;}+(CIosTools*) getInstance;
-(void) showStore;                     //打开苹果商店
-(void) showAttLayer;                  //打开iOS14.0以上的广告追踪授权弹窗@end#endif /* CIosTools_h */
//
//  CIosTools.m
//  MagicPiano-mobile
//
//  Created by Racing on 2023/4/23.
//#import <AudioToolbox/AudioToolbox.h>
#import "CIosTools.h"
//#import "Reachability.h"
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/ASIdentifierManager.h>
#import <AdSupport/AdSupport.h>@implementation CIosTools+(CIosTools*) getInstance
{static CIosTools * pThis = nil;if ( pThis==nil){pThis = [[CIosTools alloc] init];}return pThis;
}-(void) showStore{NSString *appID =@"一串appID的数字"; // 替换为你的应用在App Store中的IDNSURL *appStoreURL = [NSURL URLWithString:[NSString stringWithFormat:@"itms- apps://itunes.apple.com/app/id%@", appID]];[[UIApplication sharedApplication] openURL:appStoreURL];
}-(void)ShowAttLayer{if (@available(iOS 14, *)) {[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {// Tracking authorization completed. Start loading ads here.// [self loadAd];NSLog(@"Result request tracking authorization : %lu", (unsigned long)status);// const char* param = [[NSString stringWithFormat:@"%lu",(unsigned long)status] UTF8String];}];} else {// Fallback on earlier versions}
}/****************************************************************/
@end

/************至此,ISO 一套流程基本OK。后续。。。**************/

七:iOS 通过 pod 命令 生成 profile 文件,以及下载sdk

文件格式类似:

通过命令 pod -update 可以下载各个sdk到项目之中。然后需要使用新生成的工程打开;如图:

通过该入口打开工程,否则,可能找不到sdk的库文件配置。

八:iOS 接入 firebase 以及开启debug view 模式

1. 接入firebase

核心代码,引入firebase 库文件,初始化即可。

2。开启debug view 。

如图流程所示,加入-FIRDebugEnabled 。即可开启debug view 模式 ,安装手机运行,即可在firebase 后台实时观测到该机型打点数据。

九:接入appsflyer sdk

十。接入 Max banner广告时,需要获取主要的 展示区域

//
//  AppLovinBannerAdCtrl.h
//  MagicPiano
//
//  Created by Racing on 2023/5/23.
//#ifndef AppLovinBannerAdCtrl_h
#define AppLovinBannerAdCtrl_h
#import <AppLovinSDK/AppLovinSDK.h>
#import "RootViewController.h"@interface AppLovinBannerAdCtrl: NSObject<MAAdViewAdDelegate, MAAdRevenueDelegate>{UIWindow *mTargetWindow;RootViewController *mRootView;MAAdView*mAdView;NSString* mBannderId;bool mSdkIsInitOk;bool mIsinit;
}
+(AppLovinBannerAdCtrl*) getInstance;
-(void) initData;
-(void)setSdkInitIdel:(bool)bol;
//******************banner 广告 ************************//
-(void)createBannerAd;
-(void)requestBanner;
-(void)setBannderVisible:(bool)bol;
-(void) setBannerIsAtTop:(bool) b;
-(void) setIsLandscape:(bool) b;
-(float) getBannerHeight;
-(void) updateBannerPos;-(void)onBannerShow;
-(void)onBannerHide;@end
#endif /* AppLovinBannerAdCtrl_h *//* .mm  *////
//  AppLovinBannerAdCtrl.m
//  MagicPiano-mobile
//
//  Created by Racing on 2023/5/23.
//#import <Foundation/Foundation.h>
#import "AppLovinBannerAdCtrl.h"
#import "AdvertisingCtrl.h"
#include "GameData.h"@implementation AppLovinBannerAdCtrl+(AppLovinBannerAdCtrl*) getInstance
{static AppLovinBannerAdCtrl * pThis = nil;if ( pThis==nil){pThis = [[AppLovinBannerAdCtrl alloc] init];[pThis initData];}return pThis;
}-(void) initData{mBannderId=@"广告ID";mSdkIsInitOk=false;mAdView=nil;mIsinit=false;}-(void)setSdkInitIdel:(bool)bol{mSdkIsInitOk=bol;
}- (void)createBannerAd
{if(!mSdkIsInitOk||mIsinit||mAdView!=nil)return;UIWindow *windowW = [UIApplication sharedApplication].keyWindow;mAdView= [[MAAdView alloc] initWithAdUnitIdentifier: mBannderId];mAdView.delegate = self;// Banner height on iPhone and iPad is 50 and 90, respectivelyCGFloat height = (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) ? 90 : 50;// Stretch to the width of the screen for banners to be fully functionalCGFloat width = CGRectGetWidth(UIScreen.mainScreen.bounds);mAdView.frame = CGRectMake(0, 0, width, height);bool isMin8 = [[UIDevice currentDevice].systemVersion floatValue] < 8.0;int w =  isMin8 ? windowW.frame.size.height:windowW.frame.size.width;int h = isMin8 ? windowW.frame.size.width:windowW.frame.size.height;//bool isDeviceIPhoneX =false;//if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {//    isDeviceIPhoneX= false;//}else//{//    CGSize size = [UIScreen mainScreen].bounds.size;//    NSInteger notchValue = size.width / size.height * 100;//    if (216 == notchValue || 46 == notchValue) {//        isDeviceIPhoneX= true;//    }////}//
//////if(false)//{//    //顶部展示//    int newW=0;//    if(isDeviceIPhoneX)newW=41;//    mAdView.center = CGPointMake( w/2,mAdView.frame.size.height/2+newW);//}//else//{//    //底部展示//    int newW=0;//    if(isDeviceIPhoneX)newW=-0;//    mAdView.center = CGPointMake( w/2,h-mAdView.frame.size.height/2);//}//适配多机型,使得banner可以位于屏幕底部展示mAdView.center = CGPointMake( w/2,h-mAdView.frame.size.height/2-15);// Set background or background color for banners to be fully functional//mAdView.backgroundColor = BACKGROUND_COLOR;mRootView= (RootViewController*)windowW.rootViewController;[mRootView.view addSubview: mAdView];// Load the ad[mAdView loadAd];[mAdView setHidden:true];mIsinit=true;
}#pragma mark - MAAdDelegate Protocol- (void)didLoadAd:(MAAd *)ad {}- (void)didFailToLoadAdForAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(MAError *)error {}- (void)didClickAd:(MAAd *)ad {}- (void)didFailToDisplayAd:(MAAd *)ad withError:(MAError *)error {}#pragma mark - MAAdViewAdDelegate Protocol- (void)didExpandAd:(MAAd *)ad {}- (void)didCollapseAd:(MAAd *)ad {}#pragma mark - Deprecated Callbacks- (void)didDisplayAd:(MAAd *)ad { /* DO NOT USE - THIS IS RESERVED FOR FULLSCREEN ADS ONLY AND WILL BE REMOVED IN A FUTURE SDK RELEASE */ }
- (void)didHideAd:(MAAd *)ad { /* DO NOT USE - THIS IS RESERVED FOR FULLSCREEN ADS ONLY AND WILL BE REMOVED IN A FUTURE SDK RELEASE */ }#pragma mark - MAAdRevenueDelegate Protocol
- (void)didPayRevenueForAd:(MAAd *)ad
{//此处可以监听广告的信息,包含单价等if(ad==nil)return;NSLog(@"Hello AD  placement: %@", ad.networkPlacement);NSLog(@"Hello AD  adUnit: %@", ad.adUnitIdentifier);NSLog(@"Hello AD  netWorkName: %@", ad.networkName);NSLog(@"Hello AD  adCity: %@", @"USD");NSLog(@"Hello AD  adValue: %f", ad.revenue);auto netWorkName = [ad.networkPlacement UTF8String];auto adUnit = [ad.adUnitIdentifier UTF8String];auto adName = [ad.networkName UTF8String];auto adCity = "USD";auto adValue = ad.revenue;GameData::getInstance()->updataADLvInfo(netWorkName, adUnit, adName, adCity, adValue);
}-(void)setBannderVisible:(bool)bol{if(mAdView==nil)return;// Set this extra parameter to work around SDK bug that ignores calls to stopAutoRefresh()[mAdView setExtraParameterForKey: @"allow_pause_auto_refresh_immediately" value:bol?@"true":@"false"];if(bol){[mAdView setHidden:false];[mAdView startAutoRefresh];}else{[mAdView setHidden:true];[mAdView stopAutoRefresh];}}-(void)requestBanner{if(mAdView==nil)return;[mAdView loadAd];
};-(void)setBannerIsAtTop:(bool)b{}
-(void)setIsLandscape:(bool)b{}
-(float)getBannerHeight{return 0.0f;}
-(void)updateBannerPos{}-(void)onBannerShow
{AdvertisingCtrl::getInstance()->setIsBannerShow(true);//__NotificationCenter::getInstance()->postNotification("onBannerShow");
}
-(void)onBannerHide
{AdvertisingCtrl::getInstance()->setIsBannerShow(false);//__NotificationCenter::getInstance()->postNotification("onBannerShow");
}@end

十一: 开屏广告展示,需要在iOS下AppController文件中实现

/****************************************************************************Copyright (c) 2010-2013 cocos2d-x.orgCopyright (c) 2013-2016 Chukong Technologies Inc.Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.http://www.cocos2d-x.orgPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.****************************************************************************/#import <UIKit/UIKit.h>
#import <GoogleMobileAds/GoogleMobileAds.h>@class RootViewController;@interface AppController : NSObject <UIApplicationDelegate, GADFullScreenContentDelegate> {NSString * AD_UNIT_ID_1;NSString * AD_UNIT_ID_2;NSString * AD_UNIT_ID_3;int mCurAdId;
}@property(nonatomic, readonly) RootViewController* viewController;//@property(strong, nonatomic) UIWindow* window;
@property(strong, nonatomic) GADAppOpenAd* appOpenAd;
@property(weak, nonatomic) NSDate *loadTime;
@property(weak, nonatomic) NSDate *backTime;- (void)requestAppOpenAd;
- (void)tryToPresentAd;@end/******** .mm **********/
/****************************************************************************Copyright (c) 2010-2013 cocos2d-x.orgCopyright (c) 2013-2016 Chukong Technologies Inc.Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.http://www.cocos2d-x.orgPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.****************************************************************************/#import "AppController.h"
#import "cocos2d.h"
#import "AppDelegate.h"
#import "RootViewController.h"
#import "GameData.h"@implementation AppController@synthesize window;#pragma mark -
#pragma mark Application lifecycle// cocos2d application instance
static AppDelegate s_sharedApplication;- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {//ce shi idAD_UNIT_ID_1=@"ca-app-pub-3940256099942544/5662855259";AD_UNIT_ID_2=@"ca-app-pub-3940256099942544/5662855259";AD_UNIT_ID_3=@"ca-app-pub-3940256099942544/5662855259";mCurAdId=3;self.backTime =0;cocos2d::Application *app = cocos2d::Application::getInstance();// Initialize the GLView attributesapp->initGLContextAttrs();cocos2d::GLViewImpl::convertAttrs();// 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]];// Use RootViewController to manage CCEAGLView_viewController = [[RootViewController alloc]init];_viewController.wantsFullScreenLayout = YES;// Set RootViewController to windowif ( [[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];}[window makeKeyAndVisible];[self requestAppOpenAd];[[UIApplication sharedApplication] setStatusBarHidden:true];// IMPORTANT: Setting the GLView should be done after creating the RootViewControllercocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView((__bridge void *)_viewController.view);cocos2d::Director::getInstance()->setOpenGLView(glview);//run the cocos2d-x game sceneapp->run();return YES;
}- (void)applicationWillResignActive:(UIApplication *)application {/*Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.*/// We don't need to call this method any more. It will interrupt user defined game pause&resume logic/* cocos2d::Director::getInstance()->pause(); */self.backTime = [NSDate date];}- (void)applicationDidBecomeActive:(UIApplication *)application {/*Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.*/// We don't need to call this method any more. It will interrupt user defined game pause&resume logic/* cocos2d::Director::getInstance()->resume(); */NSDate *now = [NSDate date];NSTimeInterval timeIntervalBetweenNowAndLoadTime = [now timeIntervalSinceDate:self.backTime];if(timeIntervalBetweenNowAndLoadTime<3)return;if(!GameData::getInstance()->getGameIsPlay())[self tryToPresentAd];}- (void)applicationDidEnterBackground:(UIApplication *)application {/*Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. If your application supports background execution, called instead of applicationWillTerminate: when the user quits.*/cocos2d::Application::getInstance()->applicationDidEnterBackground();
}- (void)applicationWillEnterForeground:(UIApplication *)application {/*Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.*/cocos2d::Application::getInstance()->applicationWillEnterForeground();
}- (void)applicationWillTerminate:(UIApplication *)application {/*Called when the application is about to terminate.See also applicationDidEnterBackground:.*/
}#pragma mark -
#pragma mark Memory management- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {/*Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.*/
}#if __has_feature(objc_arc)
#else
- (void)dealloc {[window release];[_viewController release];[super dealloc];
}
#endif/*******sdk******/
- (void)requestAppOpenAd {self.appOpenAd = nil;if(mCurAdId==3){[GADAppOpenAd loadWithAdUnitID:AD_UNIT_ID_1request:[GADRequest request]orientation:UIInterfaceOrientationPortraitcompletionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {if (error) {NSLog(@"Failed to load app open ad: %@", error);mCurAdId--;if(mCurAdId>0){[self requestAppOpenAd];}else{mCurAdId=3;}return;}mCurAdId=3;self.appOpenAd = appOpenAd;self.appOpenAd.fullScreenContentDelegate = self;self.loadTime = [NSDate date];if( GameData::getInstance()->getIsFirstLoadShowOpenAd()&&!GameData::getInstance()->getIsFirstGame()){if(!GameData::getInstance()->getGameIsPlay()){[self tryToPresentAd];GameData::getInstance()->setIsFirstLoadShowOpenAd(false);}}}];}else if(mCurAdId==2){[GADAppOpenAd loadWithAdUnitID:AD_UNIT_ID_2request:[GADRequest request]orientation:UIInterfaceOrientationPortraitcompletionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {if (error) {NSLog(@"Failed to load app open ad: %@", error);mCurAdId--;if(mCurAdId>0){[self requestAppOpenAd];}else{mCurAdId=3;}return;}mCurAdId=3;self.appOpenAd = appOpenAd;self.appOpenAd.fullScreenContentDelegate = self;self.loadTime = [NSDate date];if( GameData::getInstance()->getIsFirstLoadShowOpenAd()&&!GameData::getInstance()->getIsFirstGame()){if(!GameData::getInstance()->getGameIsPlay()){[self tryToPresentAd];GameData::getInstance()->setIsFirstLoadShowOpenAd(false);}}}];}else if (mCurAdId==1){[GADAppOpenAd loadWithAdUnitID:AD_UNIT_ID_3request:[GADRequest request]orientation:UIInterfaceOrientationPortraitcompletionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {if (error) {NSLog(@"Failed to load app open ad: %@", error);mCurAdId--;if(mCurAdId>0){[self requestAppOpenAd];}else{mCurAdId=3;}return;}mCurAdId=3;self.appOpenAd = appOpenAd;self.appOpenAd.fullScreenContentDelegate = self;self.loadTime = [NSDate date];if( GameData::getInstance()->getIsFirstLoadShowOpenAd()&&!GameData::getInstance()->getIsFirstGame()){if(!GameData::getInstance()->getGameIsPlay()){[self tryToPresentAd];GameData::getInstance()->setIsFirstLoadShowOpenAd(false);}}}];}}#pragma mark - GADFullScreenContentDelegate/// Tells the delegate that the ad failed to present full screen content.
- (void)ad:(nonnull id<GADFullScreenPresentingAd>)addidFailToPresentFullScreenContentWithError:(nonnull NSError *)error {NSLog(@"didFailToPresentFullScreenContentWithError");[self requestAppOpenAd];}/// Tells the delegate that the ad will present full screen content.
- (void)adWillPresentFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {NSLog(@"adWillPresentFullScreenContent");
}/// Tells the delegate that the ad dismissed full screen content.
- (void)adDidDismissFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {NSLog(@"adDidDismissFullScreenContent");[self requestAppOpenAd];
}- (BOOL)wasLoadTimeLessThanNHoursAgo:(int)n {NSDate *now = [NSDate date];NSTimeInterval timeIntervalBetweenNowAndLoadTime = [now timeIntervalSinceDate:self.loadTime];double secondsPerHour = 3600.0;double intervalInHours = timeIntervalBetweenNowAndLoadTime / secondsPerHour;return intervalInHours < n;
}- (void)tryToPresentAd {if (self.appOpenAd && [self wasLoadTimeLessThanNHoursAgo:4]) {UIViewController *rootController = self.window.rootViewController;[self.appOpenAd presentFromRootViewController:rootController];} else {// If you don't have an ad ready, request one.[self requestAppOpenAd];}
}@end

十二:iOS 控制台调试

打开Mac  达访中 控制台 程序,在其上选择需要查看机型,运行后,即可看到相应机子的 log 信息等。

cocos2dx-3.17.2 ---- xcode 14.0.1 项目移植相关推荐

  1. Xcode 14.0编译iOS项目出错 ‘sprintf‘ is deprecated

    错误截图: 问题原因: sprintf 被认为是不安全的 解决方法: 1. 在Xcode找到工程的Build Settings,在右边的Filter检索框中输入'compiler flags'. 2. ...

  2. 【tensorflow】安装cuda10.0 and cudnn 7.5.0 and tensorflow-gpu==1.14.0

    安装cuda 的一天 使用实验室同学下载好的cuda安装报错 文件直接传:7zip Data error: 原因是安装文件损坏,重新下载 安装包下载 cuda 10.0版本 官网安装中断: 开了vpn ...

  3. QQ邮箱取消免费扩容;苹果搜索引擎“胎死腹中”,核心成员已回归谷歌麾下;Xcode 14导致应用体积大增|极客头条

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...

  4. 2020年全球自动化装卸车系统(ATLS)收入大约80百万美元,预计2026年达到134.5百万美元,2021至2026期间,年复合增长率为14.0%

    本文研究全球市场.主要地区和主要国家自动化装卸车系统(ATLS)的销量.销售收入等,同时也重点分析全球范围内主要厂商(品牌)竞争态势,自动化装卸车系统(ATLS)销量.价格.收入和市场份额等. 针对过 ...

  5. 美通企业日报 | 陶氏杜邦完成对新陶氏的分拆;英特尔1.17亿美元投资14家创新公司...

    要闻 费列罗将收购家乐氏饼干和水果小吃业务 2018年度亚太区最佳机场贵宾室公布 百乐达斯城全新梦幻主题乐园幻乐堡在韩国开业 陶氏杜邦完成对新陶氏的分拆 英特尔1.17亿美元投资14家创新公司,包括2 ...

  6. Multisim 14.0安装教程---图文讲解

    Hello,大家好,我是霜淮子,今天分享一篇Multisim 14.0的安装教程. 软件介绍 Multisim主要用于专业电子电路设计和电路仿真,并进行虚拟测试.可以在软件中设计电路,输入电流到电路中 ...

  7. 黑苹果引导工具Clover Configurator 5.14.0.0中文版

    Clover Configurator v5.14.0.0 中文版是一款四叶草图形界面配置工具,很多新手对于如何配置Clover很迷茫,因为参数众多也不明白到底是什么意思,Clover Configu ...

  8. 《FLUENT 14.0超级学习手册》——2.5 FLUENT 14.0的基本操作

    本节书摘来自异步社区<FLUENT 14.0超级学习手册>一书中的第2章,第2.5节,作者: 唐家鹏 更多章节内容可以访问云栖社区"异步社区"公众号查看. 2.5 FL ...

  9. Scrapy安装错误:building 'twisted.test.raiser' extension error: Microsoft Visual C++ 14.0 is required.

    问题描述 当前环境win10,python_3.6.1,64位.  在windows下,在dos中运行pip install Scrapy报错: building 'twisted.test.rais ...

最新文章

  1. 深度排序模型在淘宝直播的演进与应用
  2. 初试poi HssfWorkBook导出excel
  3. error java on syntax token_解决Java“syntax error on token enum”问题
  4. Nginx之负载均衡
  5. NgRx Selector 的 Memoization 特性学习笔记
  6. iOS-----线程同步与线程通信
  7. 为什么 Kafka 这么快?
  8. linux vi代码高亮,linux Vi编辑器代码高亮设置及永久显示行号的方法
  9. 骁龙660_骁龙660卖到4000元!这款手机哪里来的自信?
  10. 2005开启服务器文件夹,vss2005图文教你如何安装与配置?
  11. [笔记]三维激光SLAM学习——LiDAR里程计原理推导代码实现
  12. 考勤系统需求分析(软件工程)
  13. 英语练习79 I want to be a doctor
  14. js距离单位换算_javascript实现的平方米、亩、公顷单位换算小程序
  15. iphone11信号强度测试软件,信号差的bug过不去了?来看看iPhone 12 Pro的实际信号测试...
  16. 如何选择适合你的兴趣爱好(二十六),剪纸
  17. 上学最恐怖的事在于上课前点名签到,尤其这个签到脚本更恐怖。
  18. 高斯判别算法GDA(吴恩达机器学习实践总结,四)
  19. 传说中的处男是这样造就的 [zhuan]
  20. 清炖墨鱼汤~熬夜必备

热门文章

  1. 不能让假期变得更长,但整个十月都能让支付宝里的黄金变更大!
  2. python将字符串转换成list或dict对象的方法
  3. ML:置信区间的简介(精密度/准确度/精确度的三者区别及其关系)、使用方法、案例应用之详细攻略
  4. JavaScript冒泡排序的四种方法
  5. combobox 远程url java返回参数_TopJUI可编辑表格的列根据返回数据判断是使用 combobox 还是 numberbox...
  6. 「面试必背」设计模式面试题(收藏)
  7. 国产便宜好用的蓝牙耳机有哪些?盘点四大实惠好用的蓝牙耳机
  8. UG中通过点生成曲面时,dat文件格式
  9. Linux网络系列--网络设置(查看及测试网络,设置网络连接、修改网络配置文件、虚拟机的域名解析配置)
  10. LiquiBase笔记