只包含基本的框架、图形、字串的界面是静态的,无法和用户进行交互,因此,必须通过添加动态行为来编写真正可用的插件。
事件及脚本
用户界面通过游戏中的事件来改变其状态,并且通过框架的脚本同用户进行交互。
框架脚本
每一种框架都可以对一些特定的行为作出反应,例如,按钮可以对点击作出反应,而文本输入框则可以对输入文字作出反应。相对应的,在实际的XML代码中,就可以用<OnClick>和<OnValueChanged>标签携带的脚本来定义框架的反应行为。
游戏事件
游戏事件是客户端向用户界面发送的信息,通常由战斗、交互行为等触发。例如,当任何关注目标(包括玩家角色的目标、焦点、队伍或团队成员)生命值发生变动时,就会触发UNIT_HEALTH事件。
为了监听事件,框架需要使用:RegisterEvent()方法注册到客户端。在注册后,每当事件被触发,客户端都将呼叫框架的<OnEvent>脚本。每个框架都可以监听一个或以上的事件,但只能有一个<OnEvent>脚本。游戏客户端会将事件名称传递给<OnEvent>脚本并由其应对不同类型的事件。
通过脚本应对事件
上述的事件脚本都放置在每个XML Frame的<Scripts>元素当中。对于每种事件,都可以定义一个脚本。
<OnEnter> / <OnLeave>
任何一个可以对鼠标事件作出反应的框架(即是说,没有将enableMouse属性字段设为false的框架)均可以对<OnEnter>及<OnLeave>事件作出反应。下面的代码,对两种事件作出反应,并且在聊天窗口输出信息。
<Size x="100" y="100" />
<Anchors>
<Anchor point="CENTER" relativePoint="CENTER"
relativeTo="UIParent" />
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentIcon"
file="Interface\Icons\Spell_Shadow_ShadowWordPain"
setAllPoints="true" />
</Layer>
</Layers>
<Scripts>
<OnEnter>
ChatFrame1:AddMessage("++ Entered frame: " .. self:getName())
</OnEnter>
<OnLeave>
ChatFrame1:AddMessage("-- Leaving frame: " .. self:getName())
</OnLeave>
</Scripts>
</Frame>
对不同事件的处理,均是通过这样的、<Scripts>中的元素来进行的。每一个<On...>元素都是一个处理器,其中是一段Lua代码,对指定的行为作出反应。每一个处理器均被传入一个self参数,即此框架本身。少数处理器可以接受一个以上的参数。
在这里,屏幕中央将显示一个100*100的暗言术痛图标。当鼠标移入或移出框架范围时,聊天窗口将相应输出提示信息。
<OnLoad>
所有框架都可以拥有一段<OnLoad>脚本,这段脚本将在框架被加载的时候自动运行。通常这里用来注册监听事件,以及进行其他的初始化行为。同样被传入self参数,即框架自身。
例如,下面的代码将框架注册到UNIT_HEALTH事件:
<OnLoad>
self:registerEvent("UNIT_HEALTH")
</OnLoad>
</Scripts>
对实际的游戏事件作出反应,必须借助<OnEvent>脚本。当事件被触发时,<OnEvent>将被传入两个以上的参数,第一个为self(框架自身),第二个为event,即事件名称。根据事件种类的不同,后面还将跟随数量不等的其他参数。
可以这样认为:如果框架在<OnLoad>时注册到UNIT_HEALTH事件,写在<OnEvent>标签内的代码就会被放到这样的代码中,并作为最后的OnEvent脚本。
if event == "UNIT_HEALTH" then
-- 运行代码
end
end
例如下面的代码:
<Scripts>
<OnLoad>
self:registerEvent("UNIT_HEALTH")
</OnLoad>
<OnEvent>
local unit = ...
ChatFrame1:AddMessage("UNIT_HEALTH: unit = " ... unit)
</OnEvent>
</Scripts>
</Frame>
UNIT_HEALTH的后续参数序列只有一个成员,即生命值受到影响的单位名称。上述代码将在每次UNIT_HEALTH事件被触发时,输出提示信息到聊天窗口。
<OnClick>
按钮和复选框可以通过<OnClick>脚本对鼠标点击作出反应。此事件传入三个参数:
self: 被点击的按钮
button: 按下的鼠标键
down: 鼠标点击的方向(按下时为true,松开为false)
魔兽世界一共可以处理5种鼠标按键,分别名为:LeftButton, RightButton, MiddleButton, Button4和Button5。默认情况下,所有按钮都被设定只监听LeftButtonUp事件(即左键松开)。需要监听其他事件,必须通过:RegisterForClicks()方法修改。
例如,在<OnLoad>脚本中添加下列语句,可以使该按钮同时监听左右键的按下和释放事件:
self:RegisterForClicks("LeftButtonUp", "LeftButtonDown",
"RightButtonUp", "RightButtonDown")
一种简化的写法是用AnyUp代替所有的按钮释放事件,用AnyDown代替所有的按钮按下事件。下面是一段示例代码:
2 <Size x="100" y="100" />
3 <Anchors>
4 <Anchor point="CENTER" relativePoint="CENTER"
5 relativeTo="UIParent" />
6 </Anchors>
7 <Layers>
8 <Layer level="BACKGROUND">
9 <Texture name="$parentIcon"
10 file="Interface\Icons\Spell_Shadow_ShadowWordPain"
11 setAllPoints="true" />
12 </Layer>
13 </Layers>
14 <Scripts>
15 <OnLoad>
16 self:RegisterForClicks("AnyUp", "AnyDown")
17 </OnLoad>
18 <OnClick>
19 ChatFrame1:AddMessage(self:GetName() .. " - Button: " ..
20 tostring(button) .. " Down: " .. tostring(down))
21 </OnClick>
22 </Scripts>
23 </Button>
按钮在被按下的同时,将向聊天窗口发送“相应鼠标按键按下为true”的信息,松开时也会发送“相应鼠标按键按下为false”的信息。
<OnUpdate>
每次魔兽世界客户端重绘框架时均会呼叫<OnUpdate>脚本。实际上,“重绘框架”只意味着框架被“显示”,但并不代表框架会被用户“看见”。一个没有任何可见元素的框架,依然可以触发OnUpdate事件。此事件用来执行一些特殊的任务。
其他常见事件
OnChar(self, text)
当一个框架的enableMouse属性字段为true时,任何的键盘输入均会触发OnChar事件并将输入的字符传入。支持所有框架类型。
OnClick(self, button, down)
见上。只支持按钮和复选框类型的框架。
OnDoubleClick(self, button)
与OnClick类似。只有当按钮或复选框监听某一按钮的Up事件时,双击该按钮才会触发OnDoubleClick事件。
OnDragStart / OnDragStop (self, button)
拖曳相关。需要先用:RegisterForDrag()注册到鼠标拖曳事件(参数为鼠标按键名, 支持一个以上)。开始拖曳时呼叫OnDragStart,松开时呼叫OnDragStop。
OnEnter / OnLeave (self, motion)
当框架可接受鼠标事件时,鼠标进入/离开框架时触发。motion参数为true时,表示是鼠标移动导致鼠标指针进入/离开框架;反之,则可能是框架变为可见时鼠标恰好位于可见区域内(即进入/离开并非由鼠标指针移动引起)。
OnHide / OnShow (self)
显示/隐藏框架时触发。可以用OnHide来取消对特定事件的监听,以减少系统资源消耗。
PreClick(self, button, down) / PostClick(self, button, down)
对OnClick的一种补足。只支持按钮和复选框类型的框架。
常用的框架方法
:GetAlpha()
返回此对象的透明度(即alpha值)
:GetName()
返回此对象名称。若未在XML代码中指定名称,则返回nil。
:GetObjectType()
返回此对象的类型。
:IsObjectType("type")
若此对象的类型为参数给定类型,返回1,否则返回nil。
:SetAlpha(alpha)
设定此对象的透明度。参数取值范围0.0~1.0。
:Show()
设定此对象为可见。若该对象处于屏幕范围外,依然无法被看见。
:Hide()
隐藏此对象。
:IsShown()
当此对象没有被:Hide()隐藏时,返回1,否则返回nil。
:IsVisible()
若此对象及其所有前代对象均未被隐藏,返回1,否则返回nil。
以上的方法对所有类型的对象均适用。其他的一部分方法则只对一部分的对象有效,例如:RegisterForClicks()就只对Buttons和CheckButtons类型的对象有效。
创建及使用模板
XML在定义框架内容上,相对较显繁琐。为缩短代码书写时间,实际上,暴雪提供了上百种模板用于简化用户界面的开发工作。使用模板,不但可以迅速地创建某一特定格式的框架(例如 32x32大小、处于OVERLAY层、并包含一部分预设代码的按钮),而且在需要对同一系列的按钮格式作出修改时,只需修改模板,极大的减少了工作量。
建立模板
建立模板,实际上就是建立一个框架,只是其拥有virtual字段,并且值为true。如前所述,这样的框架代码,在加载时不会生成实际的框架实体(因为它是“虚”的),而是作为模板存在。
例如,在插件的XML文档的<Ui>元素中可以放入如下的模板定义:
2 <Size x="32" y="32" />
3 <Layers>
4 <Layer level="OVERLAY">
5 <Texture name="$parentIcon"
6 file="Interface\Icons\Spell_Shadow_ShadowWordPain"
7 setAllPoints="true" />
8 </Layer>
9 </Layers>
10 <Scripts>
11 <OnLoad>
12 self.Icon = getglobal(self:GetName().."Icon")
13 </OnLoad>
14 <OnEnter>
15 self.Icon:SetDesaturated(true)
16 </OnEnter>
17 <OnLeave>
18 self.Icon:SetDesaturated(nil)
19 </OnLeave>
20 <OnClick>
21 ChatFrame1:AddMessage("You clicked on "..self:getName())
22 </OnClick>
23 </Scripts>
24 </Button>
上面的代码创建了一个32x32按钮的模板。该按钮在OVERLAY层有图案,图案为暗言术·痛技能的图标。
在处理OnLoad事件(即实际按钮被加载)时,通过getglobal()方法获得<Texture>对象。注意在定义<Texture>时,对其命名时所用的字串是"$parentIcon",这里的$parent是其父对象名称的通配符(实际上,也就是这个框架本身)。注意这个关系:
框架名为****** ----> Texture对象名为******Icon
self:getName()获得的是框架名(******)
----> self:getName().."Icon"即是"******Icon"
所以可以用getglobal()方法加上这样的参数获得这个图标<Texture>对象本身,并存在框架的Icon变量内,方便其他代码(在这里是OnEnter/OnLeave)取用它。
现在来看处理OnEnter/OnLeave事件的代码。:SetDesaturated()方法需要一个布尔型的参数,当其为true时,将使目标对象色彩变为灰度模式。再通过:SetDesaturated(nil)可以将其调回标准色彩模式。因此,鼠标移入按钮区域时,按钮的图标将变为灰色;在移出时,按钮将变为正常色彩。
OnClick事件处理模块在每次鼠标点击图标时输出提示信息到聊天窗口。
使用模板
在定义了上面的模板之后,就可以这样利用模板创建数个按钮:
<Anchors>
<Anchor point="BOTTOMRIGHT" relativePoint="CENTER"
relativeTo="UIParent" />
</Anchors>
</Button>
<Button name="IconTest2" inherits="IconTestTemplate" parent="UIParent">
<Anchors>
<Anchor point="BOTTOMLEFT" relativePoint="CENTER"
relativeTo="UIParent" />
</Anchors>
</Button>
<Button name="IconTest3" inherits="IconTestTemplate" parent="UIParent">
<Anchors>
<Anchor point="TOPRIGHT" relativePoint="CENTER"
relativeTo="UIParent" />
</Anchors>
</Button>
<Button name="IconTest4" inherits="IconTestTemplate" parent="UIParent">
<Anchors>
<Anchor point="TOPLEFT" relativePoint="CENTER"
relativeTo="UIParent" />
</Anchors>
</Button>
这段代码会在屏幕中央建立2x2的方格,每个格子都有一个暗言术·痛的图标。点击图标时,在聊天窗口均会输出对应的提示信息。
一些常用的模板
UIPanelButtonTemplate: 长条状的按钮
UIPanelButtonTemplate2: 长条状的按钮,与UIPanelButtonTemplate稍有不同
UIPanelCloseButton: 关闭按钮(X)
InputBoxTemplate: 聊天窗口所用的输入框
UICheckButtonTemplate: 复选框模板
UIRadioButtonTemplate: 单选框模板
TabButtonTemplate: 标签模板
GameMenuButtonTemplate: 游戏系统菜单(按ESC出现)的按钮模板
OptionsSliderTemplate: 滑块条模板

浙公网安备 33010602011771号