大家好,我是Lampard~~
经过春招一番艰苦奋战之后,我终于是进入了心仪的公司。
今天给大家分享一下我在之前精心准备的一套面试知识。
由于我面试的岗位是cocos2dx的开发岗,今天就先给大家分享一下引擎方面的知识。
本人亲测80%的引擎相关题目都是围绕着我总结出来的知识点提出的 。
一.cocos的内存管理方式
cocos是通过引用计数方式管理内存,主要通过两种方式实现
1.手动管理内存
当我们创建一个实例时,基类Ref里面有一个叫referenceCount的参数就会置1,它代表我们引用的次数,使用retain()函数
可以使refernceCount+1,release()函数会使referenceCount-1,当这个参数减至0时会被引擎delete掉释放内存
2.自动回收池
有手动就会有自动。我们在create()一个对象时不单止调用new函数创建对象还会自动把该对象加入自动回收池,主线程
mainloop()每一帧会调用自动回收池中的clear()方法,clear()方法里包含了release()方法所以如果这个对象没被调用且
referenceCount被减至0就会被自动删除。
二.cocos的渲染机制
3.x之前是通过调用每一个node的draw方法来使用OpenGL代码进行渲染,3.x之后 调用draw函数把需要渲染的node放入一个队
列CommandQueue中,主线程Mainloop()每一帧会调用drawScene()函数来按照ID顺序对队列CommandQueue里的结
点进行渲染。这样做的好处是出现使用同一 张纹理图重复渲染的结点则不需重复渲染。
三.cocos的cache缓存区
TextureCache:加载大纹理图如背景图片
SpriteFrameCache.:加载碎的精灵帧图片,plist文件
AnimationCache:把想像走路,奔跑等多次重复的动作加载进缓存中
他们的作用都是把图片/动作预加载进Map容器(Map是通过键值对的形式存储数据)中储存之后再次使用该资源时,就可直接取
出,而不需重新加载提高效率且不造成加载时运存过大。顺带一提的是,纹理缓存和精灵帧缓存之间的区别是如果精灵帧缓存在
缓存区中找不到想要的图片时,它会报null,而TextureCache则会在系统路径中查找该图。
四.SpriteBatchNode精灵批处理类
SpriteBatchNode* spriteBatchNode= SpriteBatchNode::create();
spriteBatchNode.addchild(纹理);
对同一张纹理图进行多次重复的绘制,如子弹,粒子。而不用每一个粒子分开绘制,降低渲染批次从而提高效率。
也就是说引擎只需要对spriteBatchNode这个对象进行渲染而不需要分开多次对不同精灵进行渲染。
五.cocos2d-x程序的结束流程
在mainLoop中由Dictor导演执行end()函数时,程序就会结束,然后触发游戏清理工作,释放内存。
六.cocos2d 3.x的新特性
1.使用了新的渲染机制(上述)
2.使用了C++11的新特性:如auto关键字,Lamdar表达式等。Lamdar表达式是我们想使用一个方法但是又不想进行声明定义时
的简便操作(匿名函数)
3.支持多线程,使资源可以异步加载,提高cpu的利用率
4.去除了ObjectC模式,删除了CC前缀
七.cocos2dx的屏幕适配方案
pEGLView::sharedOpenGLView()->setDesignResolutionSize()
通过导演雷调用OpenGl函数 设置屏幕的配置方案
里面接三个参数,分别是长,宽,以及屏幕适配方案,一下是C++的适配方案 ,lua和 creator还有其他不同的
KResolutionExactFit:变长宽比,全屏
KResolutionNoBorder:不变长宽比,全屏但是有一部分不显示
KResolutionShowAll:不变长宽比,有黑边
八.如何对游戏的卡顿问题进行优化
造成卡顿也就是掉帧的原因主要是CPU计算量和GPU渲染压力过大,因而需要对资源进行合适的处理。
首先对于图片方面:
1.对资源进行预加载到缓存区避免游戏时出现卡顿
2.使用TexturePacket/cocoStdio打包图片,优化纹理大小、格式、颜色深度(RGB8888-)RGB4444)
3.对多次出现的纹理图使用SpriteBatchNode这个类来渲染,提高效率
4.支持pvr图片的情况下,使用pvr格式的图片,尽量避免使用jpg和png格式的纹理,因为png在加载时会调用一个临时变量来保
存图片,再生成纹理,会两倍占用内存。而且cocos2dx引擎在对pvr格式图片解压缩时比较效率。
5.. 不要使用超大的纹理
然后是对于音乐方面:
1.对背景音乐进行裁剪,通过重复播放的形式节省内存
2.使用的音乐应该要经过压缩,通过降低音质的方式来减少占用的内存
最后是对于代码方面:
1.写算法时,不要造成内存泄漏,使用算法尽量要用最优方案
2.对于重复使用的纹理,精灵,动作要加载进缓存区,避免重复的删除创建
3.已经没用的场景和精灵要及时的删除
九.cocoS包体的压缩
对于上线 项目来说安装包每大一M都是钱啊!所以对包体要进行适当的压缩:删除没有用到的代码块,对图片以及声音资源进行
压缩,尽量使用系统的字库
十.cocos的数据存储
Userdefault:本质是一颗XML文件,是cocos提供的方案优点时cocos自带的存储方案,调用比较方便
缺点:都要遍历整个文件,效率不高&&不没有数据类型的安全
SQList:轻量的嵌入式数据库,可高速且安全的在本地存储数据。
FileUtils:用文件存储,比较麻烦和效率低
十一.中文乱码怎么解决
1.在Vs2017中另存项目,找到无签名的UTF-8进行储存
2.对于一些系统需要的字体logo,使用Plist文件把字体当作精灵贴图上去
3.先写一个XML文件,里面存储着所使用的字体,当需要调用时直接再XML文件中寻找
Dictionary* strings = Dictionary::createWithContentsOfFile("string.xml");
const char * str;
str = ((String *)strings->objectForKey("menulogo"))->getCString();
十二.Cocos2d-x中所使用的设计模式
单例模式:Dictor,OpenGl,cache,userfault等只需要一个实例
单例模式的实现方式:
饿汉模式
在类中声明并实现了对象,如果调用getInstance则返回这个对象,立刻被加载,如果没有使用到会造成内存的浪费
懒汉模式
在类中声明了对象(但是还没有实例化),在调用getInstance才对其调用进行实例化
静态内置类模式
在类中再封装了一个静态类,这个类的功能能是实例化外部类的对象。
单例模式好处:只允许创建一个对象,因此节省内存,加快对象访问速度,操作方便
单例模式坏处:就是不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,
不能保存彼此的状态。
工厂模式:基类只定义接口(规定生产什么产品),由子类来具体实现。对于需求量大的类这样做简化代码,方便调用
管理者模式:如三个cache,对于体积大又要重复使用的数据,这样做可以避免多次加载
观察者模式: 指被观察者含有一个数组,里边存放了所有观察者的引用,在被观察者的状态发生改变的时候,通过调用观察者的
函数来通知观察者(事件监听),实现了信息的传递。如血量变化。
十三.场景切换的内存处理过程是什么?
一般情况下先构建新场景,然后显示新场景,然后释放旧场景。
1、如果没有切换效果,则为B的init(),A的onExit(),B的onEnter()
2、如果有切换效果,则为B的init(),B的onEnter(),A的onExit()