【Cocos2d-x】Lua 资源热更新

【Cocos2d-x】Lua 资源热更新,第1张

概述什么是热更新 所谓的热更新,指的是客户端的更新。 大致的流程是,客户端在启动后访问更新的URL接口,根据更新接口的反馈,下载更新资源,然后使用新的资源启动客户端,或者直接使用新资源不重启客户端。 热更新代码使用到的场景 情人节快到了,你想要组织一个游戏内活动,错过时机肯定是你最不想要看到的结果。 当你发现一个严重的bug。 当你想要添加一些新的场景或者关卡来延长游戏的生命。 以及非常多其他的情况.

什么是热更新

所谓的热更新,指的是客户端的更新。

大致的流程是,客户端在启动后访问更新的URL接口,根据更新接口的反馈,下载更新资源,然后使用新的资源启动客户端,或者直接使用新资源不重启客户端。


热更新代码使用到的场景

情人节快到了,你想要组织一个游戏内活动,错过时机肯定是你最不想要看到的结果。

当你发现一个严重的BUG。

当你想要添加一些新的场景或者关卡来延长游戏的生命。

以及非常多其他的情况...


在Cocos2d-x引擎中的如何实现热更新

LuaEngine

LuaEngine是一个脚本能够实时运行Lua脚本的对象,也就是因为有了LuaEngine这个C++类对象,所以才有了实现热更新技术的基础

获取LuaEngine脚本引擎的对象。

1 2 3 4 //获取LuaEngine引擎脚本类的单例对象 LuaEngine*engine=LuaEngine::getInstance(); //设置该单例对象作为脚本引擎管理器对象的脚本引擎 ScriptEngineManager::getInstance()->setScriptEngine(engine);

使用LuaEngine执行Lua字符串脚本

2
//使用Lua脚本引擎执行Lua字符串脚本 engine->executeString( "print(\"Hello蓝鸥\")" );

使用LuaEngine执行Lua文件脚本

4 5 6 7 8 9 10 11 12 13 14 15 16
//获取储存的文件路径 std::stringpath=fileUtils::getInstance()->getWritablePath(); path+= "hellolanou.lua" ; //创建一个文件指针 //路径、模式 file *file= fopen (path.c_str(), "w" ); if (file){ fputs ( "print(\"蓝鸥!!!\")" ,file); fclose (file); } else cclOG( "savefileerror." ); //使用Lua脚本引擎执行Lua文件脚本 engine->executeScriptfile(path.c_str());

lua_State

lua_State,可以认为是“脚本上下文”,主要包括当前Lua脚本环境的运行状态信息,还会有GC相关的信息。

在使用Cocos2d-x引擎开发时需要使用Lua,那么就需要连接到libcocos2d和libluacocos2d两个静态库。

也就是要在lua_State对象中注册对应的功能模块类,如果不想要使用里边相应的模块时,就可以在luamoduleregister.h中注释掉对应的一行代码。

16 17 18 19 20 21 22 23 24 25 26 27 28 29 @H_372_301@ 30
int lua_module_register(lua_State*L) { //注册cocosdenshion模块 register_cocosdenshion_module(L); //注册network网络模块 register_network_module(L); #ifCC_USE_CCBUILDER //注册cocosbuilder模块 register_cocosbuilder_module(L); #endif #ifCC_USE_CCSTUdio //注册coccostudio模块 register_cocostudio_module(L); #endif //注册ui模块 register_ui_moudle(L); //注册extension模块 register_extension_module(L); #ifCC_USE_SPINE //注册spine模块 register_spine_module(L); #endif #ifCC_USE_3D //注册3d模块 register_cocos3d_module(L); #endif //注册音频audio模块 register_audioengine_module(L); return 1; }

在使用Cocos2d-x引擎时需要使用Quick框架时,同样需要在lua_State注册quick框架的对应模块。

18
static voID quick_module_register(lua_State*L) luaopen_lua_extensions_more(L); lua_getglobal(L,monospace!important; Font-size:1em!important; min-height:inherit!important; color:blue!important; background:none!important">"_G" ); (lua_istable(L,-1)) //stack:...,_G, { register_all_quick_manual(L); //extra luaopen_cocos2dx_extra_luabinding(L); register_all_cocos2dx_extension_filter(L); luaopen_HelperFunc_luabinding(L); #if(CC_TARGET_PLATFORM==CC_PLATFORM_IOS) luaopen_cocos2dx_extra_ios_iap_luabinding(L); #endif } lua_pop(L,1);

LuaStack

通常情况下每一个lua_State对象就对应一个LuaStack。

使用到的相关代码:

10
//使用LuaEngine对象获取Lua的函数栈 LuaStack*stack=engine->getLuaStack(); #ifANYSDK_define>0 lua_getglobal(stack->getLuaState(),monospace!important; Font-size:1em!important; min-height:inherit!important; background:none!important">); tolua_anysdk_open(stack->getLuaState()); tolua_anysdk_manual_open(stack->getLuaState()); lua_pop(stack->getLuaState(),1); #endif //设置加密用的密钥 stack->setXXTEAKeyAndSign( "2dxLua" strlen ),monospace!important; Font-size:1em!important; min-height:inherit!important; color:blue!important; background:none!important">"XXTEA" ));

AssetsManager

资源管理器的诞生就是为了在游戏运行时能够完成资源热更新的技术而设计的。

这里的资源可以是图片,音频甚至是游戏的脚本本身。

使用资源管理器,你将可以上传新的资源到你的服务器,你的游戏会跟踪远程服务器上的修改,将新的资源下载到用户的设备上并在游戏中使用新的资源。

这样的话,一个全新的设计,全新的游戏体验甚至全新的游戏内容就可以立刻被推送到用户的受伤。

更加重要的是,我们并不需要针对各个渠道去重新打包我们的应用程序并且经历痛苦的应用审核,这个过程中没有任何成本!


创建AssetsManager对象

17
static AssetsManager*assetManager=NulL; (!assetManager){ /*创建AssetsManager对象 *@param资源包的下载路径 *@param资源包的当前版本 *@param资源包下载后的存储路径 */ assetManager= new AssetsManager( "http://project.lanou3g.com/game/cocos/teacher/test/src.zip" "http://project.lanou3g.com/game/cocos/teacher/test/version.php" _pathToSave.c_str()); //设置AssetsManager对象的回调对象 assetManager->setDelegate( this ); //设置AssetsManager对象的timeout时间 assetManager->setConnectionTimeout(3); AssetsManagerDelegateProtocol

AssetsManagerDelegateProtocal是一个类接口,主要用来封装下载过程中的回调接口。

26
class AssetsManagerDelegateProtocol { public : virtual ~AssetsManagerDelegateProtocol(){}; : /*@brIEfCallbackfunctionforerror @paramerrorCodeTypeoferror *@JsNA *@luaNA */ virtual onError(AssetsManager::ErrorCodeerrorCode){}; /**@brIEfCallbackfunctionforrecordingdownloadingpercent @parampercentHowmuchpercentdownloaded @warningThiscallbackfunctionjustforrecordingdownloadingpercent. AssetsManagerwilldosomeotherthingafterdownloading,youshould writecodeinonSuccess()afterdownloading. *@JsNA *@luaNA */ onProgress( percent){}; /**@brIEfCallbackfunctionforsuccess *@JsNA *@luaNA */ onSuccess(){}; };

那么接下来,我们使用AssetsManager来创建一个自动更新的类Update.

Update.h

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
// //Update.h //hello // //Createdby蓝鸥. // // #ifndef__hello__Update__ #define__hello__Update__ #include<stdio.h> #include"cocos2d.h" #include"extensions/cocos-ext.h" Update: cocos2d::Layer, cocos2d::extension::AssetsManagerDelegateProtocol { : Update(); ~Update(); virtual bool init(); update(cocos2d::Ref*pSender); reset(cocos2d::Ref*pSender); //继承的回调函数 onError(cocos2d::extension::AssetsManager::ErrorCodeerrorCode); percent); onSuccess(); CREATE_FUNC(Update); private : cocos2d::extension::AssetsManager*getAssetsManager(); //创建下载到的目录路径 initDownloadDir(); : std::string_pathToSave; //用来显示下载进度的Label标签 cocos2d::Label*_showDownloadInfo; }; #endif/*defined(__hello__Update__)*/

Update.cpp

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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 @H_856_1301@ 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
//Update.cpp #include"Update.h" #if(CC_TARGET_PLATFORM!=CC_PLATFORM_WIN32) #include<dirent.h> #include<sys/stat.h> #endif USING_NS_CC; USING_NS_CC_EXT; #defineDOWNLOAD_file"download" #include"ccluaEngine.h" Update::Update(): _pathToSave( "" _showDownloadInfo(NulL) { } Update::~Update() { AssetsManager*assetManager=getAssetsManager(); CC_SAFE_DELETE(assetManager); } Update::init() { (!Layer::init()){ return false ; } SizewinSize=Director::getInstance()->getWinSize(); initDownloadDir(); _showDownloadInfo=Label::createWithSystemFont( "Arial" _showDownloadInfo->setposition(Vec2(winSize.wIDth/2,winSize.height/2-20)); ->addChild(_showDownloadInfo); autoitemLabel1=MenuItemLabel::create( Label::createWithSystemFont( "reset" "arail" )); autoitemLabel2=MenuItemLabel::create( "Update" )); automenu=Menu::create(itemLabel1,itemLabel2,NulL); ->addChild(menu); itemLabel1->setposition(Vec2(winSize.wIDth/2,winSize.height/2+20)); itemLabel2->setposition(Vec2(winSize.wIDth/2,winSize.height/2)); menu->setposition(Vec2::ZERO); true ; } Update::onError(AssetsManager::ErrorCodecode) { switch (code){ case cocos2d::extension::AssetsManager::ErrorCode::NO_NEW_VERSION: _showDownloadInfo->setString( "nonewversion" ); break ; cocos2d::extension::AssetsManager::ErrorCode::NETWORK: ); ; cocos2d::extension::AssetsManager::ErrorCode::CREATE_file: "createfileerror" ); ; default : ; } } Update::onProgress( percent) { (percent<0){ ; } char progress[20]; snprintf(progress,monospace!important; Font-size:1em!important; min-height:inherit!important; color:blue!important; background:none!important">"download%d%%" _showDownloadInfo->setString(progress); } Update::onSuccess() { "downloadsuccess" ); ); std::stringpath=fileUtils::getInstance()->getWritablePath()+DOWNLOAD_file; LuaEngine*pEngine=LuaEngine::getInstance(); //首先添加下载文件的目录 pEngine->addSearchPath(_pathToSave.c_str()); "/src/main.lua" ; pEngine->executeScriptfile(path.c_str()); } AssetsManager*Update::getAssetsManager() { AssetsManager*assetManager=NulL; (!assetManager){ /*创建AssetsManager对象 *@param资源包的下载路径 *@param资源包的当前版本 *@param资源包下载后的存储路径 */ AssetsManager( _pathToSave.c_str()); //设置AssetsManager对象的回调对象 ); //设置AssetsManager对象的timeout时间 assetManager->setConnectionTimeout(3); } assetManager; } Update::initDownloadDir() { "initDownloadDir" ); _pathToSave=fileUtils::getInstance()->getWritablePath(); _pathToSave+=DOWNLOAD_file; "Path:%s" #if(CC_TARGET_PLATFORM!=CC_PLATFORM_WIN32) DIR*pDir=NulL; pDir=opendir(_pathToSave.c_str()); (!pDir){ mkdir(_pathToSave.c_str(),S_IRWXU|S_IRWXG|S_IRWXO); } #else ((GetfileAttributes(_pathToSave.c_str()))=INVALID_file_ATTRIBUTES){ CreateDirectoryA(_pathToSave.c_str(),0); } #endif "initDownloadDirend" ); } Update::reset(Ref*pSender) { ); //Removedownloadedfiles #if(CC_TARGET_PLATFORM!=CC_PLATFORM_WIN32) std::stringcommand= "rm-r" ; //Pathmayincludespace. command+= "\"" +_pathToSave+ ; system (command.c_str()); #else "rd/s/q" ; //Pathmayincludespace. ; (command.c_str()); #endif getAssetsManager()->deleteVersion(); initDownloadDir(); } Update::update(Ref*pSender) { ); getAssetsManager()->update(); }

可以点击下载下来网络资源压缩包,看下压缩包内包含的内容。

可以点击下载下来源代码压缩包,对应一起的。

大家最好可以在本地搭建一个apache服务器,做一下练习。



转自:http://www.cnblogs.com/daxiaxiaohao/p/4162400.HTML
总结

以上是内存溢出为你收集整理的【Cocos2d-x】Lua 资源热更新全部内容,希望文章能够帮你解决【Cocos2d-x】Lua 资源热更新所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1022318.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)