天天看点

听风的插件-你好艾泽拉斯

之前我们介绍了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>
           
  • <Ui />

    wow插件以

    <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

    标签表示的是插件中的界面元素,标签中的属性分别表示:
    • name

      : Frame对象的名称;(这里对象的意思是编程语言中的概念,如果你不是很懂,就把它看做是一个具体的界面元素就可以了)
    • parent

      : 这个涉及到编程语言继承的概念,这里的写法是固定的,

      UIParent

      是魔兽世界界面的API,一般情况下我们这里都用

      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>
               
    这段代码里对应了插件在游戏中的三个事件:
    • <OnLoad />

      :插件在加载时;ww
    • <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