关键词: cocos2d-lua项目启动流程 lua调用cocos2d引擎API
这里是个小测试
环境
引擎版本:Cocos2d-x 3.10 开发工具:Xcode8.1
简述
所谓的Cocos2d-lua,其实只是Cocos2d引擎添加了Lua绑定的版本。
从创建命令可以看出来 cocos new TestProj -d Desktop/ -l lua
,这里的引擎其实是同一套,只是创建工程时提供了不同语言的桥接层
使用C++语言和Cocos2d-x引擎进行开发时,我们写的代码是直接调用引擎的API的,因为引擎也是用C++语言编写,不需要进行语言转换 使用Lua语言和Cocos2d-x引擎进行开发时,我们写的代码通过LuaEngine执行,而LuaEngine封装了Cocos2d-x引擎的API,所以就相当于使用Lua脚本在调用Cocos2d-x的API了
C++项目和Lua项目的开始过程
简单来比较一下C++项目和Lua项目开始的过程(后面会专门写一下启动流程),这里我们都从AppDelegate.cpp的 AppDelegate::applicationDidFinishLaunching()
函数开始。
C++项目
先贴一下代码咯
bool AppDelegate :: applicationDidFinishLaunching () {
auto director = Director :: getInstance ();
auto glview = director -> getOpenGLView ();
</span><span class="hljs-comment"><span class="com">//此时GLView为空</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">if</span></span><span class="pun">(!</span><span class="pln">glview</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
# if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) glview = GLViewImpl :: createWithRect ( “TestCpp” , Rect ( 0 , 0 , designResolutionSize . width , designResolutionSize . height )); # else glview = GLViewImpl :: create ( “TestCpp” ); # endif director-> setOpenGLView ( glview ); }
</span><span class="hljs-comment"><span class="com">// turn on display FPS</span></span><span class="pln">
director</span><span class="pun">-></span><span class="pln">setDisplayStats</span><span class="pun">(</span><span class="kwd">true</span><span class="pun">);</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//显示帧率信息</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">// set FPS. the default value is 1.0/60 if you don't call this</span></span><span class="pln">
director</span><span class="pun">-></span><span class="pln">setAnimationInterval</span><span class="pun">(</span><span class="hljs-number"><span class="lit">1.0</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln"> </span><span class="hljs-number"><span class="lit">60</span></span><span class="pun">);</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//设置动画帧率,也就是界面刷新帧率咯</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">// Set the design resolution</span></span><span class="pln">
glview</span><span class="pun">-></span><span class="pln">setDesignResolutionSize</span><span class="pun">(</span><span class="pln">designResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">width</span></span><span class="pun">,</span><span class="pln"> designResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">,</span><span class="pln"> </span><span class="typ">ResolutionPolicy</span><span class="pun">::</span><span class="pln">NO_BORDER</span><span class="pun">);</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//设置设计分辨率,而不是实际分辨率,这里是为了适配,不能把实际分辨率固定</span></span><span class="pln">
</span><span class="typ">Size</span><span class="pln"> frameSize </span><span class="pun">=</span><span class="pln"> glview</span><span class="pun">-></span><span class="pln">getFrameSize</span><span class="pun">();</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//获得实际窗口大小</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">//根据实际窗口大小,设置内容缩放比例</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">// if the frame's height is larger than the height of medium size.</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">if</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">frameSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pln"> </span><span class="pun">></span><span class="pln"> mediumResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
director</span><span class="pun">-></span><span class="pln">setContentScaleFactor</span><span class="pun">(</span><span class="pln">MIN</span><span class="pun">(</span><span class="pln">largeResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">/</span><span class="pln">designResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">,</span><span class="pln"> largeResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">width</span></span><span class="pun">/</span><span class="pln">designResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">width</span></span><span class="pun">));</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="hljs-comment"><span class="com">// if the frame's height is larger than the height of small size.</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">else</span></span><span class="pln"> </span><span class="hljs-built_in"><span class="kwd">if</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">frameSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pln"> </span><span class="pun">></span><span class="pln"> smallResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
director</span><span class="pun">-></span><span class="pln">setContentScaleFactor</span><span class="pun">(</span><span class="pln">MIN</span><span class="pun">(</span><span class="pln">mediumResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">/</span><span class="pln">designResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">,</span><span class="pln"> mediumResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">width</span></span><span class="pun">/</span><span class="pln">designResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">width</span></span><span class="pun">));</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="hljs-comment"><span class="com">// if the frame's height is smaller than the height of medium size.</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">else</span></span><span class="pln">
</span><span class="pun">{</span><span class="pln">
director</span><span class="pun">-></span><span class="pln">setContentScaleFactor</span><span class="pun">(</span><span class="pln">MIN</span><span class="pun">(</span><span class="pln">smallResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">/</span><span class="pln">designResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">height</span></span><span class="pun">,</span><span class="pln"> smallResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">width</span></span><span class="pun">/</span><span class="pln">designResolutionSize</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">width</span></span><span class="pun">));</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
register_all_packages</span><span class="pun">();</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//使用包管理器。。 不太清楚这里是为什么</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">// create a scene. it's an autorelease object</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">auto</span></span><span class="pln"> scene </span><span class="pun">=</span><span class="pln"> </span><span class="typ">HelloWorld</span><span class="pun">::</span><span class="pln">createScene</span><span class="pun">();</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//新建一个场景</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">// run</span></span><span class="pln">
director</span><span class="pun">-></span><span class="pln">runWithScene</span><span class="pun">(</span><span class="pln">scene</span><span class="pun">);</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//从这个场景开始运行,开始绘制、子节点管理等</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">return</span></span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
}
这段代码是Cocos2d-x 3.10版本新建的C++语言工程中AppDelegate.cpp文件中拷出来的,加了一些注释。 从这里我们可以看出进入游戏逻辑的流程:
初始化Director 新建GLView,然后进行一些设置 新建Scene 使用Director运行这个场景
游戏逻辑就可以从这个Scene中的init函数开始,添加UI层,添加事件监听器,添加游戏层等等…如果我们有一些统计、资源管理器等,也可以在AppDelegate的applicationDidFinishLaunching
函数中来进行。
Lua项目
也来看AppDelegate.cpp中的applicationDidFinishLaunching
函数
bool AppDelegate :: applicationDidFinishLaunching ()
{
Director :: getInstance ()-> setAnimationInterval ( 1.0 / 60.0 f );
</span><span class="hljs-comment"><span class="com">//重点:添加Lua相关支持</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">// register lua module</span></span><span class="pln">
</span><span class="kwd">auto</span><span class="pln"> engine </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LuaEngine</span><span class="pun">::</span><span class="pln">getInstance</span><span class="pun">();</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//初始化一个Lua语言引擎</span></span><span class="pln">
</span><span class="typ">ScriptEngineManager</span><span class="pun">::</span><span class="pln">getInstance</span><span class="pun">()-></span><span class="pln">setScriptEngine</span><span class="pun">(</span><span class="pln">engine</span><span class="pun">);</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//将Lua语言引擎设置为当前脚本引擎(用脚本引擎管理器来管理各种脚本引擎)</span></span><span class="pln">
lua_State</span><span class="pun">*</span><span class="pln"> L </span><span class="pun">=</span><span class="pln"> engine</span><span class="pun">-></span><span class="pln">getLuaStack</span><span class="pun">()-></span><span class="pln">getLuaState</span><span class="pun">();</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//获取Lua引擎的State,也就是一组属性</span></span><span class="pln">
lua_module_register</span><span class="pun">(</span><span class="pln">L</span><span class="pun">);</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//向Lua引擎注册一些模块,如网络、动画等</span></span><span class="pln">
register_all_packages</span><span class="pun">();</span><span class="pln">
</span><span class="hljs-comment"><span class="com">//设置脚本加密相关的key和sign</span></span><span class="pln">
</span><span class="typ">LuaStack</span><span class="pun">*</span><span class="pln"> stack </span><span class="pun">=</span><span class="pln"> engine</span><span class="pun">-></span><span class="pln">getLuaStack</span><span class="pun">();</span><span class="pln">
stack</span><span class="pun">-></span><span class="pln">setXXTEAKeyAndSign</span><span class="pun">(</span><span class="hljs-string"><span class="str">"2dxLua"</span></span><span class="pun">,</span><span class="pln"> strlen</span><span class="pun">(</span><span class="hljs-string"><span class="str">"2dxLua"</span></span><span class="pun">),</span><span class="pln"> </span><span class="hljs-string"><span class="str">"XXTEA"</span></span><span class="pun">,</span><span class="pln"> strlen</span><span class="pun">(</span><span class="hljs-string"><span class="str">"XXTEA"</span></span><span class="pun">));</span><span class="pln">
</span><span class="hljs-comment"><span class="com">//register custom function</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">//LuaStack* stack = engine->getLuaStack();</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">//register_custom_function(stack->getLuaState());</span></span><span class="pln">
auto runtimeEngine = RuntimeEngine :: getInstance (); runtimeEngine-> addRuntime ( RuntimeLuaImpl :: create (), kRuntimeEngineLua ); runtimeEngine-> start (); if ( engine -> executeScriptFile ( “src/main.lua” )) { return false ; }
</span><span class="hljs-keyword"><span class="kwd">return</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">true</span></span><span class="pun">;</span><span class="pln"> </span><span class="hljs-comment"><span class="com">//正常执行到这里,后面就开始执行Cocos引擎提供的主循环</span></span><span class="pln">
}
从上面代码可以看到,Cocos2d-x新建的Lua语言项目中,这里没有进行GLView的设置,没有使用C++代码来创建Scene,所以这些操作肯定和”src/main.lua”脚本有关。这里我们一步一步来看src目录下这些脚本执行的步骤(注意看注释的序号):
在main.lua中部分注释:
cc . FileUtils : getInstance (): setPopupNotify ( false )
cc . FileUtils : getInstance (): addSearchPath ( "src/" )
cc . FileUtils : getInstance (): addSearchPath ( "res/" )
require “config” require “cocos.init”
local function main () require ( “app.MyApp” ): create (): run () end local status , msg = xpcall ( main , G__TRACKBACK ) if not status then print ( msg ) end
2.去app/MyApp.lua看看require做了什么:
local MyApp = class ( "MyApp" , cc . load ( "mvc" ). AppBase )
function MyApp : onCreate ()
math . randomseed ( os . time ())
end
return MyApp
3.继续去packages/AppBase.lua里看看生成MyApp的时候做了什么:
local AppBase = class ( " AppBase " )
– 5 . 构造函数 function AppBase : ctor ( configs ) self . configs_ = { viewsRoot = “app.views” , modelsRoot = “app.models” , defaultSceneName = “MainScene” , }
</span><span class="hljs-keyword"><span class="kwd">for</span></span><span class="pln"> k</span><span class="pun">,</span><span class="pln"> v </span><span class="kwd">in</span><span class="pln"> pairs</span><span class="pun">(</span><span class="pln">configs </span><span class="hljs-literal"><span class="kwd">or</span></span><span class="pln"> </span><span class="pun">{})</span><span class="pln"> </span><span class="kwd">do</span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">configs_</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> v
</span><span class="hljs-keyword"><span class="kwd">end</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> type</span><span class="pun">(</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">configs_</span><span class="pun">.</span><span class="pln">viewsRoot</span><span class="pun">)</span><span class="pln"> </span><span class="pun">~=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"table"</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">then</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">configs_</span><span class="pun">.</span><span class="pln">viewsRoot </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">configs_</span><span class="pun">.</span><span class="pln">viewsRoot</span><span class="pun">}</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">end</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> type</span><span class="pun">(</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">configs_</span><span class="pun">.</span><span class="pln">modelsRoot</span><span class="pun">)</span><span class="pln"> </span><span class="pun">~=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"table"</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">then</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">configs_</span><span class="pun">.</span><span class="pln">modelsRoot </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">configs_</span><span class="pun">.</span><span class="pln">modelsRoot</span><span class="pun">}</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">end</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> DEBUG </span><span class="pun">></span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">then</span></span><span class="pln">
</span><span class="kwd">dump</span><span class="pun">(</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">configs_</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"AppBase configs"</span></span><span class="pun">)</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">end</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> CC_SHOW_FPS </span><span class="hljs-keyword"><span class="kwd">then</span></span><span class="pln">
cc</span><span class="pun">.</span><span class="typ">Director</span><span class="pun">:</span><span class="pln">getInstance</span><span class="pun">():</span><span class="pln">setDisplayStats</span><span class="pun">(</span><span class="hljs-literal"><span class="kwd">true</span></span><span class="pun">)</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">end</span></span><span class="pln">
</span><span class="pun">--</span><span class="pln"> </span><span class="kwd">event</span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">:</span><span class="pln">onCreate</span><span class="pun">()</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">6</span></span><span class="lit">.</span><span class="pun">啥也没做的</span><span class="pln">create</span><span class="pun">函数</span><span class="pln">
end
4.我们可以看回第1步(注释编号3)中,生成MyApp对象后,执行了run方法,那就看看AppBase.lua中的run方法做了什么:
function AppBase : run ( initSceneName )
initSceneName = initSceneName or self . configs_ . defaultSceneName
self : enterScene ( initSceneName )
end
function AppBase : enterScene ( sceneName , transition , time , more )
local view = self : createView ( sceneName )
view : showWithScene ( transition , time , more )
return view
end
5.这里(注释编号10)看到会调用到AppBase.lua中的createView方法:
function AppBase : createView ( name )
for _ , root in ipairs ( self . configs_ . viewsRoot ) do
local packageName = string . format ( "%s.%s" , root , name )
local status , view = xpcall ( function ()
return require ( packageName )
end , function ( msg )
if not string . find ( msg , string . format ( "'%s' not found:" , packageName )) then
print ( "load view error: " , msg )
end
end )
local t = type ( view )
if status and ( t == "table" or t == "userdata" ) then
return view : create ( self , name )
end
end
error ( string . format ( "AppBase:createView() - not found view \"%s\" in search paths \"%s\"" ,
name , table . concat ( self . configs_ . viewsRoot , "," )), 0 )
end
6.上面的函数中执行到了app/views/MainScene.lua脚本,那就去看看做了什么:
local MainScene = class ( "MainScene" , cc . load ( "mvc" ). ViewBase ) -- 16 .MainScene 类继承自 ViewBase ,去 mvc / ViewBase . lua 看看
– 19 . 创建一个 Sprite ,一个 Label ,添加到这个 Node 中 function MainScene : onCreate () – add background image display . newSprite ( “HelloWorld.png” ) : move ( display . center ) : addTo ( self )
</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-built_in"><span class="pln">add</span></span><span class="pln"> </span><span class="typ">HelloWorld</span><span class="pln"> label
</span><span class="hljs-keyword"><span class="pln">cc</span></span><span class="pun">.</span><span class="typ">Labe</span><span class="hljs-variable"><span class="typ">l</span><span class="pun">:</span><span class="pln">createWithSystemFont</span></span><span class="pun">(</span><span class="hljs-string"><span class="str">"Hello World"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"Arial"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-number"><span class="lit">40</span></span><span class="pun">)</span><span class="pln">
</span><span class="pun">:</span><span class="hljs-keyword"><span class="pln">move</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="pln">display</span></span><span class="pun">.</span><span class="pln">cx</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">display</span></span><span class="pun">.</span><span class="pln">cy </span><span class="pun">+</span><span class="pln"> </span><span class="hljs-number"><span class="lit">200</span></span><span class="pun">)</span><span class="pln">
</span><span class="pun">:</span><span class="pln">addTo</span><span class="pun">(</span><span class="kwd">self</span><span class="pun">)</span><span class="pln">
end
return MainScene
7.上面第一行代码(注释编号16)可以看到,MainScene类继承自ViewBase,那进入mvc/ViewBase.lua看看
local ViewBase = class ( " ViewBase " , cc . Node ) -- 17. 继承自 Node 噢
– 18 . 构造函数,还是进行一些初始化工作 function ViewBase : ctor ( app , name ) self : enableNodeEvents () self . app_ = app self . name_ = name
</span><span class="pun">--</span><span class="pln"> check CSB resource file
</span><span class="hljs-keyword"><span class="kwd">local</span></span><span class="pln"> res </span><span class="pun">=</span><span class="pln"> rawget</span><span class="pun">(</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="kwd">class</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"RESOURCE_FILENAME"</span></span><span class="pun">)</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> res </span><span class="hljs-keyword"><span class="kwd">then</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">:</span><span class="pln">createResoueceNode</span><span class="pun">(</span><span class="pln">res</span><span class="pun">)</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">end</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">local</span></span><span class="pln"> binding </span><span class="pun">=</span><span class="pln"> rawget</span><span class="pun">(</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="kwd">class</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"RESOURCE_BINDING"</span></span><span class="pun">)</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> res </span><span class="hljs-literal"><span class="kwd">and</span></span><span class="pln"> binding </span><span class="hljs-keyword"><span class="kwd">then</span></span><span class="pln">
</span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">:</span><span class="pln">createResoueceBinding</span><span class="pun">(</span><span class="pln">binding</span><span class="pun">)</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">end</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> </span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">.</span><span class="pln">onCreate </span><span class="hljs-keyword"><span class="kwd">then</span></span><span class="pln"> </span><span class="hljs-built_in"><span class="kwd">self</span></span><span class="pun">:</span><span class="pln">onCreate</span><span class="pun">()</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">end</span></span><span class="pln">
end
8.这里可以回看到第4步(注释编号10),方法createView执行完成后,生成了一个MainScene对象(继承自ViewBase(继承自ccNode)),然后下一步就是调用MainScene对象的showWithScene函数,在packages/mvc/ViewBase.lua中:
-- 21 . 这里创建了一个 Scene ,并且把当前这个 Node 添加到 Scene 中。其实这就是 C ++项目 HelloWorldScene 类的 createScene 方法了
function ViewBase : showWithScene ( transition , time , more )
self : setVisible ( true )
local scene = display . newScene ( self . name_ ) -- 22. display 包含很多功能,有点类似于 Director 了
scene : addChild ( self )
display . runScene ( scene , transition , time , more ) -- 23. runScene 熟悉的方法
return self
end
到这里,对于Cocos2d-x引擎生成的C++和Lua语言项目,我们都分析到了生成第一个Scene的步骤,后面就可以开始写UI、写结构、写逻辑等内容了。
简单对比Cocos2d-x创建的C++工程和Lua工程
这里使用Cocos2d-x 3.10分别创建了Lua语言工程和C++语言工程,在Xcode下打开两个项目,可以对比一下项目结构:
compare.png
从最外层结构可以看出Lua工程比C++工程多了两个lib:
libsimulator 模拟器支持 cocos2d_lua_bindings 引擎与Lua脚本的桥接层
libsimulator就先不看了,和这次主题无关,就先放一边,以后有空再来看(其实我还真没仔细看过这个东东)。
打开AppDelegate.cpp文件,看到引入的头文件:
# include "AppDelegate.h"
# include "CCLuaEngine.h"
# include "SimpleAudioEngine.h"
# include "cocos2d.h"
# include "lua_module_register.h"
# if (CC_TARGET_PLATFORM != CC_PLATFORM_LINUX) # include “ide-support/CodeIDESupport.h” # endif
# if (COCOS2D_DEBUG > 0) && (CC_CODE_IDE_DEBUG_SUPPORT > 0) # include “runtime/Runtime.h” # include “ide-support/RuntimeLuaImpl.h” # endif
AppDelegate自己的头文件除外,第一个头文件就是CCLuaEngine.h,打开cocos2d_lua_bindings库的manual目录,我们就能看到这个类。打开CCLuaEngine.h文件,可以看到它包含了CCLuaStack.h和CCLuaValue.h,这两个文件都是C++与Lua直接交互需要用到的。继续往下看,可以看到cocos2d/LuaScriptHandlerMgr.h,打开manual下的cocos2d文件夹可以看到如下文件列表:
manual:cocos2d.png
从其中LuaOpengl.cpp中包含的代码:
LuaOpengl.png
可以看到这里在注册一个module,并绑定函数。另外一些lia_开头的文件中包含的也是这些代码。
理解一下
想想脚本执行时的情景,当执行到一个名为drawCircle
的函数时,用户自己很可能并没有定义这样一个函数,那Lua引擎如何识别“drawCircle”这样一个命令,而不会把它当作错误的代码呢? 看到上面的文件我们就能知道,字符串“drawCircle”早就被注册到LuaEngine中,所以当执行脚本时遇到drawCircle
时,才知道需要去调用哪一个函数。 这也就是说,cocos2d_lua_bindings库提供了Lua对Cocos2d引擎的绑定,相当于通过注册Module的方式对Cocos2d引擎提供的(相关的)API进行了一次封装(当然,如果是直接封装API,可能达不到提高开发效率的目的,所以有了quick的出现,也就是把常用的功能(例如创建一个Scene)封装成一个函数newScene)。
总结
相对于Cocos2d-x C++工程来说,Cocos2d-x生成的Lua语言工程提供了对Cocos2d引擎的Lua语言封装。将Cocos2d引擎API绑定到对应的Lua语言函数,在调用到这些函数时,会执行对应的Cocos2d引擎API。 以这个思想来看,所以能够直接或间接与C++语言进行交互的编程语言都可以用来封装Cocos2d引擎啊。。
转载小鱼网 "http://www.51xyyx.com/3263.html"