【iOS】Cocos2dx封装为view方便做3D动画效果

版权声明:本文为博主原创,如需转载请注明出处。

写在前面

本文件只是将Cocos2dx 封装为一个 UIView,方便直接添加使用

使用的 coco2d-x 版本为 3.13.1

添加过程

首先将 ~/cocos2d/build/cocos2d_lib.xcodeproj 添加到工程中

然后对照new出来的工程,修改配置:

然后添加两个 Header Search Paths,同样对照样本工程

设置TARGETS中Header Search Paths


PROJECT中设置Header Search Paths,相对路径


设置预处理的宏定义,Debug和Release

修改Custom Compiler Flags

至此,不出意外编译可以成功了。

设置view

然后在CocosViewController(我自己建立的测试界面)中设置弹出HelloWorld界面,HelloWorld界面的两个类 AppDelegateHelloWorldScene要添加到工程中。

注意这个文件是C++混编,所以 CocosViewController.m 文件要改后缀为 CocosViewController.mm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

#import "CocosViewController.h"

#import "CocosAppDelegate.h"
#import "platform/ios/CCEAGLView-ios.h"
#import "platform/ios/CCDirectorCaller-ios.h"

// cocos2d application instance
static CocosAppDelegate s_sharedApplication;

@interface CocosViewController ()

@property (weak, nonatomic) UIView *blackView;
@property (weak, nonatomic) CCEAGLView *eaglView;

@end

@implementation CocosViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.

self.view.backgroundColor = [UIColor whiteColor];
[self drawButton];

}


#pragma mark - 绘制按钮
- (void)drawButton
{
UIButton *cocoaButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 70, 80, 50)];
[cocoaButton setTitle:@"动画开关" forState:UIControlStateNormal];
[cocoaButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[cocoaButton addTarget:self action:@selector(presentCocosView) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:cocoaButton];

}

- (void)presentView
{
if (self.blackView) {
[self.blackView removeFromSuperview];
self.blackView = nil;
} else {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(50, 120, [UIScreen mainScreen].bounds.size.width / 2.0, [UIScreen mainScreen].bounds.size.height / 2.0)];
[view setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:view];

self.blackView = view;
}
}

- (void)presentCocosView
{
if (self.eaglView) {
[self destroyCocosView];
} else {
[self addCocosView];
}
}

- (void)addCocosView
{
cocos2d::Application *app = cocos2d::Application::getInstance();

// Initialize the GLView attributes
app->initGLContextAttrs();
cocos2d::GLViewImpl::convertAttrs();

// Initialize the CCEAGLView
CCEAGLView *eaglView = [CCEAGLView viewWithFrame: CGRectMake(0, 120, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height * 0.8)
pixelFormat: (__bridge NSString *)cocos2d::GLViewImpl::_pixelFormat
depthFormat: cocos2d::GLViewImpl::_depthFormat
preserveBackbuffer: NO
sharegroup: nil
multiSampling: NO
numberOfSamples: 0 ];

// Enable or disable multiple touches
[eaglView setMultipleTouchEnabled:NO];

// Set EAGLView as view of RootViewController
// self.view = eaglView;
[self.view addSubview:eaglView];
self.eaglView = eaglView;

cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView((__bridge void *)eaglView);

//set the GLView as OpenGLView of the Director
cocos2d::Director::getInstance()->setOpenGLView(glview);


//run the cocos2d-x game scene
app->run();
}

- (void)destroyCocosView
{
// cocos2d::Director::getInstance()->getTextureCache()
cocos2d::PoolManager::destroyInstance();
cocos2d::Director::getInstance()->purgeCachedData();
cocos2d::Director::getInstance()->purgeDirector();

[CCDirectorCaller destroy];
}


- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

此时就可以重复开启关闭cocos动画界面了。

释放cocos单例

检查单例

这里先对所有的cocos2dx中的单例进行检查,主要是想用Director销毁其他的单例,经过检查的结果也证明了王哲说的:用Director来管理项目中的单例,具体释放在上面的 destroyCocosView 方法中。即为:

1
2
3
4
5
6
7
8
9
- (void)destroyCocosView
{
// cocos2d::Director::getInstance()->getTextureCache()
cocos2d::PoolManager::destroyInstance();
cocos2d::Director::getInstance()->purgeCachedData();
cocos2d::Director::getInstance()->purgeDirector();

[CCDirectorCaller destroy];
}

下面为检查结果表格:

单例 是否被cocostudio释放 启动时是否被实例化
ArmatureNodeReader::destroyInstance()
ButtonReader::destroyInstance()
ActionManagerEx::destroyInstance() CCActionNode 和 CCSGUIReader
BoneNodeReader::destroyInstance()
ActionTimelineCache::destroyInstance() CSLoader销毁时会调用这个销毁 CSLoader
Animation3DCache::destroyInstance()
AnimationCache::destroyInstance() CCNodelLoader 和 CCSprite
ScriptEngineManager::destroyInstance() 有一堆类用到这个实例,但没有被销毁,但可以用Application销毁
PoolManager::destroyInstance() 同上
ArmatureDataManager::destroyInstance()
AsyncTaskPool::destroyInstance() 其他3个类有用到
Configuration::destroyInstance() 二十几个类用到
FileUtils::destroyInstance()
GLProgramCache::destroyInstance()
GLProgramStateCache::destroyInstance()
NodeLoaderLibrary::destroyInstance()
__NotificationCenter::destroyInstance()
GUIReader::destroyInstance() 十几个类调用
Sprite3DCache::getInstance() 自己调用
Sprite3DMaterialCache::destroyInstance()
SpriteFrameCache::destroyInstance()
SceneReader::destroyInstance()
DictionaryHelper::destroyInstance()
UserDefault::destroyInstance()
CheckBoxReader::destroyInstance()
NodeReader::destroyInstance()
SingleNodeReader::destroyInstance()
SpriteReader::destroyInstance()
ParticleReader::destroyInstance()
GameMapReader::destroyInstance()
ProjectNodeReader::destroyInstance()
ComAudioReader::destroyInstance()
WidgetReader::destroyInstance()
CheckBoxReader::destroyInstance()
ImageViewReader::destroyInstance()
TextBMFontReader::destroyInstance()
TextReader::destroyInstance()
TextFieldReader::destroyInstance()
TextAtlasReader::destroyInstance()
LoadingBarReader::destroyInstance()
SliderReader::destroyInstance()
LayoutReader::destroyInstance()
ScrollViewReader::destroyInstance()
PageViewReader::destroyInstance()
ListViewReader::destroyInstance()
Node3DReader::destroyInstance()
Sprite3DReader::destroyInstance()
UserCameraReader::destroyInstance()
Particle3DReader::destroyInstance()
CSLoader::destroyInstance()
FlatBuffersSerialize::destroyInstance() 一堆调用这个
GameNode3DReader::destroyInstance()
HttpClient::destroyInstance()
Light3DReader::destroyInstance()
JsonLocalizationManager::destroyInstance()
BinLocalizationManager::destroyInstance()
ObjectFactory::destroyInstance()
SkeletonNodeReader::destroyInstance()
SocketIO::destroyInstance()
TabControlReader::destroyInstance()
TabHeaderReader::destroyInstance()
TabItemReader::destroyInstance()
TriggerMng::destroyInstance()