没有其他的,搞搞cocos2dx的lua文字,话lua这件事情在几年前学过一段时间。还曾对自己c++介面,我已经做了一些小东西。只是时间的流逝,模糊记忆。

拿起点功夫和成本。下面是我的一些经验。





cocos2dx运用tolua++来制作的lua接口,tolua++文档不多,网上的一些文章也是答非所问,所以自己看代码是最佳学习途径。

cocos2dx操作lua的类是CCLuaEngine,当中实现了载入与实行lua脚本。以及操作lua stack。

LuaCocos2d.cpp非常主要,文件的开头凝视也说明其是由tolua++自己主动生成的,我们想在lua中操作自定义的类就是通过改动此文件实现的,两个重要函数是void tolua_reg_types (lua_State* tolua_S)与int tolua_Cocos2d_open (lua_State* tolua_S),前者是注冊自定义类型,后者是定义其接口,调用关系是tolua_Cocos2d_open调用tolua_reg_types,而tolua_Cocos2d_open是在CCLuaEngine的init中调用的。

如果我要向lua注冊新类。那么首先我要在tolua_reg_types中加入一行注冊代码,然后在tolua_Cocos2d_open加入其接口说明。我将这两个步骤定义成两个函数,单独在一个文件里实现。文件名称为cwLuaReg.cpp,内容为:

#include "cwLuaReg.h"





#include "cwGameObject.h"

#include "cwCollisionObject.h"

#include "cwGravityObject.h"





#ifdef __cplusplus





static int tolua_collect_cwGameObject(lua_State* tolua_S)

{

    cwGameObject* self = (cwGameObject*) tolua_tousertype(tolua_S,1,0);

    delete self;

    return 0;

}





static int tolua_collect_cwGravityObject(lua_State* tolua_S)

{

    cwGravityObject* self = (cwGravityObject*) tolua_tousertype(tolua_S,1,0);

    delete self;

    return 0;

}





#ifndef TOLUA_DISABLE_tolua_cw_GameObject_create00

static int tolua_cw_GameObject_create00(lua_State* tolua_S)

{

    tolua_Error tolua_err;

    if(!tolua_isusertable(tolua_S,1,"cwGameObject",0,&tolua_err) ||

        !tolua_isnoobj(tolua_S,2,&tolua_err))

        goto tolua_lerror;

    else

    {

        {

            cwGameObject* tolua_ret = (cwGameObject*)  cwGameObject::create();

            int nID = (tolua_ret) ? (int)tolua_ret->m_uID : -1;

            int* pLuaID = (tolua_ret) ?

&tolua_ret->m_nLuaID : NULL;

            toluafix_pushusertype_ccobject(tolua_S, nID, pLuaID, (void*)tolua_ret,"cwGameObject");

        }

    }

    return 1;

tolua_lerror:

    return 0;

}

#endif //#ifndef TOLUA_DISABLE





#ifndef TOLUA_DISABLE_tolua_cw_GameObject_getSpeed00

static int tolua_cw_GameObject_getSpeed00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

    tolua_Error tolua_err;

    if (!tolua_isusertype(tolua_S,1,"cwGameObject",0,&tolua_err) ||

        !tolua_isnoobj(tolua_S,2,&tolua_err))

        goto tolua_lerror;

    else

#endif

    {

        cwGameObject* self = (cwGameObject*)  tolua_tousertype(tolua_S,1,0);

#ifndef TOLUA_RELEASE

        if (!self) tolua_error(tolua_S,"invalid 'self' in function 'speed'", NULL);

#endif

        {

            float tolua_ret = (float)  self->speed();

            tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);

        }

    }

    return 1;

#ifndef TOLUA_RELEASE

    tolua_lerror:

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

    return 0;

#endif

}

#endif





#ifndef TOLUA_DISABLE_tolua_cw_GameObject_setSpeed00

static int tolua_cw_GameObject_setSpeed00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

    tolua_Error tolua_err;

    if (!tolua_isusertype(tolua_S,1,"cwGameObject",0,&tolua_err) ||

        !tolua_isnumber(tolua_S,2,0,&tolua_err) ||

        !tolua_isnoobj(tolua_S,3,&tolua_err))

        goto tolua_lerror;

    else

#endif

    {

        cwGameObject* self = (cwGameObject*)  tolua_tousertype(tolua_S,1,0);

        float speed = ((float)  tolua_tonumber(tolua_S,2,0));

#ifndef TOLUA_RELEASE

        if (!self) tolua_error(tolua_S,"invalid 'self' in function 'setSpeed'", NULL);

#endif

        {

            self->setSpeed(speed);

        }

    }

    return 0;

#ifndef TOLUA_RELEASE

    tolua_lerror:

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

    return 0;

#endif

}

#endif





#ifndef TOLUA_DISABLE_tolua_cw_GameObject_getMoveDir00

static int tolua_cw_GameObject_getMoveDir00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

    tolua_Error tolua_err;

    if (!tolua_isusertype(tolua_S,1,"cwGameObject",0,&tolua_err) ||

        !tolua_isnoobj(tolua_S,2,&tolua_err))

        goto tolua_lerror;

    else

#endif

    {

        cwGameObject* self = (cwGameObject*)  tolua_tousertype(tolua_S,1,0);

#ifndef TOLUA_RELEASE

        if (!self) tolua_error(tolua_S,"invalid 'self' in function 'getMoveDir'", NULL);

#endif

        cwVector2D& dir = self->moveDir();

        tolua_pushnumber(tolua_S,(lua_Number)dir.x);

        tolua_pushnumber(tolua_S,(lua_Number)dir.y);

    }

    return 2;

#ifndef TOLUA_RELEASE

    tolua_lerror:

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

    return 0;

#endif

}

#endif





#ifndef TOLUA_DISABLE_tolua_cw_GameObject_setMoveDir00

static int tolua_cw_GameObject_setMoveDir00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

    tolua_Error tolua_err;

    if (!tolua_isusertype(tolua_S,1,"cwGameObject",0,&tolua_err) ||

        !tolua_isnumber(tolua_S,2,0,&tolua_err) ||

        !tolua_isnumber(tolua_S,3,0,&tolua_err) ||

        !tolua_isnoobj(tolua_S,4,&tolua_err))

        goto tolua_lerror;

    else

#endif

    {

        cwGameObject* self = (cwGameObject*)  tolua_tousertype(tolua_S,1,0);

        float dirX = ((float)  tolua_tonumber(tolua_S,2,0));

        float dirY = ((float)  tolua_tonumber(tolua_S,3,0));

#ifndef TOLUA_RELEASE

        if (!self) tolua_error(tolua_S,"invalid 'self' in function 'setMoveDir'", NULL);

#endif

        self->setMoveDir(dirX, dirY);

    }

    return 0;

#ifndef TOLUA_RELEASE

    tolua_lerror:

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

    return 0;

#endif

}

#endif





#endif





TOLUA_API int tolua_cwLua_reg_types(lua_State* tolua_S)

{

    //add by sunny

    tolua_usertype(tolua_S,"cwGameObject");

    tolua_usertype(tolua_S,"cwGravityObject");

    //end sunny





    return 1;

}





TOLUA_API int tolua_cwLua_reg(lua_State* tolua_S)

{

#ifdef __cplusplus

    tolua_cclass(tolua_S,"cwGameObject","cwGameObject","CCSprite",tolua_collect_cwGameObject);

#else

    tolua_cclass(tolua_S,"cwGameObject","cwGameObject","CCSprite",NULL);

#endif





    tolua_beginmodule(tolua_S,"cwGameObject");

    tolua_function(tolua_S,"create",tolua_cw_GameObject_create00);

    tolua_function(tolua_S,"speed",tolua_cw_GameObject_getSpeed00);

    tolua_function(tolua_S,"setSpeed",tolua_cw_GameObject_setSpeed00);

    tolua_function(tolua_S,"moveDir",tolua_cw_GameObject_getMoveDir00);

    tolua_function(tolua_S,"setMoveDir",tolua_cw_GameObject_setMoveDir00);

    tolua_endmodule(tolua_S);





#ifdef __cplusplus

    tolua_cclass(tolua_S,"cwGravityObject","cwGravityObject","cwGameObject",tolua_collect_cwGravityObject);

#else

    tolua_cclass(tolua_S,"cwGravityObject","cwGravityObject","cwGameObject",NULL);

#endif





    tolua_beginmodule(tolua_S,"cwGravityObject");

    tolua_endmodule(tolua_S);





    return 1;

}





将tolua_cwLua_reg_types和tolua_cwLua_reg分别加到LuaCocos2d.cpp相应函数末尾。这样两个类cwGameObject与cwGravityObject就能够在lua中使用了。

做到这还不能达到我的期望,原因是cocos2d的luaproject里。在AppDelegate::applicationDidFinishLaunching函数中仅仅是载入并运行了hello.lua脚本文件。然后一切就都交给lua了,而我仅仅是想使用lua实现一些AI方面的功能,即cwGameObject在须要运行AI时。调用lua中的一个函数。所以我须要的是一个能够调用lua函数的功能,查看了一下CCLuaEngine类。貌似没有我想要的。仅仅能自己添了个函数:

virtual int executeGlobalFunction(const char* functionName, float dt, CCObject* pObject, const char* typeName);

functionName:被调lua函数名;dt:帧时间间隔。pObject:调用lua的对象;typeName:pObject对象类型

实现例如以下:

int CCLuaEngine::executeGlobalFunction(const char* functionName, float dt, CCObject* pObject, const char* typeName)

{

    lua_getglobal(m_state, functionName);      





    if (!lua_isfunction(m_state, -1))

    {

        CCLOG("[LUA ERROR] name '%s' does not represent a Lua function", functionName);

        lua_pop(m_state, 1);

        return 0;

    }





    pushFloat(dt);

    pushCCObject(pObject, typeName);





    int error = lua_pcall(m_state, 2, 1, 0);            





    if (error)

    {

        CCLOG("[LUA ERROR] %s", lua_tostring(m_state, - 1));

        lua_pop(m_state, 1); // clean error message

        return 0;

    }





    // get return value

    if (!lua_isnumber(m_state, -1))

    {

        lua_pop(m_state, 1);

        return 0;

    }





    int ret = lua_tointeger(m_state, -1);

    lua_pop(m_state, 1);                                               

    return ret;

}

基本上是照着其它函数扒下来的,不同之处就是加了两个push。

函数写的比較死。能够写一个接受可变參数的函数,做的通用些。





如果我要在cwGameObject的upadte函数中调用“do_obj_update”lua函数,写法例如以下:

void cwGameObject::update(float dt)

{

    CCLuaEngine::defaultEngine()->executeGlobalFunction("do_obj_update", dt, this,"cwGameObject");

}

这样在创建cwGameObject时scheduleUpdate一下就能够了。





lua脚本:

-- for CCLuaEngine traceback

function __G__TRACKBACK__(msg)

    print("----------------------------------------")

    print("LUA ERROR: " .. tostring(msg) .. "\n")

    print(debug.traceback())

    print("----------------------------------------")

end





winSize = CCDirector:sharedDirector():getWinSize()





-- avoid memory leak

collectgarbage("setpause", 100)

collectgarbage("setstepmul", 5000)





function do_obj_update(dt, obj)

    local x, y = obj:getPosition()

    local vx, vy = obj:moveDir()





    x = x + vx*dt*obj:speed()

    y = y + vy*dt*obj:speed()





    if x < 0 then

        x = 0

        obj:setMoveDir(-vx, vy)

    end





    if x > winSize.width then

        x = winSize.width

        obj:setMoveDir(-vx, vy)

    end

   

    if y < 0 then

        y = 0

        obj:setMoveDir(vx, -vy)

    end





    if y > winSize.height then

        y = winSize.height

        obj:setMoveDir(vx, -vy)

    end





    obj:setPosition(x, y)

end





print("test.lua loaded.")





脚本非常easy,do_obj_update函数仅仅是做了一些边框推断。

别忘了改动AppDelegate::applicationDidFinishLaunching加载脚本文件名~~

cocos2dx版本号:cocos2d-2.0-x-2.0.3

http://blog.csdn.net/honghaier/article/details/8700574

转让lua性能executeGlobalFunction的更多相关文章

  1. 怎么调试lua性能

    怎么调试lua性能 我们的游戏使用的是Cocos2dx-lua 3.9的项目,最近发现我们的游戏.运行比较缓慢.想做一次性能优化了.其实主要分为GPU.CPU的分别优化.GPU部分的优化.网上有很多优 ...

  2. Lua性能优化

    原文:Lua Performance Tips 偶然找到<Lua Performance Tips>这篇关于Lua的优化文章,个人认为相较于多数泛泛而谈要好不少.尽管Lua已经到5.2版本 ...

  3. Lua 性能相关笔记

    1.创建一个闭合函数要比创建一个table更廉价,访问非局部的变量也比table字段更快. 2.访问局部变量要比全局变量更快,尽可能的使用局部变量,可以避免无用的名称引入全局环境. 3.do-end语 ...

  4. C++转让Lua

    转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/39756423 我使用的cocos2d-x版本号是2.3.3.先在一个C++projec ...

  5. [Lua性能] 小试验一例

    local s1 = os.clock() local list1 = {} , do list1[#list1 + ] = end local e1 = os.clock() print(" ...

  6. lua的性能优化

    Roberto Ierusalimschy写过经典的Lua 性能提示的文章,链接地址>> 我通过实际的代码来验证,发现一个问题.当我使用 LuaStudio 运行时,发现结果反而与提示相反 ...

  7. 使用Lua 局部变量来优化性能,同一时候比較局部变量和全局变量

    在竞争激烈的游戏行业中,尤其页游,面对策划复杂和频繁的需求,使用脚本能够减少难度和成本.在使用Lua的过程中,会常常訪问全局变量来作为配置文件. 在訪问全局变量时,能够通过局部变量引用全局变量来优化. ...

  8. Lua 架构 The Lua Architecture

    转载自:http://magicpanda.net/2010/10/lua%E6%9E%B6%E6%9E%84%E6%96%87%E6%A1%A3/ Lua架构文档(翻译) 十 102010 前段时间 ...

  9. 深入浅出Lua虚拟机

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:郑小辉 | 腾讯 游戏客户端开发高级工程师 写在前面:本文所有的文字都是我手工一个一个敲的,以及本文后面分享的Demo代码都是我一行一 ...

随机推荐

  1. Tomcat启动错误,端口占用

    错误信息: Several ports (8080, 8009) required by Tomcat v7.0 Server at localhost are already in use. The ...

  2. SqlServer service broker 分布式系统(赵松桃)跳水 2005 数据库编程

    1.创建一个测试数据库 create database ServerbrokerTest on primary( name=ServerbrokerTest_data, filename='C:\Pr ...

  3. Nginx各版本的区别

    Nginx官网提供了三个类型的版本Mainline version:Mainline 是 Nginx 目前主力在做的版本,可以说是开发版Stable version:最新稳定版,生产环境上建议使用的版 ...

  4. ABP-N层架构

    ABP理论学习之N层架构   返回总目录 自从写这个系列博客之后,发现很多园友还是希望有个直接运行的demo,其实在github上就有官方的demo,我直接把这demo的链接放到这里吧,另外,我分析, ...

  5. 几款开源ESB总线的比较(转)

    现有的开源ESB总线中,自从2003年第一个开源总线Mule出现后,现在已经是百花争鸣的景象了.现在我就对现有的各种开源ESB总线依据性能.可扩展性.资料文档完整程度以及整合难易程度等方面展开. CX ...

  6. JAVA 公众微信的开放源码项目管理合作伙伴招募的版本号

    大家好:       jeecg开源社区.现在正在进行"JAVA 开放源码的版本号项目微信公共账号"工作,有兴趣的朋友一起參与. 截止时间:20140510 採用技术: 1. JE ...

  7. crm操作观点

    using System;     using Microsoft.Xrm.Sdk;     using Microsoft.Crm.Sdk.Messages; /// <summary> ...

  8. 数据库管理——Powershell——使用Powershell脚本找出消耗最多磁盘空间的文件

    原文:数据库管理--Powershell--使用Powershell脚本找出消耗最多磁盘空间的文件 原文译自: http://www.mssqltips.com/sqlservertip/2774/p ...

  9. MTK MOTA升级步骤

    MOTA的前提下有其自己的server,MTK我在已经完成,可以MTK应用,然后移动到它自己的server向上. 1.打开ProjectConfig.mk中间MTK_SYSTEM_UPDATE_SUP ...

  10. android从中国天气网获取天气

    http://download.csdn.net/detail/sun6223508/8011669      里面的一切..可完全移植 版权声明:本文博主原创文章.博客,未经同意不得转载.