没有其他的,搞搞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. HTML5 Storage API

    原文:HTML5 Storage API Web Storage是HTML5引入的一个非常重要的功能,可以在客户端本地存储数据,类似HTML4的cookie,但可实现功能要比cookie强大的多. 在 ...

  2. ASCII与Unicode编码消息写文件浅析

    [文章摘要] ASCII与Unicode是两种常见的字符编码. 它们的表示方法不一样,因而在程序中就要差别处理. 本文基于作者的实际开发经验,对ASCII与Unicode两种字符编码消息的写文件过程进 ...

  3. java中用正則表達式推断中文字符串中是否含有英文或者数字

    public static boolean includingNUM(String str)throws  Exception{ Pattern p  = Pattern.compile(" ...

  4. codeforces #550E Brackets in Implications 结构体

    标题效果:定义集合中{0,1}\{0,1\}上的运算符"→\rightarrow",定义例如以下: 0→0=10\rightarrow 0=1 0→1=10\rightarrow ...

  5. HDOJ 5000 Clone

    所有的属性,以满足一定的条件,是,财产和等于sum/2结果最大. Clone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536 ...

  6. 【转】Robot Framework 快速入门

    目录 介绍 概述 安装 运行demo 介绍样例应用程序 测试用例 第一个测试用例 高级别测试用例 数据驱动测试用例 关键词keywords 内置关键词 库关键词 用户定义关键词 变量 定义变量 使用变 ...

  7. Cocos2d-iPhone V3 (1) 其基本程序常用的行动框架和介绍

    Cocos2d-iPhone V3 (1) 其基本程序常用的行动框架和介绍 博客:http://blog.csdn.net/prevention 笔者:犀利哥 - 第一部分:一个 Cocos2d-iP ...

  8. JAVA学习(二):JDK介绍及其结构、用途

    JDK介绍及其结构.用途 1.JDK的介绍 JDK是Java Development Kit 的缩写.是Sun Microsystems针对Java开发员的产品.它由一个处于操作系统层之上的执行环境还 ...

  9. 数据结构(C达到)------- 双链表

    双链表中的每个节点包含两个指针域,指针域包含其后继节点的内存地址,还有一个指针所存储的存储器地址其领域前驱节点. 双向链表结点的类型描写叙述: //双向链表的类型描写叙述 typedef int El ...

  10. 实现android里面WebView显示内容

    在日常学习.我们会看到,当手机应该检查注册协议.单击协议时,以查看内部协议的全部内容! 以下给大家看看实现的过程: 首先贴show_xy.XML代码: <WebView android:layo ...