这个是我自己分析WOW原始UI代码后,对一些比较关键的部分,我记录下来的
这次我写的是ZoneText.xml和ZoneText.lua,是显示地区文字的UI,在Interface/FrameXML里面
至于如何提取文件,如何查询函数,如何测试,还有一些基础问题和显而易见的东西我就不累述了
大家可以在网上找找这些文章,或者E-mail找我要,asdic.xxs@gamil.com
文章里面如果有什么纰漏,希望大家毫不客气的提出来,我一定查究!
版本:1。7。1
做人要厚道,转载请注明出处。
该颜色表示:最近版本更新
该颜色表示:最近错误修改
------------
先看图像,因为我是在5区新开的小号测试的UI,所以不可能满世界到处跑去截图
对下面这种古怪的截图方式,希望大家能够体谅
我先解释一下下面要用到的术语指的是什么
【地域】:就是地图上面一块大地方的名字,在图像的第一排,如:莫高雷
【pvp信息】:显示该地区的阵营信息,一般在地域的下面,如:联盟或者部落
【地区】:在地图上面最细小的地方,一般和迷你地图上面的名字相同,一般在最后一排,如:纳拉其营地
【战场信息】:显示为“pvp区域”,一般在最后一排,我没有到战场截图,而是改成了战场变量
【跟随信息】:这里显示的是“正在跟随XX”,“已经停止跟随XX”那个文本框,一般在屏幕正中间
下面是ZoneText.xml和ZoneText.lua的源码,我的注释会插入其中。
ZoneText.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">
<Script file="ZoneText.lua"/>
<Script>
ZoneFadeInDuration = 0.5;
文字淡入时间
ZoneHoldDuration = 1.0;
文字显示时间
ZoneFadeOutDuration = 2.0;
文字淡出时间
function SetZoneText(showPVPInfo)
这个函数用来设置文字的颜色和临时显示位置
ZoneTextString:SetText(GetZoneText());
GetZoneText函数,用来得到当前【地域】
local pvpType, factionName, isArena = GetZonePVPInfo();
if ( pvpType == "friendly" ) then
PVPInfoTextString:SetText(format(FACTION_CONTROLLED_TERRITORY, factionName));
FACTION_CONTROLLED_TERRITORY显示为“营地”
factionName显示“部落”还是“联盟”
ZoneTextString:SetTextColor(0.1, 1.0, 0.1);
SubZoneTextString:SetTextColor(0.1, 1.0, 0.1);
PVPInfoTextString:SetTextColor(0.1, 1.0, 0.1);
SubZoneTextString:SetPoint("TOP", "PVPInfoTextString", "BOTTOM", 0, 0);
相当于SetPoint(point,relativeTo,relativePoint,OffsetX,OffsetY)
elseif ( pvpType == "hostile" ) then
PVPInfoTextString:SetText(format(FACTION_CONTROLLED_TERRITORY, factionName));
ZoneTextString:SetTextColor(1.0, 0.1, 0.1);
SubZoneTextString:SetTextColor(1.0, 0.1, 0.1);
PVPInfoTextString:SetTextColor(1.0, 0.1, 0.1);
SubZoneTextString:SetPoint("TOP", "PVPInfoTextString", "BOTTOM", 0, 0);
elseif ( pvpType == "contested" ) then
PVPInfoTextString:SetText(CONTESTED_TERRITORY);
CONTESTED_TERRITORY显示为“争夺中的领土”
ZoneTextString:SetTextColor(1.0, 0.7, 0);
SubZoneTextString:SetTextColor(1.0, 0.7, 0);
PVPInfoTextString:SetTextColor(1.0, 0.7, 0);
SubZoneTextString:SetPoint("TOP", "PVPInfoTextString", "BOTTOM", 0, 0);
else
1.6.2:这种情况一般不发生,但是当你执行/console reloadui,或者其他一些命令的时候使得UI值清空
但是此时没有调用过GetZonePVPInfo,所以这时pvpType的值为nil
1.7.1:改正了这个BUG,当执行/console reloadui后,GetZonePVPInfo将会执行一次,所以pvpType中有当前正确的值
PVPInfoTextString:SetText("");
ZoneTextString:SetTextColor(1.0, 0.9294, 0.7607);
SubZoneTextString:SetTextColor(1.0, 0.9294, 0.7607);
SubZoneTextString:SetPoint("TOP", "ZoneTextString", "BOTTOM", 0, 0);
end
if ( isArena ) then
判断在战场
PVPArenaTextString:SetText(FREE_FOR_ALL_TERRITORY);
FREE_FOR_ALL_TERRITORY显示为“pvp区域”
SubZoneTextString:SetTextColor(1.0, 0.1, 0.1);
else
PVPArenaTextString:SetText("");
end
if ( not showPVPInfo ) then
PVPInfoTextString:SetText("");
SubZoneTextString:SetPoint("TOP", "ZoneTextString", "BOTTOM", 0, 0);
当不显示【pvp信息】的时候,【地区】显示上升一排,近接着【地域】下面
end
end
</Script>
<!-- These frames are shown when the current zone or subzone changes -->
<Frame name="ZoneTextFrame" parent="UIParent" frameStrata="LOW" toplevel="true">
显示【区域】的窗口,其中还包括了【pvp信息】窗口
<Anchors>
<Anchor point="BOTTOM">
<Offset>
<AbsDimension x="0" y="512"/>
</Offset>
</Anchor>
</Anchors>
<Size>
<AbsDimension x="128" y="128"/>
</Size>
<Layers>
<Layer level="ARTWORK">
<FontString name="ZoneTextString" inherits="ZoneTextFont">
【地域】文本框
<Size>
<AbsDimension x="512" y="0"/>
他的大小,如果值为0则为自动适应大小变化
如果大小超过指定值,但还可以显示“...”,则显示“...”
如果连“...”也显示不了则什么也不显示
</Size>
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
</FontString>
<FontString name="PVPInfoTextString" inherits="SubZoneTextFont">
【pvp信息】文本框
<Size>
<AbsDimension x="512" y="0"/>
</Size>
<Anchors>
<Anchor point="TOP" relativeTo="ZoneTextString" relativePoint="BOTTOM"/>
这个是通常情况下的对齐方式,临时的方式可以在上面SetZoneText函数里面更改
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
FadingFrame_OnLoad();
FadingFrame_SetFadeInTime(this, ZoneFadeInDuration);
FadingFrame_SetHoldTime(this, ZoneHoldDuration);
FadingFrame_SetFadeOutTime(this, ZoneFadeOutDuration);
this:RegisterEvent("ZONE_CHANGED");
【地区】变更
this:RegisterEvent("ZONE_CHANGED_INDOORS");
进入城市
this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
【地域】变更
</OnLoad>
<OnEvent>
local newText = GetZoneText();
if ( event == "ZONE_CHANGED" ) then
this.zoneText = newText;
这里并没有判断【地域】是否变化,但是他更新了【地域】文本
return;
这个if的意思是,仅【地区】变更后,并不显示【地域】和【pvp信息】文本框,return实现了这个作用
end
这里注意,ZONE_CHANGED和ZONE_CHANGED_NEW_AREA是互斥事件
即当进入新【地域】的时候并不产生ZONE_CHANGED
if ( newText ~= this.zoneText ) then
这是对ZONE_CHANGED_INDOORS的处理
this.zoneText = newText;
if ( event == "ZONE_CHANGED_NEW_AREA" ) then
当进入新【地域】的时候,同时显示【pvp信息】
SetZoneText(1);
else
SetZoneText();
如果是进入城市则不显示
end
FadingFrame_Show();
显示!
end
这里注意,虽然进入城市要显示该文本框,但是它并不是一种ZONE_CHANGED_NEW_AREA事件
</OnEvent>
<OnUpdate>
FadingFrame_OnUpdate();
这个函数用来做淡出特效
</OnUpdate>
</Scripts>
</Frame>
<Frame name="SubZoneTextFrame" parent="UIParent" frameStrata="LOW" toplevel="true">
【地区】窗口,包括了【战场信息】窗口
<Anchors>
<Anchor point="BOTTOM">
<Offset>
<AbsDimension x="0" y="512"/>
</Offset>
</Anchor>
</Anchors>
<Size>
<AbsDimension x="128" y="128"/>
</Size>
<Layers>
<Layer level="ARTWORK">
<FontString name="SubZoneTextString" inherits="SubZoneTextFont">
【地区】文本
<Size>
<AbsDimension x="512" y="0"/>
</Size>
<Anchors>
<Anchor point="TOP" relativeTo="ZoneTextString" relativePoint="BOTTOM"/>
</Anchors>
</FontString>
<FontString name="PVPArenaTextString" inherits="SubZoneTextFont">
【战场信息】文本
<Size>
<AbsDimension x="512" y="0"/>
</Size>
<Anchors>
<Anchor point="TOP" relativeTo="SubZoneTextString" relativePoint="BOTTOM"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
FadingFrame_OnLoad();
FadingFrame_SetFadeInTime(this, ZoneFadeInDuration);
FadingFrame_SetHoldTime(this, ZoneHoldDuration);
FadingFrame_SetFadeOutTime(this, ZoneFadeOutDuration);
this:RegisterEvent("ZONE_CHANGED");
this:RegisterEvent("ZONE_CHANGED_INDOORS");
this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
下面3句放在OnLoad下面,表示了进入游戏后将显示全部信息
注意,在【地域】窗口中并没有下面3句
PVPArenaTextString:SetTextColor(1.0, 0.1, 0.1);
【战场信息】初始化
SetZoneText(1);
【pvp信息】初始化
SubZoneTextString:SetText(GetSubZoneText());
【地区】初始化
</OnLoad>
<OnEvent>
local text = SubZoneTextString:GetText();
local newText = GetSubZoneText();
if(text ~= newText) then
SubZoneTextString:SetText(newText);
SetZoneText(1);
更新【pvp信息】,虽然不显示,但是仍然需要更新
FadingFrame_Show();
注意,这里的FadingFrame_Show虽然和上一个【地域】窗口的同名,但是实际不同
所以这个是显示【地区】文本框,而且并不显示【pvp信息】文本框
end
注意,这里并没有判断event,因为任意一个该窗口注册的事件都能够引起以上语句
</OnEvent>
<OnUpdate>
FadingFrame_OnUpdate();
</OnUpdate>
</Scripts>
</Frame>
<Frame name="AutoFollowStatus" parent="UIParent" setAllPoints="true" frameStrata="BACKGROUND" hidden="true">
【跟随信息】窗口
<Layers>
<Layer level="ARTWORK">
<FontString name="AutoFollowStatusText" inherits="GameFontNormal">
<Anchors>
<Anchor point="CENTER">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<FontHeight>
<AbsValue val="20"/>
这个我有疑问,没有试出来,请高人帮忙指定一下,或者等我分析以后的东西知道后再写上来
</FontHeight>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
AutoFollowStatus_OnLoad();
</OnLoad>
<OnEvent>
AutoFollowStatus_OnEvent(event);
</OnEvent>
<OnUpdate>
AutoFollowStatus_OnUpdate(arg1);
arg1代表跟随目标的名字
</OnUpdate>
</Scripts>
</Frame>
</Ui>
ZoneText.lua
AUTOFOLLOW_STATUS_FADETIME = 4.0;
淡出时间
function AutoFollowStatus_OnLoad()
this:RegisterEvent("AUTOFOLLOW_BEGIN");
自动跟随开始时的事件
this:RegisterEvent("AUTOFOLLOW_END");
自动跟随结束
this:RegisterEvent("PLAYER_ENTERING_WORLD");
进出游戏,出入副本,复活或者死亡
end
function AutoFollowStatus_OnEvent(event)
if ( event == "AUTOFOLLOW_BEGIN" ) then
this.unit = arg1;
跟随对象名字
this.fadeTime = nil;
注意,正在跟随的时候,淡出时间为nil即不淡出
this:SetAlpha(1.0);
AutoFollowStatusText:SetText(format(TEXT(AUTOFOLLOWSTART),this.unit));
AUTOFOLLOWSTART显示为“正在跟随”
this:Show();
end
if ( event == "AUTOFOLLOW_END" ) then
this.fadeTime = AUTOFOLLOW_STATUS_FADETIME;
设定淡出时间,即停止跟随后文字将淡出屏幕
AutoFollowStatusText:SetText(format(TEXT(AUTOFOLLOWSTOP),this.unit));
AUTOFOLLOWSTOP显示为“已停止跟随”
this:Show();
end
if ( event == "PLAYER_ENTERING_WORLD" ) then
this:Hide();
若跟随时发生PLAYER_ENTERING_WORLD,则隐藏文本
end
end
function AutoFollowStatus_OnUpdate(elapsed)
elapsed为经过的时间,为上次OnUpdate到这次的间隔
if( this.fadeTime ) then
if( elapsed >= this.fadeTime ) then
this:Hide();
else
this.fadeTime = this.fadeTime - elapsed;
local alpha = this.fadeTime / AUTOFOLLOW_STATUS_FADETIME;
this:SetAlpha(alpha);
end
end
end
总结一下
函数
GetZoneText() 得到当前【地域】
GetZonePVPInfo() 得到当前【pvp信息】
GetSubZoneText() 得到当前【地区】
常量
FACTION_CONTROLLED_TERRITORY “营地”
CONTESTED_TERRITORY “争夺中的领土”
FREE_FOR_ALL_TERRITORY “pvp区域”
AUTOFOLLOWSTART “正在跟随”
AUTOFOLLOWSTOP “已停止跟随”
事件
ZONE_CHANGED 【地区】变更
ZONE_CHANGED_INDOORS 进入城市
ZONE_CHANGED_NEW_AREA 【地域】变更
AUTOFOLLOW_BEGIN 自动跟随开始
AUTOFOLLOW_END 自动跟随停止
PLAYER_ENTERING_WORLD 进出游戏,进出副本,死亡或者复活