其他分享
首页 > 其他分享> > cocos2d 回顾

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