欢迎访问:常州市武进区嘉泽中心小学网站 !今天是:
栏目列表
您现在的位置是:首页>>教师>>计算机技术>>程序设计>>游戏开发>>文章内容
WOW原始UI代码分析【ZoneText】
发布时间:2008-11-20   点击:   来源:本站原创   录入者:佚名
 

这个是我自己分析WOW原始UI代码后,对一些比较关键的部分,我记录下来的
这次我写的是ZoneText.xml和ZoneText.lua,是显示地区文字的UI,在Interface/FrameXML里面
至于如何提取文件,如何查询函数,如何测试,还有一些基础问题和显而易见的东西我就不累述了
大家可以在网上找找这些文章,或者E-mail找我要,asdic.xxs@{域名已经过期}

文章里面如果有什么纰漏,希望大家毫不客气的提出来,我一定查究!

版本:1。7。1

做人要厚道,转载请注明出处。

该颜色表示:最近版本更新
该颜色表示:最近错误修改

------------

先看图像,因为我是在5区新开的小号测试的UI,所以不可能满世界到处跑去截图
对下面这种古怪的截图方式,希望大家能够体谅

我先解释一下下面要用到的术语指的是什么

【地域】:就是地图上面一块大地方的名字,在图像的第一排,如:莫高雷
【pvp信息】:显示该地区的阵营信息,一般在地域的下面,如:联盟或者部落
【地区】:在地图上面最细小的地方,一般和迷你地图上面的名字相同,一般在最后一排,如:纳拉其营地
【战场信息】:显示为“pvp区域”,一般在最后一排,我没有到战场截图,而是改成了战场变量
【跟随信息】:这里显示的是“正在跟随XX”,“已经停止跟随XX”那个文本框,一般在屏幕正中间

下面是ZoneText.xml和ZoneText.lua的源码,我的注释会插入其中。

                                                 ZoneText.xml
<Ui xmlns="" xmlns:xsi="http://{域名已经过期}/2001/XMLSchema-instance" xsi:schemaLocation="
..\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   进出游戏,进出副本,死亡或者复活


附件:
    关闭窗口
    打印文档
    账号登录
    保持登录 忘记密码?
    账号与武进教师培训平台同步