lua游戏代码_在游戏中如何使用LUA脚本语言_lua如何用一段代码在游戏屏幕上添加一个按钮-程序员宅基地

技术标签: web  lua  游戏  开发语言  

当你希望在你的游戏开始的时候读取一些信息,以配置你的游戏,这些信息通常都是放到一个文本文件中,在你的游戏启动的时候,你需要打开这个文件,然后解析字符串,找到所需要的信息。

或许你认为这样就足够了,为什么还要使用Lua呢?

    应用于“配置”这个目的,Lua提供给你更为强大,也更为灵活的表达方式,在上一种方式中,你无法根据某些条件来配置你的游戏,Lua提供给你灵活的表达方式,你可以类似于这样来配置你的游戏:

if player:is_dead() then
do_something()
else
do_else()
end

更为重要的是,在你做了一些修改之后,完全不需要重新编译你的游戏代码。

通常,在游戏中你并不需要一个单独的解释器,你需要在游戏来运行解释器,下面,让我们来看看,如何在你的代码中运行解释器:

 

//这是lua所需的三个头文件
//当然,你需要链接到正确的lib

extern "C"

{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

}

int main(int argc, char *argv[])
{
lua_State *L = lua_open();

// 此处记住,当你使用的是5.1版本以上的Lua时,请修改以下两句为luaL_openlibs(L);
luaopen_base(L); 
luaopen_io(L);

const char *buf = "print('hello, world!')";

// 记住,当你使用的是5.1版本以上的Lua时请使用luaL_dostring(L,buf);

lua_dostring(buf);

lua_close(L);

return 0;
}

程序输出:hello, world!

有时你需要执行一段字符串,有时你可能需要执行一个文件,当你需要执行一个文件时,你可以这么做:
lua_dofile(L, "test.lua");

看,非常简单吧。

下面让我们来看看如何从脚本中取得我们所需要的信息。

首先,让我来简单的解释一下Lua解释器的工作机制,Lua解释器自身维护一个运行时栈,通过这个运行时栈,Lua解释器向主机程序传递参数,所以我们可以这样来得到一个脚本变量的值:

lua_pushstring(L, "var"); //将变量的名字放入栈
lua_gettatbl(L, LUA_GLOBALSINDEX);变量的值现在栈顶

假设你在脚本中有一个变量 var = 100
你可以这样来得到这个变量值:
int var = lua_tonumber(L, -1);

怎么样,是不是很简单?

Lua定义了一个宏让你简单的取得一个变量的值:
lua_getglobal(L, name)

我们可以这样来取得一个变量的值:
lua_getglobal(L, "var"); //变量的值现在栈顶
int var = lua_tonumber(L, -1);

完整的测试代码如下:

#include "lua.h"
#inculde "lauxlib.h"
#include "lualib.h"

int main(int argc, char *argv[])
{
lua_State *L = lua_open();

// 此处记住,当你使用的是5.1版本以上的Lua时,请修改以下两句为luaL_openlibs(L);
luaopen_base(L);
luaopen_io(L);

const char *buf = "var = 100";

lua_dostring(L, buf);

lua_getglobal(L, "var");
int var = lua_tonumber(L, -1);

assert(var == 100);

lua_close(L);

return 0;

调用函数

假设你在脚本中定义了一个函数:

function main(number)
number = number + 1
return number
end

在你的游戏代码中,你希望在某个时刻调用这个函数取得它的返回值。

在Lua中,函数等同于变量,所以你可以这样来取得这个函数:

lua_getglobal(L, "main");//函数现在栈顶

现在,我们可以调用这个函数,并传递给它正确的参数:

lua_pushnumber(L, 100); //将参数压栈
lua_pcall(L, 1, 1, 0); //调用函数,有一个参数,一个返回值
//返回值现在栈顶
int result = lua_tonumber(L, -1);

result 就是函数的返回值

完整的测试代码如下:

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

int main(int argc, char *argv[])
{
lua_State *L = lua_open();

// 此处记住,当你使用的是5.1版本以上的Lua时,请修改以下这句为luaL_openlibs(L);
luaopen_base(L);

const char *buf = "function main(number) number = number + 1 return number end";

lua_dostring(buf);

lua_getglobal(L, "main");
lua_pushnumber(L, 100);
lua_pcall(L, 1, 1, 0);

int result = lua_tonumber(L, -1);

assert(result == 101);

lua_close(L);

return 0;
}

脚本调用程序

Lua本身定位在一种轻量级的,灵活的,可扩充的脚本语言,这意味着你可以自由的扩充Lua,为你自己的游戏量身定做一个脚本语言。

你可以在主机程序中向脚本提供你自定的api,供脚本调用。

Lua定义了一种类型:lua_CFunction,这是一个函数指针,它的原型是:
typedef int (*lua_CFunction) (lua_State *L);

这意味着只有这种类型的函数才能向Lua注册。

首先,我们定义一个函数

int foo(lua_State *L)
{
//首先取出脚本执行这个函数时压入栈的参数
//假设这个函数提供一个参数,有两个返回值

//get the first parameter
const char *par = lua_tostring(L, -1);

printf("%s/n", par);

//push the first result
lua_pushnumber(L, 100);

//push the second result
lua_pushnumber(L, 200);

//return 2 result
return 2;
}

我们可以在脚本中这样调用这个函数

r1, r2 = foo("hello")

print(r1..r2)

完整的测试代码如下:

extern "C"

{

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

}

int foo(lua_State *L)
{
//首先取出脚本执行这个函数时压入栈的参数
//假设这个函数提供一个参数,有两个返回值

//get the first parameter
const char *par = lua_tostring(L, -1);

printf("%s/n", par);

//push the first result
lua_pushnumber(L, 100);

//push the second result
lua_pushnumber(L, 200);

//return 2 result
return 2;
}

int main(int argc, char *argv[])
{
lua_State *L = lua_open();

// 此处记住,当你使用的是5.1版本以上的Lua时,请修改以下两句为luaL_openlibs(L);
luaopen_base(L);
luaopen_io(L);

lua_register(L, "foo", foo);

const char *buf = "r1, r2 = foo("hello") print(r1..r2)";

lua_dostring(L, buf);

lua_close(L);

return 0;
}

程序输出:hello100200

local grid = {
  { 11, 12, 13 },
  { 21, 22, 23 },
  { 31, 32, 33 }
}

for y, row in ipairs(grid) do
  for x, value in ipairs(row) do
    print(x, y, grid[y][x])
  end
end

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yetaodiao/article/details/128411169

智能推荐

数据仓库ODS、DW和DM概念区分_ods-->dw-->dm-程序员宅基地

文章浏览阅读778次,点赞2次,收藏5次。数据仓库ODS、DW和DM概念区分今天看了一些专业的解释,还是对ODS、DW和DM认识不深刻,下班后花时间分别查了查它们的概念。ODS——操作性数据DW——数据仓库DM——数据集市1.数据中心整体架构数据仓库的整理架构,各个系统的元数据通过ETL同步到操作性数据仓库ODS中,对ODS数据进行面向主题域建模形成DW(数据仓库),DM是针对某一个业务领域建立模型,具体用户(决策层..._ods-->dw-->dm

iphone GNU debugger 1708下载地址-程序员宅基地

文章浏览阅读159次。cydia种添加http://cydia.radare.org源,然后搜索gnu debugger就可以了~~转载于:https://www.cnblogs.com/GrowUP-EveryDay/archive/2013/03/07/2947357.html_gnu project debugger下载

优化css性能有哪些方法?_css优化方法-程序员宅基地

文章浏览阅读1.5k次。虽然css在整个项目中占的比重并不多,但是他也是贯穿页面的全程的,一些细节上的性能优化是十分必要的。方法有很多,主要围绕,css加载,选择器嵌套,http请求内联首屏关键CSS 异步加载CSS 资源压缩 合理使用选择器 减少使用昂贵的属性 不要使用@import内联首屏关键CSS这个可能对于一些大项目而言做起来过于麻烦,但是也是一种不错的性能优化方案,在一个页面打开的时候,首要的内容出现在屏幕上的时间影响着用户体验,在加载html页面的时候如果通过链接的方式去加载css的话,需要等到_css优化方法

手动实现循环神经网络RNN,神经网络rnn是什么意思_手工实现rnn网络-程序员宅基地

文章浏览阅读634次。从 Siri 到谷歌翻译,深度神经网络已经在机器理解自然语言方面取得了巨大突破。这些模型大多数将语言视为单调的单词或字符序列,并使用一种称为循环神经网络(recurrent neural network/RNN)的模型来处理该序列。但是许多语言学家认为语言最好被理解为具有树形结构的层次化词组,一种被称为递归神经网络(recursive neural network)的深度学习模型考虑到了这种结构,这方面已经有大量的研究。虽然这些模型非常难以实现且效率很低,但是一个全新的深度学习框架 PyTorch 能使它们_手工实现rnn网络

EA(Enterprise Architect) 15 Browser突然消失_enterprise architect中browser-程序员宅基地

文章浏览阅读504次。EA Browser_enterprise architect中browser

随便推点

组蛋白修饰化合物库 | 药物筛选 | MCE-程序员宅基地

文章浏览阅读275次,点赞3次,收藏10次。MCE提供人内源性代谢物库,包括971个生物活性化合物,用于研究代谢组学和代谢相关药物开发。产品以溶液或粉末包装提供,具有多种浓度选择。化合物经临床前和临床试验验证,具有药用活性和细胞渗透性,是研究组蛋白修饰调控及相应疾病的有用工具。

flock lock ex php,在php中flock函数起什么作用呢?-程序员宅基地

文章浏览阅读92次。摘要:下文讲述php中flock()函数的功能简介说明,如下所示;php之flock()函数功能php之flock函数:flock函数的功能用于锁定或释放一个文件php之flock函数语法:flock(file,lock,block)-------参数说明-----file:必填参数,待锁定或释放的文件(此处文件必须已经打开)lock:必填参数,操作类型:lock=LOCK_SH ---共享锁定(..._phpflock作用

sqlite3命令行把.db文件导成.txt时报错及中文乱码_如何将db文件转换成文字-程序员宅基地

文章浏览阅读3.1k次。1.首先,我们有这样的需求:我有一个.db文件,想导出文件内容为.txt格式。这里推荐一个我自己用的,db查看器 SQLite Expert Personal链接:https://pan.baidu.com/s/1QgnDJaNjRVPVr3KZfLVcXA 密码:x93e傻瓜式安装,把.db文件拖到该应用中就可以查看其中内容了。然而当我们想把内容复制出来,却会出现中文乱码。如此就..._如何将db文件转换成文字

树莓派4B远程桌面连接常见问题及解决方案:无外接屏幕情况下远程桌面不显示、vnc/向日葵无法连接ubuntu wayland桌面等_树莓派的ubuntu系统无法用vnc远程连接-程序员宅基地

文章浏览阅读1.3k次,点赞24次,收藏21次。背景:在树莓派上进行开发,需要连接屏幕、键盘、鼠标,部署麻烦、占地方不方便。通过ssh+远程桌面(如用于UI相关效果展示)的方式开发更加便利,SSH基本上都没问题,大家遇到问题比较多的是诸如是否需要外接屏幕、远程桌面无法连接、连接上黑屏。本文说下遇到的一些问题及解决方案,不一定是最优的方案,但能解决我的需求的方案就是好方案。_树莓派的ubuntu系统无法用vnc远程连接

Oracle HINT的常见用法(收藏)_oracle hint 别名用法-程序员宅基地

文章浏览阅读666次。提示(hint)从Oracle7中引入,目的是弥补基于成本优化器的缺陷。提示通常用来改变SQL执行计划,提高执行效率。使用提示需要遵循的原则:1)仔细检查提示语法。尽量使用完整注释语法/*+ hint */2)使用表别名。如果在查询中指定了表别名,那么提示必须也使用表别名。例如:select /*+ index(e,dept_idx) */ * from emp e;3)不_oracle hint 别名用法

STM32F103程序串口调用printf打印数据_stm32程序打印-程序员宅基地

文章浏览阅读1.2w次,点赞10次,收藏32次。程序开发过程中调试必不可少,一种简单直接的调试方式是使用串口发送数据,并使用串口助手进行观测。以前使用MSP430做项目时也同样使用printf打印数据,所以现在想在stm32 上实现。 通常串口发送单字节库函数:USART_SendData(USART1, (uint8_t) ch);对显示小数等数据比较复杂,如果能够直接使用C语言 stdio.h中的printf直接输出就可以省去大_stm32程序打印

推荐文章

热门文章

相关标签