Cocos Creator游戲集成到原生iOS及JS和OC交互

文章主要參考:https://blog.csdn.net/xjw532881071/article/details/108715666 ,在原來基礎(chǔ)上,根據(jù)自己的集成經(jīng)驗(yàn)進(jìn)行了完善

1:獲取到Cocos Creator構(gòu)建的iOS工程

這一步主要是Cocos Creator開發(fā)工程師提供,最后給到我們的是構(gòu)建好的


image.png

jsb-default文件夾下的內(nèi)容就是我們iOS開發(fā)需要的代碼了

2.運(yùn)行jsb-default下的iOS工程

這一步的作用是為了驗(yàn)證構(gòu)建的工程是沒有問題的,同時(shí)獲取到我們這個(gè)工程集成到iOS需要的配置是哪些.

image.png

通過以上路勁,運(yùn)行iOS項(xiàng)目hello_world.xcodeproj,進(jìn)行證書配置,然后采用真機(jī)運(yùn)行,如果能夠正常運(yùn)行,說明構(gòu)建的iOS工程是沒有問題的.

得到一個(gè)能夠正常運(yùn)行的工程非常重要,非常重要,非常重要!!!因?yàn)槲覀冊(cè)谧约旱膇OS工程中集成Cocos Creator游戲用到的配置信息都是從這個(gè)工程中是查找的.

3.真正的集成開始

3.1 導(dǎo)入游戲代碼到iOS原生工程

在工程目錄下創(chuàng)建 cocos 文件夾, 然后找到之前游戲構(gòu)建的代碼,復(fù)制到cocos文件夾下,這里的jsb-default就是cocos項(xiàng)目構(gòu)建成功后的代碼:

image.png

注:frameworks中,可以只導(dǎo)入frameworks-->runtime-src-->proj.ios_mac + Classes , proj.android-studioproj.win32 可以不導(dǎo)入

3.2 導(dǎo)入游戲代碼到iOS原生工程

打開iOS原生工程,導(dǎo)入cocos下的文件和文件夾.這里要注意文件夾的黃色(group)和藍(lán)色(fold references)區(qū)別锋八。
以藍(lán)色fold references導(dǎo)入assets轰豆、cocos2d_libs.xcodeproj;

新建一個(gè)名為CocosResources的group泻蚊,并以fold references模式導(dǎo)入main.js怒炸、project.json参萄、src逃延、jsb-adapter到其中;

以黃色group模式導(dǎo)入ios拖叙、Classes文件夾;

注:如果沒有cocos2d_libs.xcodeproj,找cocos開發(fā)工程師構(gòu)建(就是構(gòu)建時(shí)勾選default,不是link)

結(jié)果如下:


Pasted Graphic 2.png

3.3 工程中移除ios文件夾下的main.m

image.png

3.4 導(dǎo)入項(xiàng)目的依賴庫(kù)

這里我們就需要使用到之前運(yùn)行起來的cocos下生產(chǎn)的工程了,去里面找依賴庫(kù),我的如下:


image.png

把庫(kù)全部導(dǎo)入即可, .lib的文件,直接采用tbd代替;

3.5 導(dǎo)入libcocos2d iOS(cocos2d_libs)

為原生iOS工程的TARGETS添加Dependences(Build Phase/Dependencies):libcocos2d iOS(cocos2d_libs),有兩處都要添加

image.png

注:如果刪除了cocos下的文件夾,重新導(dǎo)入了,可能會(huì)導(dǎo)致 libcocos2d iOS丟失,需要再次按照上面的流程重新導(dǎo)入一次,不然報(bào)錯(cuò): cocos的一些方法找不到了;

3.6 工程配置

  • 參考cocos導(dǎo)出的iOS工程為原生工程的PROJECT添加以下頭文件搜索路徑(Build Settings/Search Paths/User Header Search Paths), (SRCROOT)為相對(duì).xcodeproj文件的路徑, Always Search User Paths設(shè)為Yes
    Pasted Graphic 5.png

注:以上的User Header Search Paths中的配置要參考之前cocos導(dǎo)出的iOS工程,同時(shí)請(qǐng)驗(yàn)證路徑是否正確,我的如下:

Pasted Graphic 6.png

這里需要100%確認(rèn)正確,不然會(huì)出現(xiàn)一堆的問題;

  • 參考cocos導(dǎo)出的iOS工程為原生工程的TARGETS添加以下頭文件(搜索路徑:Build Settings/Search Paths/User Header Search Paths)

  • 同時(shí)把Always Search User Paths設(shè)為Yes;

  • TARGETS下,為Library Search Paths添加:
    $(SRCROOT)/cocos/frameworks/cocos2d-x/external/iOS/libs

cocos/frameworks/cocos2d-x/external/iOS/libs這個(gè)路徑自己驗(yàn)證下,如果你創(chuàng)建的也是cocos文件夾,就是一樣的,反正找到libs就行;

Pasted Graphic 8.png
  • 為TARGETS為other linker flags 添加 -Objc

  • 把PROJECT和TARGETS的Enable BitCode都設(shè)為NO

  • 分別修改PROJECT紊撕、TARGETS下C Language Dialectgnu11

注:這里的gnu11是我的工程的,根據(jù)自己的cocos的工程查找到對(duì)應(yīng)的,去配置

  • 在PROJECT和TARGETS為Preprocessor Macros添加預(yù)定義宏 ,具體看工程,所有的宏也根據(jù)自己的cocos的工程查找到對(duì)應(yīng)的
image.png

3.7 工程代碼的修改

  • 修改Classes文件夾下的AppDelegate.hAppDelegate.cpp
    把名稱改成CocosAppDelegate.hCocosAppDelegate.cpp,把代碼內(nèi)的AppDelegate全部替換成CocosAppDelegate

    image.png

  • 修改Classes文件夾下的 CocosAppDelegate.cppjsb_module_register.cpptype,改成Objective-C++ (這是一個(gè)巨坑,如果你的代碼在不修改的情況下,能正常運(yùn)行,就保持原C++,如果是報(bào)錯(cuò)就改成Objective-C++,個(gè)人感覺這個(gè)應(yīng)該和我們后面配置的gnu11 或者 C99有關(guān))

    Pasted Graphic 9.png

  • 把ios文件夾下的AppController.mm內(nèi)的#import "AppDelegate.h"改成#import "CocosAppDelegate.h",把下面的app = new CocosAppDelegate(bounds.size.width * scale, bounds.size.height * scale); app->setMultitouch(true);改掉

    image.png

  • 很重要的一點(diǎn),前面忘記提了,之前classes文件下的文件改名后,建議是刪除掉,重新導(dǎo)入一次,不然會(huì)出現(xiàn)報(bào)錯(cuò)或者運(yùn)行完界面黑屏 !!!! (PS:Target-->Build Phases-->Compile Sources)

  • 修改 目錄: cocos2d_libs—>platform——>iOS下的 CCApplication-ios.mm 文件的end方法入下(322行)

void Application::end()
{
    //    delete this;
       //
       //    exit(0);
       
       // 上面是原來的樣子
   #if USE_AUDIO
       AudioEngine::end();
   #endif
       // stop main loop
       [(MainLoop*)_delegate stopMainLoop];
 
}

修改它的目的是為了cocos引擎在啟動(dòng)后,退出游戲不自動(dòng)關(guān)閉引擎,不殺死APP,再次進(jìn)入游戲,可以直接開始游戲了,更加的快速;

3.8 搭建游戲引擎交互界面,游戲界面VC

搭建 CocosMng,這里面包括了所有的JS調(diào)用OC的方法,OC調(diào)用JS的方法,有參數(shù),無參數(shù),多個(gè)參數(shù)等的方法調(diào)用,這個(gè)CocosMng類名需要提供給cocos開發(fā)人員,里面注釋的方法不是不能用,而是要看cocos給的方法的參數(shù)是如何的,是讓我們傳一個(gè)int,一個(gè)string,還是多個(gè)字符串還是json字符串:

//
//  CocosMng.h
//
//  cocos引擎管理器黑滴,負(fù)責(zé)iOS啟動(dòng)憨募、退出以及管理cocos引擎
/*
 
 類名不要改變,對(duì)應(yīng)cocos的JS調(diào)用OC的類名;
 所有的供JS調(diào)用的方法,使用類方法;
 所有的OC調(diào)用的JS方法,統(tǒng)一寫在CocosMng下;
 
 */

#ifndef CocosMng_h
#define CocosMng_h

#import <UIKit/UIKit.h>

#include "platform/ios/CCEAGLView-ios.h"

@protocol CocosMngDelegate <NSObject>

//游戲開始
-(void)cocosGameStart;
//返回游戲分?jǐn)?shù)
-(void)cocosgameEnd:(int)score;
//退出游戲
-(void)cocosGameClose;


@end


@interface CocosMng : NSObject
{
}

@property(nonatomic, retain) UIViewController* viewController;

@property (nonatomic, weak) id <CocosMngDelegate> delegate;

+(instancetype)getInstance;
+(void) destroyInstance;
-(instancetype)init;
-(void)startCocos; // 啟動(dòng)cocos游戲引擎
-(void)exitCocos;  // 退出cocos游戲引擎
+(void)exitCocosForJS;   // 給js調(diào)用,js只能調(diào)用靜態(tài)方法

+(CCEAGLView *)getCocosView;

-(void)didEnterBackground;  // app進(jìn)入后臺(tái)時(shí)調(diào)用袁辈,通知游戲js層
-(void)willEnterForeground; // app返回前臺(tái)時(shí)調(diào)用, 通知游戲js層
-(void)willTerminate;


//oc 調(diào)用 js  測(cè)試
-(void)testOCForJS;


-(void)gamePauses;//游戲暫停
-(void)gameContinue;//游戲繼續(xù)
-(void)gameOver;//游戲結(jié)束


#pragma mark 初始化參數(shù)設(shè)置
-(void)gameInitDataSet:(NSDictionary *)data;

#pragma mark fish 給JS調(diào)用的方法
//初始化配置,此方法被調(diào)用后,需要調(diào)用recvDataFromNativeWithData把初始化參數(shù)傳遞給JS
+(void)initGameVC;

//游戲開始
+(void)game_GetStar_Start;
//返回游戲分?jǐn)?shù)
+(void)game_GetStar_end:(int)score;
//退出游戲
+(void)closeGameVC;

#pragma mark fish OC調(diào)用JS的方法
//log輸出:printlog
-(void)printlog:(NSString *)logString;
//初始化方法recvDataFromNative(historyMaxFraction, model, max, min)
-(void)recvDataFromNativeWithData:(NSDictionary *)dataDic;
//接收肌電值數(shù)據(jù)onRecvFly(s)
-(void)onRecvFly:(int)num;
//導(dǎo)聯(lián)脫落onDaoLianRecv
-(void)onDaoLianRecv:(BOOL)recv;
//電極脫落onDianJiRecv
-(void)onDianJiRecv:(BOOL)recv;

@end


#endif /* CocosMng_h */

#import "CocosMng.h"

#import "cocos2d.h"
#import "CocosAppDelegate.h"
#import "SDKWrapper.h"
#import "platform/CCApplication.h"
#import "platform/ios/CCEAGLView-ios.h"
#import "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#import "CRBeeGameController_new.h"

using namespace cocos2d;

static CocosMng * _instance = NULL;
static Application * _app = NULL;

@interface CocosMng ()

@property (nonatomic, strong) NSDictionary *gameData;

@end

@implementation CocosMng


+(instancetype)getInstance {
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        _instance = [[self alloc] init];
//    });
    
    if (!_instance) {
        _instance = [[CocosMng alloc]init];
    }
    
    return _instance;
}

+(void) destroyInstance {
    if (_instance != NULL) {
        _instance = NULL;
    }
}

+(CCEAGLView*)getCocosView {
    return (__bridge CCEAGLView *)cocos2d::Application::getInstance()->getView();
}

-(instancetype)init {
    self = [super init];
    if (self) {
        float scale = [[UIScreen mainScreen] scale];
        CGRect bounds = [[UIScreen mainScreen] bounds];
        // cocos2d application instance
        if (_app == NULL) {
            _app = new CocosAppDelegate(bounds.size.width * scale, bounds.size.height * scale);
            _app->setMultitouch(false);
        }
        
//        [self setupCocos];
    }
    
    return self;
}

//-(void)setupCocos {
//    self.viewController = [[CRBeeGameController_new alloc]init];
//    [self.viewController setModalPresentationStyle:UIModalPresentationFullScreen];
//}

-(void)startCocos {
    NSLog(@"start cocos.");
    
    _app->restart();
    return;
}

+ (void)exitCocosForJS {
    [[CocosMng getInstance]exitCocos];
}

- (void)exitCocos {
    if (_app == NULL) {
        return;
    }
    
    _app->end(); // mark: 這里修改了CCApplication-ios.mm菜谣,end不再直接退出游戲而是只停止主循環(huán)和音頻播放
    [self.viewController dismissViewControllerAnimated:YES completion:NULL];
}

-(void)didEnterBackground {
    if (_app != NULL) {
        _app->onPause();
    }
}

-(void)willEnterForeground {
    if (_app != NULL) {
        _app->onResume();
    }
}

-(void)willTerminate {
    [self.viewController dismissViewControllerAnimated:YES completion:NULL];
    [CocosMng destroyInstance];
}

//oc 調(diào)用 js
-(void)testOCForJS{
//    NSLog(@"%s",__func__);
//    std::string strRet = "hahaha";
//    std::string jsCallStr = cocos2d::StringUtils::format("onGameStop();"); //Main.js
//    se::Value *ret = new se::Value();
//    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret);
//    NSLog(@"jsCallStr rtn = %s", ret->toString().c_str());
    
    
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //測(cè)試  -->OC調(diào)用 JS 的方法 'window.testMethod'
        NSLog(@"OC調(diào)用 JS 的方法");
        std::string strRet = "hahaha";
        std::string jsCallStr = cocos2d::StringUtils::format("window.onGameStop();"); //gamectrl
        se::Value *ret = new se::Value();
        se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret);
        NSLog(@"jsCallStr rtn");
//    });
    
    
    
}
/*
 1.std::string轉(zhuǎn)NSString

 std::string _string("hello");
 NSString *str= [NSString stringWithCString:_string.c_str() encoding:[NSString defaultCStringEncoding]];

 2.NSString轉(zhuǎn)std::string
 NSString  * nsfaceName=@"HELLO";
 const char  *  lpfaceName = [nsfaceName UTF8String];
 std::string   strFaceName=  [nsfaceName UTF8String];

 */

#pragma mark 游戲暫停
-(void)gamePauses{
    std::string strRet = "hahaha";
    std::string jsCallStr = cocos2d::StringUtils::format("window.onGameStop();"); //gamectrl
    se::Value *ret = new se::Value();
    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret);
    
    
}
#pragma mark 游戲繼續(xù)
-(void)gameContinue{
    std::string strRet = "hahaha";
    std::string jsCallStr = cocos2d::StringUtils::format("window.onGameResume();"); //gamectrl
    se::Value *ret = new se::Value();
    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret);
}
#pragma mark 游戲結(jié)束
-(void)gameOver{
    std::string strRet = "hahaha";
    std::string jsCallStr = cocos2d::StringUtils::format("window.onGameOver();"); //gamectrl
    se::Value *ret = new se::Value();
    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret);
    
}

#pragma mark fish 給JS調(diào)用的方法
//初始化配置,此方法被調(diào)用后,需要調(diào)用recvDataFromNativeWithData把初始化參數(shù)傳遞給JS
+(void)initGameVC{
    NSLog(@"游戲初始化中~~~~~~~");
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [_instance recvDataFromNativeWithData:_instance.gameData];
//    });
    
}

//游戲開始
+(void)game_GetStar_Start{
    NSLog(@"游戲開始~~~~~~~");
    if (_instance.delegate && [_instance.delegate respondsToSelector:@selector(cocosGameStart)]) {
        [_instance.delegate cocosGameStart];
    }
}
//返回游戲分?jǐn)?shù)
+(void)game_GetStar_end:(int)score{
    NSLog(@"游戲分?jǐn)?shù)~~~~~~~%d",score);
    if (_instance.delegate && [_instance.delegate respondsToSelector:@selector(cocosgameEnd:)]) {
        [_instance.delegate cocosgameEnd:score];
    }
}
//退出游戲
+(void)closeGameVC{
    NSLog(@"游戲退出,關(guān)閉界面~~~~~~~");
    if (_instance.delegate && [_instance.delegate respondsToSelector:@selector(cocosGameClose)]) {
        [_instance.delegate cocosGameClose];
    }
}

#pragma mark 初始化參數(shù)設(shè)置
-(void)gameInitDataSet:(NSDictionary *)data{
    if (data) {
        _instance.gameData = [data copy];
    }else{
        //未賦值的情況下,給默認(rèn)初值
        _instance.gameData =  @{
            @"historyMaxFraction":@(200),
            @"model":@(1),
            @"max":@(40),
            @"min":@(10)
        };
    }
}

#pragma mark fish OC調(diào)用JS的方法
//log輸出:printlog
-(void)printlog:(NSString *)logString{
    std::string strRet = [logString UTF8String];//"haha";
    std::string jsCallStr = cocos2d::StringUtils::format("window.printlog(\"%s\");", strRet.c_str());
    se::Value *ret = new se::Value();
    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret);
}
//初始化方法recvDataFromNative(historyMaxFraction, model, max, min)
-(void)recvDataFromNativeWithData:(NSDictionary *)dataDic{
    NSString *hisScore = [NSString stringWithFormat:@"%@",dataDic[@"historyMaxFraction"]];
    NSString *model = [NSString stringWithFormat:@"%@",dataDic[@"model"]];
    NSString *max = [NSString stringWithFormat:@"%@",dataDic[@"max"]];
    NSString *min = [NSString stringWithFormat:@"%@",dataDic[@"min"]];
    std::string hisScoreRet = [hisScore UTF8String];
    std::string modelScoreRet = [model UTF8String];
    std::string maxScoreRet = [max UTF8String];
    std::string minScoreRet = [min UTF8String];
    std::string jsCallStrNew = cocos2d::StringUtils::format("window.recvDataFromNative2(\"%s\",\"%s\",\"%s\",\"%s\");", hisScoreRet.c_str(),modelScoreRet.c_str(),maxScoreRet.c_str(),minScoreRet.c_str());
    se::ScriptEngine::getInstance()->evalString(jsCallStrNew.c_str());
    
    
//    int historyMaxFraction = [dataDic[@"historyMaxFraction"] intValue];
//    int model = [dataDic[@"model"] intValue];
//    int max = [dataDic[@"max"] intValue];
//    int min = [dataDic[@"min"] intValue];
//    NSLog(@"初始參數(shù):%d,%d,%d,%d",historyMaxFraction,model,max,min);
//
////    std::string jsCallStr = cocos2d::StringUtils::format("window.recvDataFromNative(\"%d,%d,%d,%d\");", historyMaxFraction,model,max,min);
//    std::string jsCallStr = cocos2d::StringUtils::format("window.recvDataFromNative(\"%d\",\"%d\",\"%d\",\"%d\");", historyMaxFraction,model,max,min);
//
//    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
   
    
}
//接收肌電值數(shù)據(jù)onRecvFly(s)
-(void)onRecvFly:(int)num{
    std::string jsCallStr = cocos2d::StringUtils::format("window.onRecvFly(\"%d\");", num);
    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
}
//導(dǎo)聯(lián)脫落onDaoLianRecv
-(void)onDaoLianRecv:(BOOL)recv{
    std::string jsCallStr = cocos2d::StringUtils::format("window.onDaoLianRecv(\"%d\");", recv == 0?false:true);
    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
}
//電極脫落onDianJiRecv
-(void)onDianJiRecv:(BOOL)recv{
    std::string jsCallStr = cocos2d::StringUtils::format("window.onDianJiRecv(\"%d\");", recv == 0?false:true);
    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
}

//
//- (void)statusBarOrientationChanged:(NSNotification *)notification {
//    if (_app == NULL) {
//        return;
//    }
//
//    CGRect bounds = [UIScreen mainScreen].bounds;
//    float scale = [[UIScreen mainScreen] scale];
//    float width = bounds.size.width * scale;
//    float height = bounds.size.height * scale;
//    Application::getInstance()->updateViewSize(width, height);
//}
//
//- (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.
//     */
//    if (_app == NULL) {
//        return;
//    }
//
//    _app->onPause();
//    [[SDKWrapper getInstance] applicationWillResignActive:application];
//}
//
//- (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.
//     */
//    if (!_app) {
//        return;
//    }
//
//    _app->onResume();
//    [[SDKWrapper getInstance] applicationDidBecomeActive:application];
//}
//
//- (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.
//     */
//    if (!_app) {
//        return;
//    }
//
//    [[SDKWrapper getInstance] applicationDidEnterBackground:application];
//}
//
//- (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.
//     */
//    if (!_app) {
//        return;
//    }
//
//    [[SDKWrapper getInstance] applicationWillEnterForeground:application];
//}
//
//- (void)applicationWillTerminate:(UIApplication *)application
//{
//    if (!_app) {
//        return;
//    }
//
//    [[SDKWrapper getInstance] applicationWillTerminate:application];
////    delete _app;
////    _app = nil;
//}
//
//#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.
//     */
//    NSLog(@"%s",__func__);
//}
//

@end



搭建游戲VC:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface GameViewController : UIViewController
{
    
}
- (BOOL)prefersStatusBarHidden;
@end

NS_ASSUME_NONNULL_END
#import "GameViewController.h"
#import "CocosMng.h"
#import "AppDelegate.h"

#import "platform/ios/CCEAGLView-ios.h"
#import "SDKWrapper.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#import "cocos2d.h"
//#import "AppDelegate.h"


@interface GameViewController ()

@end

@implementation GameViewController

//- (void) loadView {
//    UIView *cocosViw = [CocosMng getCocosView];
//    if (cocosViw != nil) {
//        self.view = [CocosMng getCocosView];
//    } else {
//        NSLog(@"初始化cocos view失敗!");
//        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//            [self dismissViewControllerAnimated:YES completion:NULL];
//        });
//    }
//}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor redColor];
    NSLog(@"---%s", __func__);
    
    // Do any additional setup after loading the view.
    // 支持多個(gè)view
//    self.view.backgroundColor = [[UIColor alloc] initWithRed:160 / 255.0 green:140 / 255.0 blue:255 / 255.0 alpha:1];
//    self.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"上課背景圖"].CGImage);
//    //    ((GLKView *)self.view).delegate = self;
//    if ([[UIDevice currentDevice].model isEqualToString:@"iPhone"]) {
//        self.view.layer.contents = nil;
//        self.view.backgroundColor = [UIColor blackColor];
//    }
    
//    UIView *videoView = [[UIView alloc] initWithFrame:CGRectMake(50, 70, 150, 150)];
//    [self.view addSubview:videoView];
//    videoView.tag = kPTGameVideoPlayerViewTag;
    
    UIView *_cocosView = [CocosMng getCocosView];
    if (_cocosView == NULL) {
        NSLog(@"創(chuàng)建cocos view失敗!");
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self dismissViewControllerAnimated:true completion:NULL];
        });
        return;
    }
    _cocosView.frame = self.view.bounds;
    _cocosView.backgroundColor = UIColor.clearColor;
    [self.view addSubview:_cocosView];
    
    
//    UIView *courseVideoView = [[UIView alloc] initWithFrame:CGRectZero];
//    [self.view addSubview:courseVideoView];
//    courseVideoView.tag = kPTGameCourseVideoPlayerViewTag;
    
//
    
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        [PTNativeFunc showNoRecordToast:@"為保證您的上課體驗(yàn)尾膊,建議您使用更高性能的設(shè)備上課媳危!"];
//    });
    
//    [PTNativeFunc onNetBlock:^{
//        [PTCocos2D onNoNetShowDialog];
//    }];
    
    [[UIApplication sharedApplication] setStatusBarHidden:true];
    
    
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        NSLog(@"游戲暫停-------->");
//        [[CocosMng getInstance] gamePauses];
//    });
//    
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(20 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        NSLog(@"游戲繼續(xù)-------->");
//        [[CocosMng getInstance] gameContinue];
//    });
//    
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        NSLog(@"游戲結(jié)束-------->");
//        [[CocosMng getInstance] gameOver];
//    });
    
    
}

- (BOOL)prefersStatusBarHidden {
     return YES;
}

- (BOOL)prefersHomeIndicatorAutoHidden {
    return YES;
}

#pragma mark - 橫屏設(shè)置
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self checkLandscapeRight];
}
- (void)checkLandscapeRight {
    [self switchNewOrientation:UIInterfaceOrientationLandscapeRight];
}

void switchNewOrientation(UIInterfaceOrientation interfaceOrientation)
{

    NSNumber *orientationTarget = [NSNumber numberWithInt:interfaceOrientation];

    [[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
    
}

- (void)switchNewOrientation:(UIInterfaceOrientation)orientation
{
//    AppDelegate * appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
//    //允許轉(zhuǎn)成橫屏
//    appDelegate.allowRotation = orientation != UIInterfaceOrientationPortrait;
    //調(diào)用橫屏代碼
    switchNewOrientation(orientation);

}


- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    NSLog(@"---%s", __func__);
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSLog(@"---%s", __func__);
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    NSLog(@"---%s", __func__);
}

- (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.
    NSLog(@"---%s", __func__);
}

- (void)becomeActive {
    NSLog(@"---%s", __func__);
}

- (void)willResginActive {
    NSLog(@"---%s", __func__);
}

- (void)willEnterForeground {
    NSLog(@"---%s", __func__);
}

- (void)didEnterBackground {
    NSLog(@"---%s", __func__);
}


/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end


進(jìn)入游戲VC的界面VC

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end

#import "ViewController.h"
#import "CocosMng.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"ViewController");
    self.view.backgroundColor = [UIColor whiteColor];
    // Do any additional setup after loading the view.
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self presentViewController:[CocosMng getInstance].viewController animated:YES completion:nil];
        NSLog(@"啟動(dòng)cocos引擎");
        [[CocosMng getInstance] startCocos];
    });
    
}
- (IBAction)startCocos:(id)sender {
    GameViewController * vc = [[GameViewController alloc] init];
    [CocosMng getInstance].viewController = vc;

    [self presentViewController:[CocosMng getInstance].viewController animated:YES completion:nil];
    NSLog(@"啟動(dòng)cocos引擎");
    [[CocosMng getInstance] startCocos];
    
    
    
}


@end


到此,整個(gè)配置流程完成


4 報(bào)錯(cuò)

很多報(bào)錯(cuò)沒有總結(jié)進(jìn)來忘記了,這里就幾個(gè)

  • 出現(xiàn)setting.js 找不到—>直接clear后,卸載APP重新安裝,緩存問題導(dǎo)致的;(有可能是)
  • 在導(dǎo)入Class后報(bào)錯(cuò):Unknown type name 'NSString'
    1__#$!@%!#__Pasted Graphic.png

解決辦法就是把Class下的兩個(gè)cpp文件修改type(上面提到了)

  • Multiple commands produce LaunchScreen.storyboardc
    我的做法是刪除Target--->Build Phases下的info文件,同時(shí)進(jìn)行如下設(shè)置:
    image.png

如果不修改Projetc Setting(有??),也可以刪除掉自己工程中的Main 和 LaunchScreen(如果沒有用到的話)


image.png
  • 在cocos 2.4.5的版本上,生成的iOS工程,集成時(shí),出現(xiàn) Undefined symbols for architecture x86_64 報(bào)錯(cuò),如下:
    image.png

    我發(fā)現(xiàn),采用上面的這些配置正確配置,還是有這個(gè)問題,不知道是新的版本需要添加什么配置,有找到的大佬請(qǐng)留言解惑; 我的解決辦法是把cocos2.4.3生成的 cocos2d-x文件夾,替換掉新的 cocos2d-x文件夾,這樣可以解決,但是不知道原因;

后期還有集成了游戲后的上架問題,也是需要處理的,這里還沒上架,后期上架再補(bǔ)上了.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冈敛,一起剝皮案震驚了整個(gè)濱河市待笑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌抓谴,老刑警劉巖暮蹂,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異癌压,居然都是意外死亡仰泻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門滩届,熙熙樓的掌柜王于貴愁眉苦臉地迎上來集侯,“玉大人,你說我怎么就攤上這事帜消√耐鳎” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵泡挺,是天一觀的道長(zhǎng)辈讶。 經(jīng)常有香客問我,道長(zhǎng)粘衬,這世上最難降的妖魔是什么荞估? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任咳促,我火速辦了婚禮稚新,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘跪腹。我一直安慰自己褂删,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布冲茸。 她就那樣靜靜地躺著屯阀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪轴术。 梳的紋絲不亂的頭發(fā)上难衰,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音逗栽,去河邊找鬼盖袭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鳄虱。 我是一名探鬼主播弟塞,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拙已!你這毒婦竟也來了决记?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤倍踪,失蹤者是張志新(化名)和其女友劉穎系宫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體建车,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笙瑟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了癞志。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片往枷。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凄杯,靈堂內(nèi)的尸體忽然破棺而出错洁,到底是詐尸還是另有隱情,我是刑警寧澤戒突,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布屯碴,位于F島的核電站,受9級(jí)特大地震影響膊存,放射性物質(zhì)發(fā)生泄漏导而。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一隔崎、第九天 我趴在偏房一處隱蔽的房頂上張望令蛉。 院中可真熱鬧,春花似錦消略、人聲如沸守谓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)实牡。三九已至,卻和暖如春轴合,著一層夾襖步出監(jiān)牢的瞬間创坞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工受葛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留题涨,地道東北人豪椿。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像携栋,于是被迫代替她去往敵國(guó)和親搭盾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容