魔兽世界编程宝典读书笔记(11)

本章探讨XML模板并开始向XML窗体中添加动态行为,介绍事件和脚本响应,包括理解事件和脚本,使用脚本响应窗体事件,创建并使用模板,以及使用默认UI工具集模板。

第11章            XML窗体中添加行为

我们现在已经创建了窗体、图形以及字体,并能对窗体的大小和位置进行设置,但是这些窗体都是静态的,不能同用户进行交互,或对任何游戏事件进行响应。本章将讨论XML模板,并且开始向XML窗体中添加动态行为。本章仅简单介绍如何添加行为,详细介绍要在第31章进行。

11.1       理解事件和脚本

通过游戏事件,用户界面随着游戏状态的改变而改变。在这个过程中游戏可以通过窗体脚本与用户进行交互。

11.1.1窗体脚本

每个用于创建用户界面的窗体都具有特定类型的行为,它们可以实现响应,从而使界面真正变得具有交互性。

11.1.2游戏事件

游戏事件是指游戏当中发生的各种事情,这些事情通常是游戏中的各种状态发生了改变。例如,当某个单位(团队中小队中的一个成员,或者是你选中的目标,无论是怪还是队友)生命值发生改变时,就会触发一个事件:UNIT_HEALTH

如果你希望在某事件发生时去做一些事情(例如当队友血量过低时发出一个警告声),我们就必须使用:RegisterEvent()方法进行一个注册,这会使得每次事件触发时就调用<OnEvent>脚本。

每个窗体可以根据需要注册任意多的事件,但仅能够有一个 <OnEvent>脚本。游戏会将事件名称都发送到该处理模块,然后再根据不同的事件进行响应。

11.2       使用脚本响应窗体事件

11.2.1<OnEnter><OnLeave>

任何具有enableMouse属性的窗体都可以使用自定义的脚本对<OnEnter><OnLeave>行为进行响应。(默然说话:OnEnter就是鼠标进入事件,它在鼠标移动到一个窗体上被触发,OnLeave是鼠标离开事件,它在鼠标离开一个窗体上被触发)下面的代码是一个窗体的XML定义,其对这些行为进行了响应;它们应当位于WowXMLExample.xml<Ui>节中:

<Framename="EnterLeaveTest" parent="UIParent">

             <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_ShadowWordPain" setAllPoints="true"/>

                    </Layer>

             </Layers>

             <Scripts>

                    <OnEnter>

                           ChatFrame1:AddMessage("++ 进入窗体:" .. self:GetName())

                    </OnEnter>

                    <OnLeave>

                           ChatFrame1:AddMessage("-- 离开窗体:" .. self:GetName())

                    </OnLeave>

             </Scripts>

      </Frame>

<Scripts>专门用来进行了事件响应代码的编写。如果你将这个插件加载,你会在屏幕的中央看到一个窗体,它的图标是“暗言术:痛”,如果你把鼠标移动到这个窗体上,你会看到聊天窗口会输出一句话:“++进入窗体:EnterLeaveTest”,如果移出来,则会看到:“离开窗体:EnterLeaveTest”。

11.2.2<OnLoad>

XML中定义的每个窗体都可以拥有一个<OnLoad>脚本,并在窗体最初创建时执行。这个脚本通常用于注册事件和其他的初始化行为。脚本处理模块被调用时,伴随着表示窗体本身的self变量。下面的XML可以用于注册UNIT_HEALTH事件:

<OnLoad>

self:RegisterEvent("UNIT_HEALTH")

</OnLoad>

11.2.3<OnEvent>

大多数事件的响应代码都应该放在OnEvent元素里。我们可以使用一系列判断语句,来完成对不同事件的响应处理。下面是一断模拟代码:

functionOnEvent(self,event,…)

      if event == “UNIT_HEALTH” then

             --这里写响应生命变动的代码

    elseif event == “UNIT_MANA” then

             --这里写响应法师值变动的代码

    end

end

对于各种不同的事件,它们会有各种不同的参数,请参考第30章的事件列表。

下面是测试事件的注册和响应的代码:

<Scripts>

             <OnLoad>

                    self:RegisterEvent("UNIT_HEALTH")

             </OnLoad>

                           

             <OnEvent>

                    local unit=...

                    ChatFrame1:AddMessage("UNIT_HEALTH - unit=" .. unit)

             </OnEvent>

</Scripts>

UNIT_HEALTH事件仅接收一个参数,即生命值受到影响的单位。由于OnEvent处理模块使用Lua的变量机制来传入变量,因此我们将“”指定到局部变量,以使得我们可以得到unit这个参数并进行输出。这段代码在窗体发现单位的血量发生变化时就会触发,在聊天窗体里打出一句话。

11.2.4<OnClick>

按钮及复选按钮可以借助<OnClick>脚本响应对按钮的单击。本函数按受3个参数:

self——被单击的按钮

button——进行单击的鼠标按键

down——鼠标单击的方向

魔兽世界总共可以识别5种不同的鼠标按键:左键(LeftButton)、右键(RightButton)、中键(MiddleButton)、按键4Button4)和按键5Button5)。此外,游戏可以区分单击动作中鼠标按下和放开。默认情况下,按键仅接受LeftButtonUp事件,即左键的鼠标放开动作。这一点可以使用“:RegisterForClicks()”方法进行改变。

想要注册左击和右击,并且同时能接受按下和放开事件,您可以在<OnLoad>脚本中调用下面的代码:

self:RegisterForClicks(“LeftButtonUp”,”LeftButtonDown”,”RightButtonUp”,”RightButtonDown”)

注册一个按钮单击最简单的方法是在RegisterForClicks()方法中使用”AnyUp””AnyDown”虚拟按键。下面的代码是一个XML定义的例子,展示了一个<OnClick>脚本。

<Buttonname="OnClickTest" parent="UIParent">

             <Size x="100" y="100" />

             <Anchors>

                    <Anchorpoint="CENTER" relativePoint="CENTER"relativeTo="UIParent" />

             </Anchors>

             <Layers>

                    <Layer level="BACKGROUND">

                           <Texture name="$parentIcon"file="Interface\Icons\Spell_Shadow_ShadowWordPain"setAllPoint="true" />

                    </Layer>

             </Layers>

             <Scripts>

                    <OnLoad>

                           self:RegisterForClicks("AnyUp","AnyDown")

                    </OnLoad>

                    <OnClick>

                           ChatFrame1:AddMessage(self:GetName() .." - Button: " .. tostring(button) .. "Down:" ..tostring(down))

                    </OnClick>

             </Scripts>

      </Button>

11.2.5<OnUpdate>

这是一个特殊的脚本,它在每次魔兽世界客户端重新绘制一个窗体时调用。因此,当窗体被显示(不一定被玩家看到)时触发。一个窗体可以没有纹理或可视元素,但OnUpdate脚本仍可存在,来完成一些阶段性的任务,这个脚本将在第18章创建MapZoomOut插件时使用,并用来创建一个管理排序的时间器。

11.3       可用的窗体脚本

11-1    窗体脚本

脚本

描述

适用的窗体

OnChar(self,text)

当窗体enableMouse属性为true时,所有的键盘输入将使用这个脚本发送到窗体中,第二个参数为从键盘接收到的文本

所有窗体类型

OnClick(self,button,down)

当鼠标单击到按钮上时,该脚本被调用,第二个参数为鼠标所按的键(LeftButton,RightButton),第三个参数为触发时鼠标键的状态,true表示被按下

按钮、复选按钮

OnDoubleClick(self,button)

当鼠标双击到一个按钮时调用此脚本。鼠标按下不能触发此事件,只能在鼠标放开的时候会触发。

按钮、复选按钮

OnDragStart(self,button)

OnDragStop(self,button)

窗体拖拉事件,在用户按住鼠标键同时移动鼠标时触发OnDragStart事件,释放鼠标时触发OnDragStop事件。第2个参数是鼠标键的名称列表,如LeftButton,RightButton等。可以调用self:RegisterForDrag()来注册拖拽事件。

所有窗体类型

OnEnter(self,motion)

OnLeave(self,motion)

当一个窗体被设定为接收鼠标事件时,OnEnter在鼠标移动到窗体里时触发,OnLeave在鼠标移动到窗体外时触发。

所有窗体类型

OnHide(self)

OnShow(self)

OnHide在窗体被隐藏时触发,OnShow在窗体被显示时触发,隐藏的窗体可以继续接收事件。

所有窗体类型

PreClick(self,button,down)

PostClick(self,button,down)

预单击

后单击(什么屁话!)

按钮,复选按钮

11.4       使用窗体方法改变窗体

您在魔兽世界中所创建的每个带名称的窗体可以通过Lua脚本接口进行访问,您可以直接与它进行交互。调用它们的方法,修改它们的属性。包含所有窗体类型及相关可用方法的完整列表请参阅第31章。

11.4.1常用方法

11-2窗体、纹理和字体字符串的常用方法

方法

描述

Object:GetAlpha()

得到给定对象当前的透明度值

Object:GetName()

得到给定对象的名称,若没有名称则返回nil

Object:GetObjectType()

返回包含对象类型的字符串

Object:IsObjectType(“type”)

若对象为给定的类型则返回1,否则返回nil

Object:SetAlpha(alpha)

设定给定对象的透明度。alpha应当为一个介于0.0~1.0之间的值

Object:Show()

显示对象。这可能不会使其显示在屏幕上,例如,若其没有被放置,或是其父对象被隐藏。

Object:Hide()

隐藏对象

Object:IsShown()

若对象正在被显示则返回1,否则返回nil。这并不意味着其一定在屏幕上可见,仅能说明对象的Object:Hide()没有被调用。

Object:IsVisible()

若对象及其父对象、祖父对象等祖先均被显示,则返回1

11.4.2指定类型的函数

关于窗体方法有很多,请参阅第31章。

11.5       创建并使用模板

魔兽世界提供了几百个不同的模板来供默认用户界面使用,这样,你开发的用户界面与别人开发的用户界面很容易就能统一一致。

11.5.1模板有用的原因

模板最大的作用不是体现在创建它的时候,而是体现在当我们需要进行修改的时候,如果不使用模板,我们需要对界面进行的相同修改可能就需要重复几十甚至上百次,而使用了模板,我们只需要修改模板就可以了。

11.5.2新建XML模板

创建一个XML模板需要在name属性中提供模板名称,并将virtual属性设置为true。其它和您编辑一个窗体的设置是一样的。

在您的WowXMLExample.xml文件的<Ui>节中创建下面的XML定义:

<Buttonname="IconTestTemplate" virtual="true">

             <Size x="32" y="32" />

             <Layers>

                    <Layer level="OVERLAY">

                           <Texture name="$parentIcon"

file="Interface\Icons\Speel_Shadow_ShadowWordPain"setAllPoints="true" />

                    </Layer>

             </Layers>

             <Scripts>

                    <OnLoad>

                           self.Icon=getglobal(self:GetName() .."Icon")

                    </OnLoad>

                    <OnEnter>

                           self.Icon:SetDesaturated(true)

                    </OnEnter>

                    <OnLeave>

                           self.Icon:SetDesaturated(nil)

                    </OnLeave>

                    <OnClick>

                           ChatFrame1:AddMeessage("You clickedon " .. self:GetName())

                    </OnClick>

             </Scripts>

      </Button>

这里创建了一个按钮,它会显示暗言术:痛的图标,当鼠标移动到上面时,图标会变成灰度(OnEnter中定义的内容),当鼠标移动开的时候,图标双恢复彩色(OnLeave中定义的内容),如果你单击了这个按钮,会在聊天窗体中显示一句话(OnClick定义的内容)。

11.5.3使用XML模板

现在我们使用刚刚定义的模板来创建四个按钮:(同样位于<Ui>节)

<Buttonname="IconTest1" inherits="IconTestTemplate"parent="UIParent">

             <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="TOPLEFT"relativePoint="CENTER" relativeTo="UIParent" />

             </Anchors>

      </Button>

      <Button name="IconTest4"inherits="IconTestTemplate" parent="UIParent">

             <Anchors>

                    <Anchor point="TOPRIGHT"relativePoint="CENTER" relativeTo="UIParent" />

             </Anchors>

      </Button>

11.6       使用默认UI工具集模板

魔兽世界提供了几百个在游戏中很有用的用户界面模板。本节将介绍使用最频繁的几个模板。

11-3使用最频繁的模板

模板

描述

UIPanelButtonTemplate

在游戏中用于游戏按钮

UIPanelButtonTemplate2

UIPanelButtonTemplate用途相同,更易于调整尺寸。

UIPanelCloseButton

用于许多用户界面创建简单的“关闭”按钮

InputBoxTemplate

默然用户界面用它来做聊天窗体,插件用它来输入文本

UICheckButtonTemplate

允许您创建一个复选按钮。包括显示的提示功能的文字

TabButtonTemplate

可用于在一个窗口的顶端或底端创建带标签的按钮。它可以较好地整合到默认UI样式中

GameMenuButtonTemplate

具有指定的尺寸,这是由于其被用于当您按Esc键时显示的菜单

UIRadioButtonTemplate

可用于创建简单的选项按钮。

OptionsSliderTemplate

为您提供一个主标签,同时提供了一些子标签来表示最大值和最小值。有个滑块可以用来在一个范围内选择数值。

11.7       小结

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

默然说话

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值