之前我們介紹了wow插件的構成和使用,從這篇開始我們将要學習自己DIY插件,我們從一個簡單的例子開始學習。你一定有很多顧慮,如果你想問在學習之前我們需不需要有一些程式設計方面的基礎,答案是:不需要。隻要你是遊戲玩家,你要你玩過遊戲,這些看起來so easy! 魔獸世界都肝這麼多年了,你還覺得有什麼事比肝魔獸更難的嗎?跟着我的教程,一起創造屬于我們自己的“艾澤拉斯”。
當然你如果并不清楚插件是什麼以及如何運作,你隻需要看下我之前的文章,關注微信公衆号“艾澤拉斯日常”,簡單的了解之後,我們就可以切入正題了。
我們需要的工具
- 魔獸世界用戶端
-
可以編寫代碼的文本工具
文本工具有很多,如果你不想費事去找,那麼用系統自帶的記事本工具也完全可以,我這裡推薦幾個比較好用的軟體,可以去自行百度。
-
Sublime text 3
-
如果你會用Atom
還可以:Markdown
-
作業部落
-
Evernote
-
插件的組織方式
關于這個内容我們在先前的文章中也有提到過,如下:
我們所要編寫的所有插件都會儲存在wow遊戲用戶端
Interface/AddOns
目錄下,如圖:
接下來我們需要開始在
AddOns
下建立我們第一個插件目錄
01_HelloAzeroth
,
├─README.md
├─01_HelloAzeroth
│ ├─01_HelloAzeroth.toc
│ ├─HelloAzeroth.lua
│ ├─HelloAzeroth.xml
│ └─README.md
└─...
如上結構,我們在Addons下建立檔案夾
01_HelloAzeroth
,在檔案夾下用前面提到的文本工具建立同名的
01_HelloAzeroth.toc
TOC格式檔案,注意這裡的
.toc
格式檔案必須與檔案夾名稱相同,且字尾必須是
.toc
,否則魔獸用戶端内不會對插件進行識别。
進行完這一步我們在
.toc
檔案裡填寫如下内容:
# 這是聽風編寫的第一個插件
# 注意我前面是一個“#”開頭的,這個表示注釋,可以無視
# 下面的兩個“##”開頭的,是插件相關,在下面會做具體講解
## Interface: 20400
## Title: 01-你好艾澤拉斯
## Notes: I am just trying to say hello to my azeroth world.
## Notes-zhCN: 我隻是在向我的艾澤拉斯世界問好。
## Author: 聽風
## DefaultState: Enabled
## Version: 1.0.0
HelloAzeroth.lua
HelloAzeroth.xml
先不着急解釋,編寫完TOC檔案,我們打開遊戲用戶端檢視,我們編寫的插件已經出現在遊戲裡了。
TOC檔案的解釋
在
01_HelloAzeroth.toc
檔案的開頭用一個“#”寫的内容表示注釋,是友善我們自己作記錄用的,它們不會對插件産生任何影響。我們完全可以寫一些文字來讓我們清楚自己編寫插件的思路等等。
下面的第二部分用兩個“#”開頭的内容是插件相關資訊,我們先前也有過解釋,這裡我們隻解釋本插件中提到的。
适用的魔獸版本号
## Interface: 20400
插件名稱,對應遊戲内顯示
## Title: 01-你好艾澤拉斯
遊戲内滑鼠移到插件上所顯示的内容,以下不同語言對應遊戲目前顯示語言
## Notes: I am just trying to say hello to my azeroth world.
## Notes-zhCN: 我隻是在向我的艾澤拉斯世界問好。
插件作者
## Author: 聽風
DefaultState: 預設狀态 disabled 不可用 Enabled 可用
## DefaultState: Enabled
插件的版本,這個版本與遊戲版本号無關
## Version: 1.0.0
最後第三部分是遊戲加載時所要加載的檔案,這些檔案内會有插件的界面以及事件腳本檔案代碼,接下來我們要開始正式編寫插件了。
HelloAzeroth.lua
HelloAzeroth.xml
這裡所列出的檔案應該與
.toc
檔案處于同一路徑下,當然如果檔案位于
01_HelloAzeroth
目錄下的子目錄
Hello
,則應該寫成相對路徑,比如這樣:
Hello/HelloAzeroth.lua
Hello/HelloAzeroth.xml
HelloAzeroth
我們的插件需要一個界面,同時需要處理一些遊戲中的事件,在我們自己的插件目錄下建立兩個檔案,
HelloAzeroth.lua
和
HelloAzeroth.xml
,前者用來處理事件,後者用來描述界面。
做一個簡單的界面
先來說界面,我們用
.xml
描述插件的界面,在本篇中我們簡單的加載了一個框,在上面我們顯示一些遊戲内的資訊。
我們完全可以用
.xml
來完成界面編輯,下面我們将編輯界面,完整的代碼在這裡,https://github.com/usiege/Addons/blob/master/01_HelloAzeroth/HelloAzeroth.xml 别急,我們将逐行進行解釋。
這個界面的代碼所展示的内容如圖:
不懂XML語言也完全沒有關系,我們隻要知道所有的标簽都是成對出現的就可以了,如果對上面的内容進行簡化,則上面的代碼的結構将會是下面這個樣子。
<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..\FrameXML\UI.xsd">
<Frame name="HelloWorldTestFrame" parent="UIParent" enableMouse="true"
movable="true" frameStrata="LOW">
<Size x="300" y="150" />
<TitleRegion setAllPoints="true" />
<Anchors>
<Anchor point="CENTER" />
<Anchors>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border">
<Backdrop>
<Layers>
<Layers>
<Scripts>
</Scripts>
</Frame>
</Ui>
-
wow插件以<Ui />
包裹,下面的格式是固定的,在這個标簽對裡的内容将會對界面進行設定:<Ui> </Ui>
<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..\FrameXML\UI.xsd">
</Ui>
這裡要說明一下xml标簽的兩種形式,一種是簡化的如,另外一種是成對的如
<Ui xmlns="http://www.blizzard.com/wow/ui" />
,兩種形式表示的内容完全一樣。我這裡文章為簡化說明内容全部用第一種形式。
<Ui xmlns="http://www.blizzard.com/wow/ui"> </Ui>
-
<Frame />
标簽表示的是插件中的界面元素,标簽中的屬性分别表示:Frame
-
: Frame對象的名稱;(這裡對象的意思是程式設計語言中的概念,如果你不是很懂,就把它看做是一個具體的界面元素就可以了)name
-
: 這個涉及到程式設計語言繼承的概念,這裡的寫法是固定的,parent
是魔獸世界界面的API,一般情況下我們這裡都用UIParent
;(與上一個UIParent
屬性不同的是,name
我們可以自己指定名稱,這裡我們隻能用name
或者我們已知的,初學者一般知道這個地方是不可以随意替換的就可以了)UIParent
-
: 表示我們的界面元素是否可以用滑鼠操作;enableMouse
-
: 表示我們的界面元素是否可以移動;movable
-
: 表示我們界面元素所在的層級,簡單了解就是我們的界面元素有上下之分,上面的會覆寫下面的界面,這個frameStrata
,LOW
之分就能告訴我們哪個界面要在上面顯示,關于這個屬性以後我們遇到界面覆寫的時候會很好了解。HIGH
-
-
這個标簽修飾了界面元素的大小;<Size />
-
<TitleRegion />
-
: 當setAllPoints
的Frame
為movable
時,這個屬性表示是否界面上的所有點都可以使界面移動,即點選界面上的任何點移動界面都是有效的;true
-
-
錨點是一個遊戲設計的概念,具體可自行百度下,這裡不做具體解釋,因為我們現在還涉及不到這個;<Anchor />
-
我們在<Layer />
裡顯示了幾項内容,都是通過這個标簽排列的:Frame
-
<FontString />
上面的<FontString name="$parentTextTitle" inherits="GameFontNormal" text="Hello Azeroth!">
裡name
表示的是$parent
父标簽的名稱,即<Layer />
的名稱<Frame />
,是以這裡HelloWorldTestFrame
其實就是name
;HelloWorldTestFrameTextTitle
表示字型繼承自的對象;inherits
表示所要顯示的内容;text
-
插件的一些事件
以上所有的界面顯示已經全部解釋完,在上面的界面代碼裡,最後還有一個
<Script />
标簽,這個标簽就是用來描述腳本的一些事件的,我們接着進行剖析;
-
先要說一個很重要的内容
我們在前面說到的
檔案中有一段插件加載檔案的代碼:.toc
這裡要注意的是,這兩行代碼是有順序的,也就是說遊戲在加載插件時會按順序對檔案進行加載,由于我們的界面HelloAzeroth.lua HelloAzeroth.xml
檔案會用到.xml
中的内容,是以.lua
檔案要先于.lua
檔案,否則進入遊戲會出現插件加載錯誤的問題,我們看一下.xml
标簽裡的内容就了解了;<Script />
-
<Script />
這段代碼裡對應了插件在遊戲中的三個事件:<Scripts> <OnLoad> HelloWorldLoad(); </OnLoad> <OnEvent> HelloWorldEvent(); </OnEvent> <Scripts>
-
:插件在加載時;ww<OnLoad />
-
<OnEvent />
: 插件在一些互動事件發生時,比如滑鼠點選等;
而這些标簽下的代碼來源于
檔案中,是以前面我們說到.lua
一定要先于.lua
;.xml
-
事件是如何發生的
終于來到我們本篇中最難了解的部分,這可能需要你有一定的程式設計基礎,但是如果不懂那麼也可以從英語單詞中猜到一些内容,當然如果你對程式設計稍微有些興趣可以簡單學習一下 Lua 這個語言。但即使你不想學任何一門程式設計語言,看了我這一篇你也能寫出一個插件,相信我,這很簡單。
下面這個連結是我們所有的代碼,很簡短,同樣我們逐行進行解剖,https://github.com/usiege/Addons/blob/master/01_HelloAzeroth/HelloAzeroth.lua
- HelloWorldLoad()
function HelloWorldLoad(frame)
-- 還記得.xml檔案裡Frame标簽裡的界面元素嗎
-- 這裡我們擷取我們的界面元素,并把它設定成了隐藏
frame:Hide()
-- 正面這行我們在預設的聊天視窗列印一行文字,當你進入遊戲後
-- 在聊天視窗會看到一串文字顯示,說明我們的插件加載成功
-- 本段我們會給出展示
DEFAULT_CHAT_FRAME:AddMessage("HelloAzeroth is Loaded!");
-- 下面這句我們為界面元素注冊了一個CHAT_MSG_SAY事件
-- 這個事件是當你周圍有人說話時發生的
-- 這個事件對應<OnEvent />标簽下的内容,也就是HelloWorldEvent函數
frame:RegisterEvent("CHAT_MSG_SAY");
end
當界面加載時我們運作上面這個函數(函數的概念自己去百度一下吧,不懂的話就無視,我們隻要知道插件在做事情就可以了);
- HelloWorldEvent()
function HelloWorldEvent(frame, event, arg1, arg2, ...)
if(event == "CHAT_MSG_SAY") then
DEFAULT_CHAT_FRAME:AddMessage(arg2.." said "..arg1);
if arg1 == "hide" then
frame:Hide()
elseif arg1 == "show" then
frame:Show()
end
end
end
上面
RegisterEvent
注冊的函數會通過在
<OnEvent />
标簽裡的函數運作,也就上所有注冊的事件都會運作上面這段代碼,代碼中的三個參數:
enent
是一個字元串類型,對應注冊的事件,這些事件是wow定義好了的,主要對應遊戲裡的一些事件,像我們這裡是對應一個聊天的事件,任何你角色周圍的人說話都會觸發這個事件,也就是會運作上面這段代碼;
arg1
是說話的内容,
arg2
是說話人的角色名;
我們進入遊戲界面預設是不顯示我們自己寫的歡迎界面的,是以我們就在我們事件裡加入了一段代碼,當我們說話是
show
的時候顯示,
當說話是
hide
的時候隐藏;
好了,我們的歡迎插件就做好了,儲存代碼檔案,在遊戲裡使用
/reload
指令看一下效果吧!!!
有感興趣的可以下載下傳我的代碼,全部代碼在這裡https://github.com/usiege/Addons/tree/master/01_HelloAzeroth