1. 程式人生 > >遊戲中使用LUA指令碼語言的簡介

遊戲中使用LUA指令碼語言的簡介

我們知道指令碼語言是解除硬編碼,防止重編譯的利器,可以這樣說,任何大型遊戲都有自己的腳本系統。

想要做出一款精品遊戲,指令碼語言也是我們需要掌握和運用的。

較流行的指令碼語言有Python,LUA,Ruby等。

LUA有著輕量,高效,接口乾淨等特點,學起來很快,風靡全球的《魔獸爭霸3:冰封王座》就是採用的LUA指令碼語言。

以下的內容非我原創,前幾天發現了這篇文章,覺得總結得不錯,於是我覺得偷下懶,省得自己總結,直接轉載過來供大家學習了。原文地址http://blog.csdn.NET/b2b160/article/details/4799302,我將內容進行了排版,程式碼進行了高亮顯示,更方便大家觀看了。

當你希望在你的遊戲開始的時候讀取一些資訊,以配置你的遊戲,這些資訊通常都是放到一個文字檔案中,在你的遊戲啟動的時候,你需要開啟這個檔案,然後解析字串,找到所需要的資訊。




    是的,或許你認為這樣就足夠了,為什麼還要使用Lua呢?

    應用於“配置”這個目的,Lua提供給你更為強大,也更為靈活的表達方式,在上一種方式中,你無法根據某些條件來配置你的遊戲,Lua提供給你靈活的表達方式,你可以類似於這樣來配置你的遊戲:

 print?
  1. if player:is_dead() then  
  2. do_something()  
  3. else
  4. do_else()  
  5. end  



更為重要的是,在你做了一些修改之後,完全不需要重新編譯你的遊戲程式碼。


通常,在遊戲中你並不需要一個單獨的直譯器,你需要在遊戲來執行直譯器,下面,讓我們來看看,如何在你的程式碼中執行直譯器:

 print?
  1. //這是lua所需的三個標頭檔案
  2. //當然,你需要連結到正確的lib
  3. extern"C"
  4. {  
  5. #include "lua.h"
  6. #include "lauxlib.h"
  7. #include "lualib.h"
  8. }  
  9. int main(int argc, char *argv[])  
  10. {  
  11. lua_State *L = lua_open();  
  12. // 此處記住,當你使用的是5.1版本以上的Lua時,請修改以下兩句為luaL_openlibs(L);
  13. luaopen_base(L);   
  14. luaopen_io(L);  
  15. constchar *buf = "print('hello, world!')";  
  16. // 記住,當你使用的是5.1版本以上的Lua時請使用luaL_dostring(L,buf);
  17. lua_dostring(buf);  
  18. lua_close(L);  
  19. return 0;  
  20. }  



程式輸出:hello, world!


有時你需要執行一段字串,有時你可能需要執行一個檔案,當你需要執行一個檔案時,你可以這麼做:
lua_dofile(L, "test.lua");


看,非常簡單吧。


取得資訊

下面讓我們來看看如何從指令碼中取得我們所需要的資訊。



首先,讓我來簡單的解釋一下Lua直譯器的工作機制,Lua直譯器自身維護一個執行時棧,通過這個執行時棧,Lua直譯器向主機程式傳遞引數,所以我們可以這樣來得到一個指令碼變數的值:

 print?
  1. <span style="font-family:'Microsoft YaHei';font-size:16px;">lua_pushstring(L, "var"); //將變數的名字放入棧
  2. lua_gettatbl(L, LUA_GLOBALSINDEX);變數的值現在棧頂</span>  

假設你在指令碼中有一個變數 var = 100

你可以這樣來得到這個變數值:

 print?
  1. int var = lua_tonumber(L, -1);  

怎麼樣,是不是很簡單?


Lua定義了一個巨集讓你簡單的取得一個變數的值:

 print?
  1. lua_getglobal(L, name)  

我們可以這樣來取得一個變數的值:

 print?
  1. lua_getglobal(L, "var"); //變數的值現在棧頂
  2. int var = lua_tonumber(L, -1);  
 print?

完整的測試程式碼如下:

 print?
  1. #include "lua.h"
  2. #inculde "lauxlib.h"
  3. #include "lualib.h"
  4. int main(int argc, char *argv[])  
  5. {  
  6. lua_State *L = lua_open();  
  7. // 此處記住,當你使用的是5.1版本以上的Lua時,請修改以下兩句為luaL_openlibs(L);
  8. luaopen_base(L);  
  9. luaopen_io(L);  
  10. constchar *buf = "var = 100";  
  11. lua_dostring(L, buf);  
  12. lua_getglobal(L, "var");  
  13. int var = lua_tonumber(L, -1);  
  14. assert(var == 100);  
  15. lua_close(L);  
  16. return 0;  
  17. }   

呼叫函式

假設你在指令碼中定義了一個函式:

 print?
  1. function main(number)  
  2. number = number + 1  
  3. return number  
  4. end  




在你的遊戲程式碼中,你希望在某個時刻呼叫這個函式取得它的返回值。


在Lua中,函式等同於變數,所以你可以這樣來取得這個函式:

 print?
  1. lua_getglobal(L, "main");//函式現在棧頂



現在,我們可以呼叫這個函式,並傳遞給它正確的引數:

 print?
  1. <span style="font-family:'Microsoft YaHei';">lua_pushnumber(L, 100); //將引數壓棧
  2. lua_pcall(L, 1, 1, 0); //呼叫函式,有一個引數,一個返回值
  3. //返回值現在棧頂
  4. int result = lua_tonumber(L, -1);</span>  


result 就是函式的返回值


完整的測試程式碼如下:

 print?
  1. #include "lua.h"
  2. #include "lauxlib.h"
  3. #include "lualib.h"
  4. int main(int argc, char *argv[])  
  5. {  
  6. lua_State *L = lua_open();  
  7. // 此處記住,當你使用的是5.1版本以上的Lua時,請修改以下這句為luaL_openlibs(L);
  8. luaopen_base(L);  
  9. constchar *buf = "function main(number) number = number + 1 return number end";  
  10. lua_dostring(buf);  
  11. lua_getglobal(L, "main");  
  12. lua_pushnumber(L, 100);  
  13. lua_pcall(L, 1, 1, 0);  
  14. int result = lua_tonumber(L, -1);  
  15. assert(result == 101);  
  16. lua_close(L);  
  17. return 0;  
  18. }  

指令碼呼叫程式



Lua本身定位在一種輕量級的,靈活的,可擴充的指令碼語言,這意味著你可以自由的擴充Lua,為你自己的遊戲量身定做一個指令碼語言。


你可以在主機程式中向指令碼提供你自定的api,供指令碼呼叫。


Lua定義了一種型別:lua_CFunction,這是一個函式指標,它的原型是:
typedef int (*lua_CFunction) (lua_State *L);


這意味著只有這種型別的函式才能向Lua註冊。


首先,我們定義一個函式

 print?
  1. int foo(lua_State *L)  
  2. {  
  3. //首先取出指令碼執行這個函式時壓入棧的引數
  4. //假設這個函式提供一個引數,有兩個返回值
  5. //get the first parameter
  6. constchar *par = lua_tostring(L, -1);  
  7. printf("%s/n", par);  
  8. //push the first result
  9. lua_pushnumber(L, 100);  
  10. //push the second result
  11. lua_pushnumber(L, 200);  
  12. //return 2 result
  13. return 2;  
  14. }  
  15. 我們可以在指令碼中這樣呼叫這個函式  
  16. r1, r2 = foo("hello")  
  17. print(r1..r2)  

完整的測試程式碼如下:

 print?
  1. extern"C"
  2. {  
  3. #include "lua.h"
  4. #include "lauxlib.h"
  5. #include "lualib.h"
  6. }  
  7. int foo(lua_State *L)  
  8. {  
  9. //首先取出指令碼執行這個函式時壓入棧的引數
  10. //假設這個函式提供一個引數,有兩個返回值
  11. //get the first parameter
  12. constchar *par = lua_tostring(L, -1);  
  13. printf("%s/n", par);  
  14. //push the first result
  15. lua_pushnumber(L, 100);  
  16. //push the second result
  17. 相關推薦

    遊戲使用LUA指令碼語言簡介

    我們知道指令碼語言是解除硬編碼,防止重編譯的利器,可以這樣說,任何大型遊戲都有自己的腳本系統。 想要做出一款精品遊戲,指令碼語言也是我們需要掌握和運用的。 較流行的指令碼語言有Pyt

    Java使用Lua指令碼語言

    Lua是一個實用的指令碼語言,相對於Python來說,比較小巧,但它功能並不遜色,特別是在遊戲開發中非常實用(WoW採用的就是Lua作為指令碼的)。Lua在C\C++的實現我就不多說了,網上隨便一搜,到處都是這方面的介紹,我想說的是如何在Java下使用Lua以提高程式設計

    指令碼語言簡介

    Lua 教程 Lua 是一種輕量小巧的指令碼語言,用標準C語言編寫並以原始碼形式開放, 其設計目的是為了嵌入應用程式中,從而為應用程式提供靈活的擴充套件和定製功能。 Lua 是巴西里約熱內盧天主教大學(Pontifical Catholic University of Rio de J

    NodeMcu開發(二)--lua指令碼語言快速入門

    NodeMcu是已lua為指令碼語言開發的, 是不是聽到又要學語言了, 就抓狂了???? 不是的, 其實我感覺只要學好了一門語言, 其他語言就是類似的, 觸類旁通, 經過一個小時的學習後, 發現lua挺像python的, 少說廢話, 來點實際的 lua語言詳細教程參考網站: 菜鳥教程 網址:ht

    遊戲PVP和PVE簡介

                在WOW中就是指不同陣營或者同陣營之間玩家對打(PK),比如野外、戰場、、插旗、競技場等都是PVP。同時,WOW有專門為PVP準備的帶有韌性的裝備,和PVE適合RAID副本的裝備不同。而PVP伺服器則是指不同陣營間的玩家(部落跟聯盟)在野外可以互

    esp8266學習筆記②:LUA指令碼語言的學習

    一、LUA語言 Lua 是一種輕量小巧的指令碼語言,用標準C語言編寫並以原始碼形式開放, 其設計目的是為了嵌入應用程式中,從而為應用程式提供靈活的擴充套件和定製功能。 二、Lua 特性 1.輕量級: 它用標準C語言編寫並以原始碼形式開放,編譯後僅僅一百餘K,可以很方便的嵌入別

    Javascript指令碼語言簡介、查詢元素節點、檢視是否存在子節點、根節點

    Javascript指令碼語言簡介、查詢元素節點、檢視是否存在子節點、根節點 1、Js中的的dom的元素節點和文字節點 DOM是Document Object Model文件物件模型的縮寫。根據W3C DOM規範,DOM是一種與瀏覽器,平臺,語言無關的介面,使得你可以訪問頁面其他的標準組件       

    Modelsim.do指令碼語言基本介紹

    轉載自:http://www.cnblogs.com/LJWJL/archive/2013/01/14/simulation.html 網上的關於DO檔案的編寫好像資料不多,比較雜,所以本人總結一下常用的簡單語法,方便大家檢視。其實本人也剛接觸DO檔案沒多久,有紕漏很正

    linux下搭建lua指令碼語言的程式設計環境詳解

    歡迎掃碼加入Java高知群交流 1、首先了解lua的一些知識 lua是一個小巧的指令碼語言。是巴西里約熱內盧天主教大學(Pontifical Catholic University of Rio de Janeiro)裡的一個研究小組,由Roberto Ierusalim

    【微控制器筆記】NodeMcu入坑—LUA指令碼語言PWM調光

    先上程式碼--pwm.lua pin = 4 dutyMAX = 1023 dutyMIN = 0 flag = 0 pwm.setup(pin,100,dutyMAX) pwm.start(pin) function changeDuty() local duty

    有關Lua指令碼語言應用

    在金融行業一"呆"又是兩年,有時候的確很迷惑,學的東西在專案中用不上.很容易就忘記了.現在工作中用到的沒有所謂的SSH.沒有什麼新技能.用的最基本的靜態頁面,基本的servlet, 用不上IE之外的瀏覽器,想學一切都看平時自己的愛好.不想學就是加班再加班中度過,現在想想加班

    Lua指令碼語言快速入門手冊

    學了兩天Lua語言,感嘆其短小精悍,上手極快,語法還很舒服,不錯!整理下學習過程中經常用到的基礎知識,共勉! Lua用法簡述 Lua語言是在1993年由巴西一個大學研究小組發明,其設計目標是作為嵌入式程式移植到其他應用程式,它是由C語言實現的,雖然簡單小巧但是功能強大,所以許多應用都選用它作為指令碼語言,

    深入LUA指令碼語言,讓你徹底明白除錯原理

    這是道哥的第008篇原創 ![](http://ql815naye.hn-bkt.clouddn.com/wechat-qrcode.png) ## 一、前言 上篇文章我們聊了[gdb的底層除錯機制](https://mp.weixin.qq.com/s/oY2pF5ilk8UCq09022Tt6w

    在Unity使用Lua指令碼語言層和遊戲邏輯粘合層處理

    前言:為什麼要用Lua 首先要說,所有程式語言裡面,我最喜歡的還是C#,VisualStudio+C#,只能說太舒服了。所以說,為什麼非要在Unity裡面用Lua呢?可能主要是閒的蛋疼。。。。。另外還有一些次要原因: 方便做功能的熱更新;Lua語言的深度和廣度都不大,易學

    在redis使用lua指令碼讓你的靈活性提高5個逼格

    原文連結 在redis的官網上洋洋灑灑的大概提供了200多個命令,貌似看起來很多,但是這些都是別人預先給你定義好的,但你卻不能按照自己的意圖進行定製, 所以是不是感覺自己還是有一種被束縛的感覺,有這個感覺就對了。。。   一:Lua指令碼       說來也巧

    指令碼語言】RINGO JS簡介

    Ringo 101 為了讓使用者更高效地編寫和執行 Javascript 指令碼,我們在 Total Control 指令碼環境中集成了 RingoJS 框架,使用者可在指令碼中直接引入並使用 RingoJS 提供的大量豐富的庫。 例如:如果您想在指令碼中使用 RingoJS 模組 fs 中的方

    Linux 下 expect 指令碼語言互動處理常用命令

    Linux 下 expect 指令碼語言中互動處理常用命令 Linux 下 expect 指令碼語言中互動處理常用命令 1. #!/usr/bin/expect 告訴作業系統腳本里的程式碼使用那一個 shell 來執行。這裡的 expect 其實和 Linux 下的 bash、win

    Vivado HLS的TCL命令介面(指令碼語言)(高階綜合)(FPGA)

    前言:這個例項源於賽靈思的官方HLS手冊——(UG871),展示瞭如何基於已存在的Vivado HLS工程來建立一個TCL指令碼命令和如何應用TCL介面(已存在的工程為"lab1",使用TCL新建立的工程為“lab2”),軟體版本2013.4和2017.4均親測有效。 一、步驟1:

    Java原生解析JavaScript指令碼語言

    前言 由於一些需求,現在需要在Java中解析字串,做一些簡單的算數運算和邏輯運算,那麼最先想的是模板引擎這個東西,但是Java中的模板引擎是針對View層的,也就是JSP的,在Service層中使用不是太方便,因此選用了原生的JavaScript指令碼解析引擎。實際上Jav

    在redis使用Lua指令碼如何判斷變數是否為空

    --在lua中,除了nil和false,其他的值都為真,包括0,可以通過nil為false這一點來判斷是否為空 local temp = redis.call('get',key) if temp then    print('temp為非空')  else