cocos2d 回顾
作者:互联网
最近两三年年都没怎么搞游戏客户端了,最近在重新找工作,有cocos的面试,于是就再扫一遍引擎源码了。
关于cocos技术, 我认为比较重要几个点:
1. 引擎工作流?
一个游戏循环,每帧渲染节点树。。
2. 渲染流?
3. 事件流? 鼠标点击, 键盘输入, 手指触摸, 重力感应
4. 不同语言的交互。 c++ 掉用 mm文件方法, c++调用 java. lua调用c++. js调用c++
5. drawcall 优化: Node节点关系入手, BatchNode入手
6. 内存优化:能否改用有对象池? 场景按需加载, 切换场景释放不必要声音资源,图片资源?
7. 电量优化: 从CPU计算,网络消息, drawcall优化 着手
8. 数据和界面之间咋衔接的? 游戏设计思想, 采用哪些设计模式?
经常碰到的场景, 一个界面上很多元素的显示依赖服务器数据。
大部分做法是调用服务端接口,等消息到了再整体显示。 这种情况一般需要菊花转圈。
也有一个部分是先显示界面, 等消息来了,在刷新页面元素。 两种方式没有好坏,这个看功能需求。
我设计一般某个页面层, 初始化时采用Net.on("login", this.onLogin) 这种方式, 销毁时采用Net.off('login', this.onLogin)
net.send('login', {usr: 'dzq', pwd:'123'}). 收到服务器回复后把数据先放到消息队列,用一个帧循环处理这个消息队列。
有时需要对网络数据进行保存,一般设计很多数据类管理器, 比如UserMangaer, GameDataManager, 之后用就从管理器中去取。
9. 包体优化, 一般就是把图片进行无损压缩, tinypng网站不错。 声音资源压缩。 然后就是热更新了。 如果还是很大, 把资源进行压缩打包,如使用ZIP, 把资源都搞成bin文件
其他的点, 无关紧要的点, 面试官喜欢问的点:
1. Node节点引用技术机制? 估计是面试想知道你是否了解cocos?
2. spine动画咋使用? 这个问题说真的, 没啥价值, 即使没用过, 看下API也知道咋使用了。
3. 消息协议用的啥,数据协议用的啥, 粘包残包咋处理的?
消息传输无非就是HTTP, socket, websocket. 百分之九十九的游戏都是这三种的传输方式
数据协议无非就是json, protobuf, MessagePack, 百分之八十的游戏都是这三种的传输方式。 不过很多游戏有自己的加密算法。
粘包残包只在socket编程的出现, websocket协议不需要自己处理。 只要把数据包格式设计好就没啥好说的。
一般来说, 4字节包长加上包体。 在包体部分有的会加上4字节crc32校验, 防止数据出现修改。 这个还是比较好处理的,网上也有很多开源的算法。
服务器和客户端都需要处理分包粘包的问题,额外的一点, 业务层需要加心跳协议。 因为用户一段时间(这个时间大概1分钟吧, 不同系统时间也不一样)不发消息,TCP连接会被系统断开。
于是就需要加一个心跳协议, 发了一个心跳包,服务器肯定会回复。如果收不到回复,就基本认为与服务器断开连接。 这个等待回复时间一般是心跳包间隔的2倍。
比如间隔5秒发一个心跳包,从调用发送心跳包开始计算,第10秒还没有收到回复, 就可以弹出一个小框告诉玩家掉线了。不建议时间太短。 时间设置太短和太长都不好。
引擎是怎么工作的?
主要方法: Director:mainloop 游戏循环
渲染工作:
Node::visit(renderer, parentTransform, parentFlags)
drawScene()-> 或递归遍历每一个节点, 然后使用rencder对象渲染, render是对GLES的封装。
怎么把图片显示到屏幕上的?
首先说一点:
每个平台opengl都不一样:
#if CC_TARGET_PLATFORM == CC_PLATFORM_MAC #include "platform/mac/CCGL-mac.h" #elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS #include "platform/ios/CCGL-ios.h" #elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID #include "platform/android/CCGL-android.h" #elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 #include "platform/win32/CCGL-win32.h" #elif CC_TARGET_PLATFORM == CC_PLATFORM_WINRT #include "platform/winrt/CCGL.h" #elif CC_TARGET_PLATFORM == CC_PLATFORM_LINUX #include "platform/linux/CCGL-linux.h" #elif CC_TARGET_PLATFORM == CC_PLATFORM_TIZEN #include "platform/tizen/CCGL-tizen.h" #endif 1. PNG文件 2. sprite->initWithFile 3. Texture2D *texture = _director->getTextureCache()->addImage(filename); 得到texture对象 4. setTexture 主要做了两个事情,更新对象属性_texture 和 updateBlendFunc 5. 游戏循环到visit, 在到draw方法 _trianglesCommand.init(_globalZOrder, _texture, getGLProgramState(), _blendFunc, _polyInfo.triangles, transform, flags); renderer->addCommand(&_trianglesCommand); 这个步骤添加了一个渲染命令, 其实添加到 _renderGroups[_commandGroupStack.top()] 队列了。 6. Renderer::render() 方法里会调用: renderer->visitRenderQueue.. ---> renderer->processRenderCommand
7. 最终调用: TrianglesCommand::useMaterial()
最终调用gl函数 activeTexure和 glbindTexture
render方法在drawScene中调用:
至此一个图片就显示了。 至于gl是怎么操作texture的就不用管了,最终肯定也是调用显卡驱动的API了。
总结起来其实就四步:
1, 把图片转成texture对象
2. 把tuexture设置给Node节点
3. 当帧循环执行到vistit时 发送_trianglesCommand
4. 执行_trianglesCommand命令, 调用GL::bindTuexture2D显示图片
标签:调用,回顾,platform,CC,PLATFORM,CCGL,cocos2d,include 来源: https://www.cnblogs.com/dzqdzq/p/14800366.html