视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
【游戏开发笔记】--Lua基础与应用
2025-09-24 20:59:11 责编:小OO
文档
【游戏开发笔记】Lua基础与应用

有关Lua的FAQ

Q:Lua是什么?

A:Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。(感谢百度百科)

Q:为什么用Lua?

A: 1、开源,就是不用钱。

2、灵活扩展你的软件(增加游戏关卡,制作文字类游戏等等)

3、灵活进行软件配置(例如一个GUI程序的界面微调,而且支持if...else...这样的配置方式,爽吧)

4、弱类型,这意味着在宿主语言内比较麻烦的逻辑计算操作都可以扔给lua

5、纯c编写,意味着比python这样的老牌脚本语言运行更快(话说python跑在虚拟机上的,跟java差不多)

Q:我感觉我很菜,能学习Lua么?

A:话说我也很菜。。总之你学会c语言后就能学Lua了,programming in lua里面有lua与c交互的例子。会c++更佳,游戏开发你总要会c++吧

一、新手任务——编译静态库,解析器,编译器

lua官网

http://www.lua.org/

找到最新的版本5.2.2下载下来

其实我们得到的是一堆源码,打开src文件夹看看

所以我们要自己编译想要的东西= =

先打开高端洋气的vs2012(呵呵

(配置方法跟微软其他的IDE差不多,只用vs2012举例)

新建一个空的控制台程序。然后把lua源码复制到工程目录下

并添加到项目

在release下配置类型为lib

为了编译静态库,需要把下面两个文件移除到工程外(lua.cpp是编译解析器的,luac就是用来编译编译器的= =)

如果你是用vs2012编译lib,请添加这个宏(感谢CHU提醒)

_CRT_SECURE_NO_WARNINGS

编译成功,生成lib

收起回复

∙6楼

∙2013-07-05 08:25

∙举报 |

wishout: 自己在桌面建一个文件夹先把lib保存起来吧= =

2013-7-5 08:27 回复

⑨chu: 你为何不直接点上面那个静态库呢。。

2013-7-7 00:04 回复

梦里—唱忧伤: 同问,建工程直接选静态库就是。

接下来编译解析器= =

把配置类型改为exe 把用来编译解析器的lua.cpp添加回项目中

编译ok,生成编析器

为了在控制台下使用方便,可以改名为lua.exe

继续保存到新建的文件夹里= =

编译解编译器,把luac.cpp添加到项目,移除lua.h,lua.cpp

改名为luac.exe保存到刚才的文件夹下,现在我们要用到的东西都做好了,欧耶~

在使用这些东西之前,我们先来简单地了解一下lua语法,想深入学习的同学自己找些专业的资料

1、lua类型

lua分为这些类型Nil、Booleans、Numbers、Strings、Functions、Userdata、Threads

这些看名字都能懂吧。

Nil就是空,就是什么都没有(话说在java里面null不是一个对象,那老师怎么整天在说java一切都是对象,害我java考试那题没分了= =)

Booleans是布尔型,true 和 false

Numbers是数值类型,在lua里面,你学过的int float double long short都是这种数值类型,所以知道lua为什么被叫做弱类型语言了吧

而且由于我们可以这样声明一个Numbers

a = 4

b = 0.4

c = 4.57e - 3

d = 0.3e12

跟python一样,lua变量的类型只有在执行脚本的时候被确定,所以前面不用声明类型

Strings是字符串类型

通用地,我们这样声明一个Strings

s = "hello wishout!"

那些转义字符例如'\\n', '\', '\\\\'跟c是一样的,放心用吧

Functions是函数类型

在lua里面,我们这样下面的形式使用函数

function [函数名]([参数一], [参数二], [参数三]...)

end 

哈哈,很简单吧

比如我们写一个NPC对话的函数

function PrintNPCMsg(msg)

print(msg)

end

2、表达式

算术运算符

+ - * / ^(加减乘除,还有幂!)

-(相反数)

关系运算符

< > <= >= == ~=

注意lua里面没有!=这个东西,被取代为~=

逻辑运算符

and or not(与、或、非)

特殊地,在字符串操作中,lua有很方便的一个操作符

..(两个点号,用来连接连个字符串)

例如

"hello " .. "wishout!" == "hello wishout!"

3、luaの神器——table的构造

为什么说table是神器呢?因为它很神啊!(废话)

table是lua里特有的东西(也不算特有吧,python也有元组,字典之类的东西)

类似于c语言里面数组的东西

构造方法如下

mytable = {"wishout", "sama", "i", "love", "you!", 1, 2, 3}

table里面可以放你任何想放的东西

table构造完以后,我们像访问数组一样访问table,注意lua的table下标从1开始,Strings也一样

mytable[1] == "wishout"

mytable[3] == "i"

mytable[6] == 1

字典方法构造table

mytable = {master = "wishout", servant = "you"}

我们现在可以这样访问table

mytable["master"] == "wishout"

servant["servant"] == "you"

用这样方法配置游戏相当的爽

config = {client_x = 100, client_y = 100, width = 0, height = 480, windowed = false}

这种方法还能管理游戏素材的映射,相当方便,欧耶~

我现在做的一个小游戏是这样管理一个背景纹理的映射的

我在c++里面就能很方便的取得这个背景纹理的信息,不用硬编码就是很爽啊

3、luaの神器(续)——table的遍历与维护

我们用# tablename这样方式取得一个table的长度,这种方法也适用于求一个字符串的长度

例如

mytable = {"wishout", "sama", "i", "love", "you!", 1, 2, 3}

s = "123"

# mytable == 8

# s == 3

既然我们得到了table的长度,我们就能遍历这个table

for i = 1, # mytable do 

print(mytable[i])

end

输出:

wishout

sama

i

love

you!

1

2

3

我们这里使用了一个循环语句的知识,语法如下

for i = [起始下标], [终止下标], [步长] do

[循环体]

end

我们步长不写默认为一

往table里面插入元素的方法

table.insert(tablename, tableitem)

例如

table.insert(mytable, "shit")

也可以插入一个table

table.insert(mytable, {"holy ", "shit!"})

删除table元素的方法

table.remove(tablename, tableindex)

例如

table.remove(mytable, 1)

清空table的方法(so easy...)

tablename = {}

4、基本语法

控制语句

if [条件] then

[dotask]

end

if [条件] then

[dotask_1]

else

[dotask_2]

end

if [条件一] then

[dotask_1]

elseif [条件二] then

[dotask_2]

end

循环语句

while [条件] do

[循环体]

end

repeat 

[循环体]

util [条件]

for i = [起始下标], [终止下标], [步长] do

[循环体]

end

*break在lua里的用法一样

*return用法一样

*lua里有个local关键字,被local声明的变量只在被声明的代码块里面有效

wishout: 以上语法在游戏开发里基本够用,更多高级语法请参详专业资料

二、点亮武器天赋——静态库、编译器、解析器的使用,两个好用的lua编辑器

好吧,我们学习完了lua的基本语法,现在拿我们编译好的东西玩玩\(^o^)/

我们先新建一个lua脚本文件,键入一条简单的语句

与解析器、编译器放在同一目录下

在命令行下进入该目录

使用lua -i命令进入lua交互模式,你能看到自己正在使用的lua版本

我们使用dofile("filename")命令调用lua解析器执行特定脚本

上面是执行lua脚本的方法一

下面介绍方法二

我们可以用luac.exe先把lua脚本编译一次,再去执行编译后的脚本,这样用户就不能随意修改我们编译后的脚本了,哈哈

首先退出交互模式

我们用这种形式编译特定脚本

luac -o [编译后脚本名] [脚本名]

编译成功后,目录下生成一个文件

再次进入交互模式,执行这个文件

执行结果是一样的,但这种方法能杜绝玩家修改脚本的可能

刚才我们使用notepad编辑lua脚本,作为一个程序猿,不会装逼怎么行!

所以呢,我向大家介绍两个好用的编辑器,如果你用过,当我没说= =

屌丝的好帮手——notepad++

如果你经常在window写代码,应该对这款软件有所耳闻吧,看看它的lua高亮方案

大概就是这种效果,还是蛮顺眼的= =

高帅的象征——Sublime Text 2

我从刚用sublime text 2的时候,瞬间有种屌丝变高帅,村里刚通网的感觉!我马上意识到,这是一款高帅的软件,帅的无法直视啊啊啊啊啊

lua高亮方案

Sublime Text 2还支持脚本的执行(果然是高帅的软件),实际上要配置一下的,自己到网上找= =

使用静态库——c/c++与lua的交互

在vs下建立一个控制台空项目,项目包含src下面的头文件,附加库和依赖项填好刚才编译好的lib

项目里建立一个源文件Main.cp,包含我们要用到的头文件

#include "lua.h" 

#include "lualib.h" 

#include "lauxlib.h" 

声明一个全局变量

lua_State * L;

在main里面开始lua的初始化工作

//开启lua状态机

L = luaL_newstate();

//装载lua库

luaL_openlibs(L);

相比起d3d,lua的初始化操作太简单了,我要感动的哭了T_T

//执行脚本 

luaL_dofile(L, "res.lua");

//关闭lua状态机

lua_close(L);

c++调用lua函数的例子

//c++调用lua函数

void PrintMsg(const char * msg)

{

//填充一个lua函数名

lua_getglobal(L, "PrintMsg"); 

//参数进栈 

lua_pushstring(L, msg);

//使用lua_pcall调用lua本函数 

if(lua_pcall(L, 1, 0, 0) != 0) 

std::cout << "FAILED - PrintMsg(): " << std::cout << lua_tostring(L, -1);

}

void main (void)

//开启lua状态机

L = luaL_newstate(); 

//装载lua库

luaL_openlibs(L); 

//执行脚本 

luaL_dofile(L, "mylua.lua");

//调用函数

PrintMsg("hello wishout!");

system("pause");

//关闭lua状态机lua_close(L);

}

//lua脚本

function PrintMsg(msg)

print(msg)

end

lua调用c++函数的例子

//lua调用c++函数

int Add(lua_State * L)

//提取参数 

int a = (int)lua_tonumber(L, 1); 

int b = (int)lua_tonumber(L, 2);

//c++实际完成的工作 

int c = a + b;

//计算结果进栈 

lua_pushnumber(L, c);

//因为要返回一个参数,所以要return 1 

return 1;

}

void main (void){

//开启lua状态机

L = luaL_newstate();

//装载lua库 

luaL_openlibs(L);

//往lua脚本添加c++函数

lua_pushcfunction(L, Add);

//添加一个函数名 

lua_setglobal(L, "Add");

//执行脚本luaL_dofile(L, "mylua.lua");

system("pause");

//关闭lua状态机

lua_close(L);

}

lua脚本

print(Add(1, 2))

三、魔法学堂——lua的简单应用

嘛嘛,楼主写了一上午的帖子,这层就结束了

下面是我以前练手用的控制台版avg源码,里面有注释,可以简单看一下lua的实际使用(我承认写的很渣= =)

http://pan.baidu.com/share/link?shareid=3286131315&uk=1208824379

---完---

表扬吧主大人的无私奉献

咳咳

然后、、其实、、Lua的CAPI用起来不是那么简单的,你要查询每个函数会造成什么副作用

比如会对lua虚拟机的堆栈造成什么影响(弹出几个元素、加入几个元素)

Lua本身还涉及到GC、注册表、Upvalue等等各种概念

为了方便与C++交互,网上有很多Lua的扩展。

如tolua+、luabind、luaplus等等

通过这些扩展你可以直接在lua里面创建一个C++类。

把C++类成员函数绑定到lua里面等等下载本文

显示全文
专题