上一章传送门:
本章我们来学习一个小demo,也就是上一章中的场景:c++从lua中获取一个全局变量的字符串。
1. 引入头文件
我们来看看要在c++中使用lua,需要些什么东西
#ifndef __hello_lua_h_
#define __hello_lua_h_
#include "cocos2d.h"
extern "c" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
};
using namespace cocos2d;
class hellolua : public cclayer {
public:
create_func(hellolua);
virtual bool init();
static ccscene* scene();
};
#endif
看到红色粗体的代码了吗?(旁白:在哪呢?在哪啊?)
在这:
不过没关系,cocos2d-x本来就支持lua,所以这一步我们省下了,为了保险起见,我在新建demo项目的时候勾选了支持lua。
建议大家首先能创建一个支持lua的cocos2d-x项目,并且能编译运行,然后再继续往下看~
(旁白:你就不能教我们引入lua库么?= =)
我教?我不懂~
2. 开始使用
来看看我们的cpp文件,我们要开始使用lua了~!
ccscene* hellolua::scene() {
ccscene* scene = ccscene::create();
cclayer* layer = hellolua::create();
scene->addchild(layer);
return scene;
}
bool hellolua::init() {
lua_state* pl = lua_open();
luaopen_base(pl);
luaopen_math(pl);
luaopen_string(pl);
/* 1.执行lua脚本,返回0代表成功 */
/* 2.重置栈顶索引 */
/* 3.判断栈顶的值的类型是否为string, 返回非0值代表成功 */
/* 4.获取栈顶的值 */
lua_close(pl);
return true;
}
为了不一下子就一大堆代码吓坏大家,我把部分代码先删了,我们来看看现在这个代码的情况:
1) hellolua是一个场景(旁白:废话…)
2) hellolua有一个init函数(旁白:你妹纸的,进入正题好不?)
3) 我就喜欢旁白吐槽~(旁白:….)
4) 要使用lua,首先要有一个lua_state,这是什么呢?我引用《游戏人工智能编程案例精粹》一书的一句话(191页):“每一个运行的脚本文件都在一个动态分配的叫做lua_state的数据结构中运行”。不明白的话,也没有关系,我们就把lua_state当成是一个lua的身体,lua在做任何事情的时候都不能没有身体。
5) 接下来看到几句话:luaopen_base(pl);luaopen_math(pl);luaopen_string(pl);
lua有一些标准库,要使用这些库,就要用luaopen_**去加载这些库
6) 然后最后还有一句话:lua_close(pl),一看就知道了,用来释放内存的。
7) 旁白呢?(旁白:心情不好…不想吐槽)
3. 执行lua脚本
现在我们来一步步完善我们的代码,执行lua脚本很简单,看看:
/* 1.执行lua脚本,返回0代表成功 */
int err = lual_dofile(pl, "hellolua.lua");
cclog("open : %d", err);
/* 2.重置栈顶索引 */
lua_settop(pl, 0);
lua_getglobal(pl, "myname");
/* 3.判断栈顶的值的类型是否为string, 返回非0值代表成功 */
/* 4.获取栈顶的值 */
lua_close(pl);
return true;
}
4. 重置栈顶索引, 将全局变量放到堆栈中
大家没有发现吗?我把第2步也放出来了~
(旁白:啊喂~!我说了好多次了,我发现了啊~!)
lua_settop(pl, 0);是为了确认让栈顶的索引置为0,因为我们操作栈的时候是根据索引来操作的。置0之后,我们入栈的第一个元素的索引就是1。
那,lua_getglobal(pl, “myname”);又是什么呢?咋一看好像是从lua中取得myname这个全局变量的值,但并不是这样的,虽然最终也是这样。
(旁白:你妹纸的,说清楚点)
我们之前说过了,lua和c++是不能直接通信的,要通过堆栈来通信。
因此,lua_getglobal(pl, “myname”);只是把myname放到了栈中,然后lua就会通过myname去全局表寻找,找到myname对应的字符串“beauty girl”,再放到栈中。(第01章的时候介绍过的步骤,还记得吗?不记得的建议大家去看看~)
(旁白:停!让我缓冲一下…)
(旁白:
1.c++把myname放到堆栈
2.lua从堆栈取得myname
3.lua用myname去lua全局表查找获取myname对应的字符串,得到“beauty girl”字符串,然后再放回堆栈
4.最后c++就可以从堆栈中取得“beauty girl”字符串?
好~!明白了~)
5. 最后一步,c++取得字符串
我们来看看完整的代码:
/* 1.执行lua脚本,返回0代表成功 */
int err = lual_dofile(pl, "hellolua.lua");
cclog("open : %d", err);
/* 2.重置栈顶索引 */
lua_settop(pl, 0);
lua_getglobal(pl, "myname");
/* 3.判断栈顶的值的类型是否为string, 返回非0值代表成功 */
int isstr = lua_isstring(pl, 1);
cclog("isstr = %d", isstr);
/* 4.获取栈顶的值 */
const char* str = lua_tostring(pl, 1);
cclog("getstr = %s", str);
lua_close(pl);
return true;
}
6. 赠送的
最后再告诉大家一个笑眯眯~
那就是用lua_pop(pl, 1); 可以清除指定堆栈上的数据~
噗,闪人~
(旁白:我帮他解释一下。。。是小秘密。。。不是笑眯眯= =)
如对本文有疑问, 点击进行留言回复!!
网友评论