三国社区

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1442|回复: 1

游戏开发引擎对Cocos2d-x 3.3 Lua相关修改

[复制链接]
糖果猪恋
鲜花 鲜花(0)鸡蛋 鸡蛋(0)
发表于 2015-7-24 20:37:37 | 显示全部楼层 |阅读模式
1友盟币
  Cocos2d-x 3.3的Lua项目在运行时,会出现一些不符合人类习惯的问题。下面是我碰到的问题以及解决方案。

  

  1. SpriteFrameCache.addSpriteFrameWithFile 调用错误

  问题描述:

  SpriteFrameCache的addSpriteFramesWithFile方法是支持重载的。

  在tolua中,addSpriteFrameWithFile也同样支持重载。从lua_cocos2dx_auth.cpp中的lua_cocos2dx_SpriteFrameCache_addSpriteFramesWithFile可以看出:

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37

  38

  39

  40

  41

  42

  43

  44

  45

  46

  47

  48

  49

  50

  51

  52

  53

  54

  55

  56

  57

  58

  59

  60

  61

  62

  63

  64 int lua_cocos2dx_SpriteFrameCache_addSpriteFramesWithFile(lua_State* tolua_S)

  {

      int argc = 0;

      cocos2d::SpriteFrameCache* cobj = nullptr;

      bool ok  = true;

  #if COCOS2D_DEBUG >= 1

      tolua_Error tolua_err;

  #endif

  #if COCOS2D_DEBUG >= 1

      if (!tolua_isusertype(tolua_S,1,"cc.SpriteFrameCache",0,&tolua_err)) goto tolua_lerror;

  #endif

      cobj = (cocos2d::SpriteFrameCache*)tolua_tousertype(tolua_S,1,0);

  #if COCOS2D_DEBUG >= 1

      if (!cobj)

      {

          tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_SpriteFrameCache_addSpriteFramesWithFile'", nullptr);

          return 0;

      }

  #endif

      argc = lua_gettop(tolua_S)-1;

      do{

          if (argc == 2) {

              std::string arg0;

              ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.SpriteFrameCache:addSpriteFramesWithFile");

              if (!ok) { break; }

              std::string arg1;

              ok &= luaval_to_std_string(tolua_S, 3,&arg1, "cc.SpriteFrameCache:addSpriteFramesWithFile");

              if (!ok) { break; }

              cobj->addSpriteFramesWithFile(arg0, arg1);

              return 0;

          }

      }while(0);

      ok  = true;

      do{

          if (argc == 1) {

              std::string arg0;

              ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.SpriteFrameCache:addSpriteFramesWithFile");

              if (!ok) { break; }

              cobj->addSpriteFramesWithFile(arg0);

              return 0;

          }

      }while(0);

      ok  = true;

      do{

          if (argc == 2) {

              std::string arg0;

              ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.SpriteFrameCache:addSpriteFramesWithFile");

              if (!ok) { break; }

              cocos2d::Texture2D* arg1;

              ok &= luaval_to_object<cocos2d::Texture2D>(tolua_S, 3, "cc.Texture2D",&arg1);

              if (!ok) { break; }

              cobj->addSpriteFramesWithFile(arg0, arg1);

              return 0;

          }

      }while(0);

      ok  = true;

      CCLOG("%s has wrong number of arguments: %d, was expecting %d \n",  "cc.SpriteFrameCache:addSpriteFramesWithFile",argc, 2);

      return 0;

  #if COCOS2D_DEBUG >= 1

      tolua_lerror:

      tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_SpriteFrameCache_addSpriteFramesWithFile'.",&tolua_err);

  #endif

      return 0;

  }

  但是,在Lua里面调用addSpriteFramesWithFile时,如果第二个参数传递Texture2D,就会报错。信息如下:

  cocos2d: error:

  cc.SpriteFrameCache:addSpriteFramesWithFile argument #3 is ‘cc.Texture2D'; ‘string’ expected.

  解决方案:不解决。

  问题分析:

  因为这是个误报。

  从上面 lua_cocos2dx_SpriteFrameCache_addSpriteFramesWithFile 的绑定代码可以看出,第二个参数是字符串的重载版本(版本1)是先调用的。当使用第二个参数是 Texture2D 的重载版本时,版本1也会被调用,但不会执行。

  不过参数判断总是会执行,因此就出现了误报。

  误报的输出发生在 LuaBasicConversions.cpp 的 luaval_to_native_err 函数中:

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25 void luaval_to_native_err(lua_State* L,const char* msg,tolua_Error* err, const char* funcName)

  {

      if (NULL == L || NULL == err || NULL == msg || 0 == strlen(msg))

          return;

      if (msg[0] == '#')

      {

          const char* expected = err->type;

          const char* provided = tolua_typename(L,err->index);

          if (msg[1]=='f')

          {

              int narg = err->index;

              if (err->array)

                  CCLOG("%s\n     %s argument #%d is array of '%s'; array of '%s' expected.\n",msg+2,funcName,narg,provided,expected);

              else

                  CCLOG("%s\n     %s argument #%d is '%s'; '%s' expected.\n",msg+2,funcName,narg,provided,expected);

          }

          else if (msg[1]=='v')

          {

              if (err->array)

                  CCLOG("%s\n     %s value is array of '%s'; array of '%s' expected.\n",funcName,msg+2,provided,expected);

              else

                  CCLOG("%s\n     %s value is '%s'; '%s' expected.\n",msg+2,funcName,provided,expected);

          }

      }

  }

  终极解决方案就是取消这个方法的自动导出,改为手动导出。但本着尽量少修改Cocos2d-x源码的初衷,知道就好,不必改动。

  

  2. 不能载入luac文件

  问题描述:

  在载入main.lua文件的时候,明明已经载入成功,但却一直会收到下面的提示:

  can not get file data of main.luac

  如果有多个lua文件,那么载入每个Lua文件都会收到这个提示,只是扩展名变成了luac。

  

  解决方案:

  找到 Cocos2dxLuaLoader.cpp 文件,找到其中的 cocos2dx_lua_loader 方法,将下面这段删除或注释:

  1

  2

  3

  4

  5

  6 chunkName = prefix.substr(0, pos) + filename + BYTECODE_FILE_EXT;

  if (utils->isFileExist(chunkName))

  {

      chunk = utils->getFileData(chunkName.c_str(), "rb", &chunkSize);

      break;

  }

  注意,上面的代码是一段 if … else 结构的一部分,因此删除或注释后,还需要做一些其它的修改才能通过编译。

  

  问题分析:

  Cocos2d-x的Lua载入代码会优先载入luac文件,然后再处理Lua文件。取消载入luac文件即可解决这个问题。

  

  3. print 内容净化

  问题描述:

  使用Lua的print方法打印出来的内容,在控制台中显示如下:

  1 cocos2d: [LUA-print] ——– require(root.pretreatent.init)

  这个 cocos2d: [LUA-print] 看起来相当讨厌,要干掉它。

  

  解决方案:

  在 CCLuaStack.cpp 中找到 lua_print 方法,将其中的:

  1 CCLOG("[LUA-print] %s", t.c_str());

  改为:

  1 CCLOG("%s", t.c_str());

  在 CCConsole.cpp 中找到 _log 方法,将其中的:

  1 fprintf(stdout, "cocos2d: %s", buf);

  改为:

  1 fprintf(stdout, "%s", buf);

  4. print 中加入时间戳显示

  问题描述:

  以前使用Quic-Cocos2d-x的时候,每一句 print 之前,都有一个当前 print 时刻的时间戳显示。单位是从程序执行开始的秒数。

  Cocos2d-x 3.3 Lua版本中没有这个时间显示。

  

  解决方案:

  在 CCLuaStack.cpp 中,在全局命名空间中(namespace { 之下)加入下面的内容,定义一个全局变量和一个全局函数:

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29 static timeval lua_print_lasttime = {0};

  std::string lua_print_gettime()

  {

      timeval now;

      float deltatime = 0;

      if(gettimeofday(&now, nullptr) != 0)

      {

          CCLOG("lua_print_gettime() - error in gettimeofday");

      }

      else

      {

          if (lua_print_lasttime.tv_sec)

          {

              deltatime = now.tv_sec - lua_print_lasttime.tv_sec + (now.tv_usec - lua_print_lasttime.tv_usec) / 1000000.0f;

          }

          else

          {

              lua_print_lasttime = now;

              deltatime = 0;

          }

      }

      std::string t("[");

      char timestr[32];

      memset(timestr, 0, sizeof(timestr));

      sprintf(timestr, "%.4f", deltatime);

      t += timestr;

      t += "] ";

      return t;

  }

  在 LuaStack::init 方法的第一行加入 gettimeofday(&lua_print_lasttime, nullptr); ,修改完毕的函数如下所示:

  1

  2

  3

  4

  5

  6

  7

  8

  9 bool LuaStack::init(void)

  {

      gettimeofday(&lua_print_lasttime, nullptr);

      //.........原来的内容

      _state = lua_open();

      luaL_openlibs(_state);

      toluafix_open(_state);

      //.........原来的内容

  }

  修改 lua_print 方法,将其中的:

  1 std::string t;

  改为:

  1 std::string t(lua_print_gettime());

  有任何问题欢迎到原文与作者谈论学习。

  

[发帖际遇]:在深山偶遇世外高人糖果猪恋获得 5 积分.
泪水泡咖啡
鲜花 鲜花(0)鸡蛋 鸡蛋(0)
发表于 2015-7-27 20:21:19 | 显示全部楼层
注意:该代码只是为了方便使用自定义商品列表 标签的快速调用!

如果您使用HTML单独编辑,是很好.但如果你要更换其它商品就必须重新编辑!
使用自定义页面可以快速更换商品!
[发帖际遇]:泪水泡咖啡 在袁绍帐下镇守乌巢期间中饱私囊获得 2 ¥ 友盟币.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|三国在线 ( 豫ICP备11015806号 |

GMT+8, 2017-9-23 15:29

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表