解析LUA快速入手指南
LUA快速入手指南是本文要介紹的內(nèi)容,主要是來學(xué)習(xí)LUA在游戲中使用方法,具體內(nèi)容來看本文詳解。TOC工程描述文件后綴名為toc的文件就是工程文件,包含工程的基本信息。主要包含以下內(nèi)容:
切換行號(hào)顯示
- ## Interface: 適用的魔獸版本號(hào)
- ## Title: 顯示的標(biāo)題(默認(rèn)語言)
- ## Notes: 顯示的說明(默認(rèn)語言)
- ## Title-zhCN: 特定語言的標(biāo)題(簡體中文)
- ## Notes-zhCN: 特定語言的說明(簡體中文)
- ## Author: 作者(不顯示)
- ## Version: 版本
- ## eMail: 如題
- ## UIType: 插件類型
- ## Dependencies: 依賴的插件
- ## RequiredDeps: 必須依賴的其他插件
- ## OptionalDeps: 可選倚賴
- ## SavedVariables: 統(tǒng)一存放的變量
- ## SavedVariablesPerCharacter: 按角色存放的變量
- ## LoadOnDemand: 1 (調(diào)用時(shí)加載)
- ## LoadWith: 當(dāng)指定插件加載時(shí)才加載,前提是調(diào)用時(shí)加載
- ## DefaultState: disabled 默認(rèn)狀態(tài)
- ## Secure: 安全(功能未知)
- # 注釋1 dklasjfkasdj
- Script.lua -- 腳本文件
- % 注釋2 dskajfklasdjfklsdaj
- Layout.xml -- 布局文件
‘#’ 和 ‘%’ 為行注釋符號(hào)。
而以##開頭的注釋行可就不光是好看的了,這些都是插件的工程描述標(biāo)記,要是不注意插件根本就不會(huì)載入。
示例中彩色的標(biāo)記表示標(biāo)準(zhǔn)標(biāo)記,每個(gè)標(biāo)準(zhǔn)標(biāo)記都有特定功能。其它eMail, Author等為擴(kuò)展標(biāo)記,只有注釋功能。
工程標(biāo)記之后的部分為包含文件列表,腳本文件和布局文件,數(shù)量隨意,但每種至少要有一個(gè):一個(gè)lua或一個(gè)xml。
包含文件列表中的順序?qū)?yīng)著載入順序,非常要緊!
如果要寫中文,一定要將toc文件保存為UTF-8格式,否則無法正確識(shí)別。方法很簡單:用記事本打開,另存為,選擇編碼就行;文件格式要選所有文件,否則會(huì)存成txt文件。
建議你多下幾個(gè)插件,打開看看,參考一下。
XML —— 屏幕布局描述文件在魔獸插件中使用XML來描述UI的屏幕布局。
注釋符號(hào):<!-- 注釋內(nèi)容 --> 。
如果要寫中文注釋,必須在XML文件開頭添加一行:
- <?xml version="1.0" encoding="UTF-8"?>
XML文件主要內(nèi)容一個(gè)XML文件往往包含以下內(nèi)容:
- <!-- Ui標(biāo)簽是包含所有其它標(biāo)簽的根標(biāo)簽 -->
- <Ui xmlns="http://www.blizzard.com/wow/ui/"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.blizzard.com/wow/ui/
- C:\Projects\WoW\Bin\Interface\FrameXML\UI.xsd">
- <Script file="localization.lua"/> <!-- 在此載入用于漢化的lua文件 -->
- <Frame name="zBar" parent="UIParent"> <!-- 一個(gè)Frame框架 -->
- <Scripts> <!-- 腳本部分,用于處理事件 -->
- <OnLoad>
- zBar_OnLoad();
- </OnLoad>
- <OnEvent>
- zBar_OnEvent(event);
- </OnEvent>
- </Scripts>
- </Frame>
- </Ui>
Ui標(biāo)簽<Ui>是最上級(jí)標(biāo)簽。其中的schema用來語法檢查,如果你的XML編輯器支持還可以用來代碼提示。否則對(duì)我們來說用處不大??梢院喕癁椋?/p>
- <Ui xmlns="http://www.blizzard.com/wow/ui/"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
</Ui>或者更加簡化,不太規(guī)范但是可用:<Ui>布局內(nèi)容</Ui>
Script標(biāo)簽在Ui標(biāo)簽中最先包含的往往是<Script file="lua 文件名"/>表示在此處載入某lua文件。
注意這里也有順序哦,如果發(fā)現(xiàn)變量、函數(shù)不存在,檢查一下看是不是順序問題。
這樣一來我們有了兩種方法載入lua文件。在xml中載入lua實(shí)際上不是非如此不可的,有時(shí)候沒必要用xml的就直接在toc中放個(gè)lua,把xml省掉。這樣做你必須在lua中有個(gè)入口,也就是有個(gè)裸語句(不在任何function中的)進(jìn)行事件注冊(cè)或者調(diào)用函數(shù)。
Frame標(biāo)簽XML中最主要的一個(gè)標(biāo)簽是<Frame></Frame>。所謂Frame意指框架,就是用來包含其他東西的。
UIParent是最上層的框架,所有的UI都包含在其中。與之并列的是一個(gè)特殊框架World Frame,包括FPS、截圖。
其它控件一般都是Frame的子類,都包含類似的屬性和子標(biāo)簽:背景、貼圖、邊框、事件處理。如:<button> <slider> <statusbar> 等等。
Frame標(biāo)簽就像一個(gè)透明的玻璃容器。你可以僅用它來裝載其它部件,當(dāng)然也可以給他添加貼圖顯示出來。
記得游戲中按下“Alt+z”的效果了么,被隱藏的就是UIParent。容器被隱藏了,里面裝的東西也就透明了。
子標(biāo)簽和屬性
- <Frame name="名稱,唯一" inherits="myFather繼承" toplevel="true等級(jí)" parent="UIParent父標(biāo)簽" id="編號(hào)"
- movable="true可移動(dòng)" enableMouse="true允許鼠標(biāo)事件" frameStrata="HIGH層級(jí)" hidden="false隱藏" >
- <Size> <!--大小 -->
- <AbsDimension x="" y=""/> <!--絕對(duì)尺寸 -->
- </Size>
- <!-- 簡化寫法 -->
- <Size x="" y=""/>
- <Anchors> <!--錨點(diǎn),用來標(biāo)記相對(duì)位置 -->
- <Anchor Point="本控件的參考點(diǎn)" relativeTo="參考控件" relativePoint="參考控件的參考點(diǎn)">
- <Offset> <!-- 偏移值 -->
- <AbsDimension x="" y=""/>
- </Offset>
- <!-- 簡化寫法 -->
- <Offset x="" y="" />
- </Anchor>
- </Anchors>
- <!-- 背景和邊框 -->
- <Backdrop name="$parentBackdrop" bgFile="背景貼圖" edgeFile="邊框貼圖" tile="不知道">
- <EdgeSize>
- <AbsValue val="18"/> <!-- 邊框縮放大小 -->
- </EdgeSize>
- <TileSize>
- <AbsValue val="16"/>
- </TileSize>
- <BackgroundInsets>
- <AbsInset left="5" right="5" top="5" bottom="5"/> <!-- 背景四周留白 -->
- </BackgroundInsets>
- </Backdrop>
- <Layers> <!-- 分層,主要放置貼圖材質(zhì)和字符 -->
- <Layer level="BACKGROUND"> <!-- 背景層 -->
- <Texture name="$parentRed" file="貼圖" hidden="true"/>
- </Layer>
- <Layer level="ARTWORK"> <!-- 藝術(shù)層 -->
- <FontString name="$parent名字" inherits="Font" justifyH="CENTER"/>
- <Layer level="OVERLAY"> <!-- 覆蓋層 -->
- <Texture name="$parentShine" file="貼圖" alphaMode="ADD透明模式" hidden="true">
- <Anchors>
- <Anchor point="CENTER"/>
- </Anchors>
- </Texture>
- </Layer>
- </Layers>
- <Frames>
- <!-- 嵌入其他框架 -->
- </Frames>
- <Scripts>
- <OnLoad>處理載入事件</OnLoad>
- <OnEvent>處理用RegisterEvent注冊(cè)過的事件</OnEvent>
- <OnUpdate>更新事件</OnUpdate>
- <OnShow>顯示事件</OnShow>
- <OnHide>隱藏事件</OnHide>
- <OnClick>單擊事件</OnClick>
- <OnDoubleClick>雙擊事件</OnDoubleClick>
- <OnEnter>鼠標(biāo)進(jìn)入</OnEnter>
- <OnLeave>鼠標(biāo)移出</OnLeave>
- <OnDragStart>拖放開始</OnDragStart>
- <OnReceiveDrag>接受拖放</OnReceiveDrag>
- <OnValueChanged>值改變(用于Slider滑塊)</OnValueChanged>
- </Scripts>
- </Frame>
如圖:
UI對(duì)象的繼承關(guān)系UIObject
始祖,所有其他UI對(duì)象都由它繼承。
LayoutFrame
布局框架,繼承UIObject,主要有一些布局函數(shù),(這是一個(gè)虛類不可創(chuàng)建實(shí)例)。
LayoutFrame的重要函數(shù):GetParent() SetParent() GetAlpha() SetAlpha() SetWidth() SetHeight()
IsShown() 和 IsVisible() 的區(qū)別,如圖:
Frame
框架,繼承Layout Frame,最重要的UI對(duì)象,屏幕上可見的UI對(duì)象都是它的子類,一般用來在上面放置其他控件。Frame的子類;描述
- Button;按鈕。
- EditBox;可編輯文本框。
- GameTooltip;鼠標(biāo)提示
- ColorSelect;顏色選擇器
- MessageFrame;信息框架
- Minimap;迷你地圖,小地圖、戰(zhàn)場(chǎng)地圖等
- Model;模型,用于顯示3D動(dòng)畫。人物模型,冷卻都是Model
- MovieFrame;影像框架,放電影的。。。不知道怎么用
- ScrollFrame;可滾動(dòng)框架
- ScrollingMessageFrame;滾動(dòng)信息框架,例如聊天窗口、戰(zhàn)斗信息窗口
- SimpleHTML;簡單超文本標(biāo)記語言,應(yīng)該是類似網(wǎng)頁的可定義字體大小顏色式樣、帶圖片的文本
- Slider;滑快,像系統(tǒng)設(shè)置中的UI縮放那個(gè)滑快
- StatusBar;進(jìn)度條,像是施法條,血條等等
LUA 腳本代碼文件 更深入的學(xué)習(xí)請(qǐng)閱讀本站的其它文章:ProgrammingInLua, 魔獸Api索引
如果你有一門以上的語言基礎(chǔ),那么學(xué)習(xí)lua語言不是什么難事。
lua是一種靈活的語言,關(guān)于他的來源我并不知道多少,只談一下自己的感受?;菊Z法和Basic類似,或者說更像是Asp的腳本語言吧。但同時(shí)他又借鑒了Java的長處,更加的智能化、靈活。寫法多樣又方便不同習(xí)慣的人上手。
lua語法很簡單,相關(guān)資料也很多,我只列出需要注意的部分。
基本語法摘要行注釋符號(hào):“--”
段注釋符號(hào):“--” “”;實(shí)際上還是行注釋,而“” “”包圍的部分編譯器會(huì)認(rèn)為是一行。
行結(jié)束符號(hào):用“;”或者不寫都行,看你的習(xí)慣了,只要沒有歧義就好
NULL空值:在這里是nil
沒有指針:和Java一樣,沒指針的意思就是所有變量都是引用。要注意不是拷貝的副本,改變引用變量原始變量會(huì)同時(shí)改變。
變量作用域:默認(rèn)是global(全局作用域),加上local前綴就是局部的了(文件內(nèi)部作用域)。
函數(shù)作用域:和變量一樣默認(rèn)是全局作用域。實(shí)際上函數(shù)也是變量。
數(shù)組,集合:只有一種,類似于。。。我也不知道類似什么。寫法也很隨意,舉例:
- Config = {
- attribute1 = "apple",
- attribute2 = false,
- ["attribute3"] = "animal",
- [1] = "Button1",
- ["2"] = "Cool",
- }
關(guān)于數(shù)組的就看上面的“Lua腳本語言入門”,講的很清楚。
關(guān)于布爾變量:要注意的是只有nil和false表示false,其他一律為true(包括0),而false是要占用引用內(nèi)存的,建議把false一律換成nil。
關(guān)于布爾運(yùn)算:lua里的布爾運(yùn)算是很有趣的,也相當(dāng)合理。注意運(yùn)算的值并不是布爾值,而是其中一個(gè)操作數(shù)的值。
- x = a and b; -- 與運(yùn)算,a為false則x等于a,a為true則x=b。
- x = a or b; -- 或運(yùn)算,a為true則x等于a,a為false則x = b。
是不是有點(diǎn)暈?其實(shí)很合理。如果你一時(shí)繞不清楚,就只要記住結(jié)果好了。
布爾運(yùn)算的妙用:我堅(jiān)定地認(rèn)為lua中的布爾運(yùn)算實(shí)際上不是布爾運(yùn)算,而是簡化了的條件語句。比如:
- x = a and b; --相當(dāng)于:
- if (not a) then
- x = a;
- else
- x = b;
- end
- x = a or b; -- 相當(dāng)于:
- if (a) then
- x = a;
- else
- x = b;
- end
還有一種簡化,常用于變量的初始化:
- xx = x or a; -- 相當(dāng)于:
- if ( not x ) then
- x = a;
- end
對(duì)象在lua里,框架和控件都作為對(duì)象存在。 要引用在XML中定義的框架或控件,使用如下語句:
- frame = getglobal("FrameName");
對(duì)象的屬性
屬性在對(duì)象中就像集合成員一樣,屬性引用符號(hào)為:“.”,例如:frame.attribute1
對(duì)象實(shí)際上就是一個(gè)特殊集合?。?/p>
對(duì)象的屬性同樣可以用集合方式引用: frame["attribute2"]。函數(shù)調(diào)用也是一樣,見下面說明。
函數(shù)函數(shù)定義
類似Basic,例如:
- function add(a,b)
- local ret = a + b;
- return ret;
- end
覆蓋函數(shù)
函數(shù)定義實(shí)際上是把一個(gè)變量指向一段代碼。前面舉的例子含義是:把變量add指向一段函數(shù)代碼。 因此,我們可以很方便的覆蓋(Override)Blizzard的系統(tǒng)函數(shù),只要把系統(tǒng)函數(shù)變量指向自己定義的函數(shù)代碼就可以了。以覆蓋上面的add函數(shù)為例,有幾種方法:-- 1. 把原函數(shù)變量指向新的函數(shù)代碼段
- old_add = add; -- 保存原始的add指向的函數(shù)
- add = function(a,b) -- add 指向新的代碼段
- if ( old_add(a,b) == 0 ) then return nil end
- return a + b
- end
2. 直接定義一個(gè)同名函數(shù)
function add(a,b) -- 含義與第一種方法相同:改變add的值,使它指向新的代碼段
- local ret = a + b
- if ( ret == 0 ) then return nil end
- return ret
- d
對(duì)象的函數(shù)
函數(shù)在對(duì)象中有些特別,調(diào)用符號(hào)為冒號(hào):“:”,例如:frame:Show();
函數(shù)實(shí)際上是一種特殊變量
它指向一段代碼,更一般的調(diào)用符號(hào)和一般的對(duì)象屬性相同,為 “.”。 而特殊符號(hào)“:”實(shí)際上是在調(diào)用的時(shí)候多加了一個(gè)參數(shù)“self”,指代調(diào)用者本身。例如:
- Frame1:SetAlpha(0.5)
相當(dāng)于
Frame1.SetAlpha( Frame1, 0.5)函數(shù)的默認(rèn)參數(shù)
有一些函數(shù)參數(shù)比較特殊:對(duì)象事件處理函數(shù),有一些有默認(rèn)參數(shù),例如OnClick OnMouseDown OnMouseUp;默認(rèn)參數(shù) arg1
OnEvent;默認(rèn)參數(shù)event所以在定義這些函數(shù)的時(shí)候可以不寫參數(shù):function zOnClick()
- if ( arg1 == "LeftButton" ) then
- doSomething()
- end
- d
但是要注意:如果函數(shù)定義里寫了參數(shù),那么調(diào)用函數(shù)的時(shí)候一定要寫參數(shù)?。。?!否則認(rèn)為參數(shù)為nil。例如:
- <OnClick>if ( not this.lock ) then zOnClick(arg1) end</OnClick>
之所以有默認(rèn)參數(shù)存在是因?yàn)樵趧?dòng)態(tài)改變事件處理函數(shù)的時(shí)候不能寫參數(shù),例如button:SetScript("OnClick", zOnClick)默認(rèn)參數(shù)的原理
經(jīng)過多方考證,這些默認(rèn)參數(shù)均為全局變量。
實(shí)現(xiàn)默認(rèn)參數(shù)得流程為:對(duì)象觸發(fā)事件時(shí)會(huì)調(diào)用對(duì)應(yīng)函數(shù),在其中將全局變量即默認(rèn)參數(shù)賦值。
例如xml中有如下描述:
- <OnClick>zOnClick()</OnClick>
雖然不知道WoW虛擬機(jī)確切的處理方式,但我們可虛擬如下:-- 事件觸發(fā)時(shí)調(diào)用對(duì)象的事件處理函數(shù)
- Object:OnClick("LeftButton")
該處理函數(shù)定義模擬如下
- function Object:OnClick(arg1)
- zOnClick()
- end
- -- [[
由于arg1 為全局變量,對(duì)象被調(diào)用時(shí) arg1 被賦值為"LeftButton"
其后Object:OnClick()中又馬上調(diào)用了zOnClick()插件處理函數(shù),
其中并無被改變的機(jī)會(huì),因此 arg1 被成功傳遞,看起來就像是默認(rèn)參數(shù)了。
-- ]] 默認(rèn)參數(shù)還包括 this,但是 self 不是全局變量。
小結(jié):解析LUA快速入手指南的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí)能對(duì)你有所幫助!