【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 4026|回复: 3

[脚本语言] 魔兽插件以及LUA--程序员快速入手指南

[复制链接]
发表于 2007-5-10 11:18:13 | 显示全部楼层 |阅读模式
QUOTE:
目录:
1楼: toc
2楼: xml
3楼: lua
4楼: 工具
5楼: 沙发-.o
你首先要做的,是了解在WoW中的插件基本规则:每一个project要放在 魔兽目录\Interface\Addons\Project 中。
基本文件有:一个toc文件、一个lua文件或者xml文件。

toc文件就是工程文件,包含工程的基本信息。主要包含以下内容

QUOTE:
## Interface: 适用的魔兽版本号
## Title: 显示的标题(默认语言)
## Notes: 显示的说明(默认语言)
## Title-zhCN: 特定语言的标题(简体中文)
## Notes-zhCN: 特定语言的说明(简体中文)
## Author: 作者(不显示)
## Version: 版本
## eMail: 如题
## UIType: 插件类型
## Dependencies: 依赖的插件
## RequiredDeps: 必须依赖的其他插件
## OptionalDeps: 可选倚赖
## SavedVariables: 统一存放的变量
## SavedVariablesPerCharacter: 按角色存放的变量
## LoadOnDemand: 1 (调用时加载)
## DefaultState: disabled  默认状态
脚本文件.lua
布局文件.xml

其中##是注释符号,注意这些注释不是光好看的哦,要是不注意插件根本就不会载入。绿色表示必须的,棕色的是比较重要的,其他可选。有很多都是没什么用的,像Version、eMail都不会显示,纯属注释。

脚本文件和布局文件的数量随意,但至少要有一个:一个lua或一个xml。最需要注意的是,这里的顺序对应着载入顺序,非常要紧!!!!

还有一点也很要紧:注意你如果要写中文,文件一定要保存为UTF-8格式
方法很简单:用记事本打开,另存为,选择编码就行;文件格式要选所有文件,否则会存成txt文件。

建议你多下几个插件,打开看看,参考一下。

实用资料汇集(工具选用见4楼):

链接:
魔兽API索引
控件API索引
事件EVENT索引

魔兽插件XML文件语法定义文件,可用记事本打开察看[1.11]:

http://bbs.game.mop.com/attachment.php?aid=112403

魔兽系统界面原始代码[1.11.2]:lua文件和xml文件,包括UI.xsd
获取办法:用打开mpq文件的工具打开Interface.mpq解压FrameXML文件夹,然后还必须打开Patch.mpq文件以及patch-1~N文件解压FrameXML并覆盖Interface中的即可
http://bbs.game.mop.com/attachment.php?aid=113507

 楼主| 发表于 2007-5-10 11:18:57 | 显示全部楼层
XML文件

在魔兽插件中使用XML来描述UI布局。

首先注意:在魔兽插件中XML的注释,是<!--  -->,最好不要写中文注释

一个XML文件往往包含以下内容:

QUOTE:
<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/
C:\Projects\WoW\Bin\Interface\FrameXML\UI.xsd">
        <Script file="localization.lua"/>
        <Frame name="zBar" parent="UIParent">
                <Scripts>
                        <OnLoad>
                                zBar_OnLoad();
                        </OnLoad>
                        <OnEvent>
                                zBar_OnEvent(event);
                        </OnEvent>
                </Scripts>
        </Frame>
</Ui>
Ui标签是最上级标签。其中的schema用来语法检查,对我们来说用处不大。可以简化为:

<Ui xmlns="http://www.blizzard.com/wow/ui/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
</Ui>

或者更加简化,不太规范但是可用:
<Ui></Ui>
Script标签:在Ui标签中最先包含的往往是<Script file="lua file name"/>表示在此处载入某lua文件,注意这里也有顺序哦,如果发现变量、函数不存在,检查一下看是不是顺序问题。

QUOTE:
  这样一来我们有了两种方法载入lua文件。xml中载入lua实际上不是非如此不可的,有时候没必要用xml的就直接在toc
  中放个lua,把xml省掉。注意:这样做你必须在lua中有个入口,也就是有个裸语句(不在任何function中的)进行事件
  注册或者调用函数。
Frame标签:XML中最主要的一个标签是<Frame></Frame>。所谓Frame意指框架,就是用来包含其他东西的。
UIParent是最上层的框架,所有的UI都包含在其中。与之并列的是一个特殊框架WorldFrame,包括FPS、截图。

控件也是框架,如:<panel> <button> <slider> <statusbar> 等等。据我观察,控件和框架是一样的,都包含类似的属性和子标签:背景、贴图、边框、事件处理。

子标签和属性:

QUOTE:
<Frame name="名称,唯一" inherits="myFather继承" toplevel="true等级" parent="UIParent父标签" movable="true可移动" enableMouse="true允许鼠标事件" frameStrata="HIGH层级" hidden="false隐藏" id="编号">
        <Size> --大小
                <AbsDimension x="" y=""/> --绝对尺寸
        </Size>
        <Anchors> --锚点,用来标记相对位置
                <Anchor Point="本控件的参考点" relativeTo="参考控件" relativePoint="参考控件的参考点">
                        <Offset> -- 偏移值
                                <AbsDimension x="" y=""/>
                        </Offset>
                </Anchor>
        </Anchors>
        -- 背景和边框
        <Backdrop name="$parentBackdrop" bgFile="背景贴图" edgeFile="边框贴图" tile="不知道">
                <EdgeSize>
                        <AbsValue val="18"/> -- 边框缩放大小
                </EdgeSize>
                <TileSize>
                        <AbsValue val="16"/>
                </TileSize>
                <BackgroundInsets>
                        <AbsInset left="5" right="5" top="5" bottom="5"/> -- 背景四周留白
                </BackgroundInsets>
        </Backdrop>
        <Layers> -- 分层,主要放置贴图材质和字符
                <Layer level="BACKGROUND"> -- 背景层
                        <Texture name="$parentRed" file="贴图" hidden="true"/>
                </Layer>
                <Layer level="ARTWORK"> -- 艺术层
                        <FontString name="$parent名字" inherits="Font" justifyH="CENTER"/>
                <Layer level="OVERLAY"> -- 覆盖层
                        <Texture name="$parentShine" file="贴图" alphaMode="ADD透明模式" hidden="true">
                                <Anchors>
                                        <Anchor point="CENTER"/>
                                </Anchors>
                        </Texture>
                </Layer>
        </Layers>
        <Frames>-- 嵌入其他框架
        </Frames>
        <Scripts>
                <OnLoad>载入事件处理</>
                <OnEvent>用RegisterEvent注册过的事件处理</>
                <OnUpdate>更新事件</>
                <OnShow>显示事件</>
                <OnHide>隐藏事件</>
                <OnClick>单击事件</>
                <OnDoubleClick>双击事件</>
                <OnEnter>鼠标进入</>
                <OnLeave>鼠标移出</>
                <OnDragStart>拖放开始</>
                <OnReceiveDrag>接受拖放</>
                <OnValueChanged>值改变(用于Slider滑块)</>
        </Scripts>
</Frame>
inherits和parent的区别
inherits  继承,表示本控件未标明的属性全部继承自某某控件(包括事件处理脚本)。
parent   父控件,表示依存关系,如果父控件隐藏了那么子控件也会隐藏。

Anchor锚点中的定位规则
Point              自身参考点
relativeTo       参考控件
relativePoint   参考控件参考点

比如一个正方形的按钮,<Anchor Point="LEFT" relativeTo="$parent" relativePoint="RIGHT"/>
意思就是说:我的左边对父控件的右边。效果就是按钮始终在父控件的右边。


UI对象的继承关系
UIObject:始祖,所有其他UI对象都由它继承。
LayoutFrame:布局框架,继承UIObject,主要有一些布局函数,(这是一个虚类不可创建实例)。

QUOTE:
LayouFrame的重要函数:GetParent() SetParent() GetAlpha() SetAlpha() SetWidth() SetHeight()
IsShown() 和 IsVisible()的区别
IsShown():是否显示,表示一种属性:如果父对象可见的时候是否会显示。
IsVisible():是否可见,表示当前状态:当前对象在屏幕上有没有显示。
Frame:框架,继承LayoutFrame,最重要的UI对象,屏幕上可见的UI对象都是它的子类,一般用来在上面放置其他控件。

QUOTE:
Frame的子类
Button:按钮。
EditBox:可编辑文本框。
GameTooltip:鼠标提示
ColorSelect:颜色选择器
MessageFrame:信息框架
Minimap:迷你地图,小地图、战场地图等
Model:模型,用于显示3D动画。人物模型,冷却都是Model
MovieFrame:影像框架,放电影的。。。不知道怎么用
ScrollFrame:可滚动框架
ScrollingMessageFrame:滚动信息框架,例如聊天窗口、战斗信息窗口
SimpleHTML:简单超文本标记语言,应该是类似网页的可定义字体大小颜色式样、带图片的文本
Slider:滑快,像系统设置中的UI缩放那个滑快
StatusBar:进度条,像是施法条,血条等等
 楼主| 发表于 2007-5-10 11:19:13 | 显示全部楼层
Lua语言

先给几个链接:Lua脚本语言入门, 魔兽Api索引

如果你有一门以上的语言基础,那么学习lua语言不是什么难事。

lua是一种灵活的语言,关于他的来源我并不知道多少,只谈一下自己的感受。基本语法和Basic类似,或者说更像是Asp的脚本语言吧。但同时他又借鉴了Java的长处,更加的智能化、灵活。写法多样又方便不同习惯的人上手。

lua语法很简单,相关资料也很多,我只列出需要注意的部分。

行注释符号:“--”
段注释符号:“--[[”  “]]--”
行结束符号:用“;”或者不写都行,看你的习惯了,只要没有歧义就好

NULL空值:在这里是nil
   没有指针:和Java一样,没指针的意思就是所有变量都是引用。要注意不是拷贝的副本,改变引用变量原始便量会同时改变。
变量作用域:默认是global(全局作用域),加上local前缀就是局部的了(文件内部作用域)。
函数作用域:和变量一样。实际上函数也是变量。
数组,集合:只有一种,类似于。。。我也不知道类似什么。写法也很随意,举例:
Config = {
    attribute1 = "apple",
    attribute2 = false,
    ["attribute3"] = "animal",
    [1] = "Button1",
    ["2"] = "Cool",
}
关于数组的就看上面的“Lua脚本语言入门”,讲的很清楚。

关于布尔变量
要注意的是只有nil和false表示false,其他一律为true(包括0),
而false是要占用引用内存的,建议把false一律换成nil。

关于布尔运算
lua里的布尔运算是很有趣的,也相当合理。注意运算的值并不是布尔值,而是其中一个操作数的值。
x = a and b; 与运算,a为false则x等于a,a为true则x=b。
x = a or b; 或运算,a为true则x等于a,a为false则x = b。
是不是有点晕?其实很合理。如果你一时绕不清楚,就只要记住结果好了。

我坚定地认为lua中的布尔运算实际上不是布尔运算,而是简化了的条件语句。比如:

QUOTE:
x = a and b;  --相当于:
if (not a) then
  x = a;
else
  x = b;
end

x = a or b;  -- 相当于:
if (a) then
  x = a;
else
  x = b;
end

-- 还有一种简化,常用于变量的初始化
x = x or a;   -- 相当于:
if ( not x ) then
  x = a;
end
对象
在lua里,框架和控件都作为对象存在。
要引用在XML中定义的框架或控件,使用如下语句:
frame = getglobal("FrameName");

对象的属性
属性在对象中就像集合成员一样,属性引用符号为:“.”,
例如:frame.attribute1

QUOTE:
对象实际上就是一个特殊集合!!
对象的属性同样可以用集合方式引用: frame["attribute2"]
函数调用也是一样,见下面说明。
对象的函数
函数在对象中有些特别,调用符号为冒号:“:”
例如:frame:Show();

QUOTE:
函数实际上是一种特殊变量,指向一段代码。
更一般的调用符号和一般的对象属性相同,为“.”。
而特殊符号“:”实际上是在调用的时候多加了一个参数“self”,指代调用者本身。
例如: Frame1:SetAlpha(0.5) 相当于 Frame1.SetAlpha(self, 0.5)
函数定义
类似Basic,例如:
function add(a,b)
  local ret = a + b;
  return ret;
end

QUOTE:
函数定义实际上是把一个变量指向一段代码。前面举的例子含义是:把变量add指向一段函数代码。
因此,我们可以很方便的覆盖(Override)Blizzard的系统函数,只要把系统函数变量指向自己定义的函数代码就可以了。
以覆盖上面的add函数为例,有几种方法:
-- 1. 把原函数变量指向新的函数代码段
old_add = add;  -- 保存原始的add指向的函数
add = function(a,b)   --  add 指向新的代码段
  if ( old_add(a,b) == 0 ) then return nil end
  return a + b
end
-- 2. 直接定义一个同名函数
function add(a,b)   -- 含义与第一种方法相同:改变add的值,使它指向新的代码段
  local ret = a + b
  if ( ret == 0 ) then return nil end
  return ret
end
函数的默认参数
有一些函数参数比较特殊:对象事件处理函数,有一些有默认参数,例如
OnClick OnMouseDown OnMouseUp  -  默认参数 arg1
OnEvent  -  默认参数event
所以在定义这些函数的时候可以不写参数:
function zOnClick()
  if ( arg1 == "LeftButton" ) then
      doSomething()
  end
end
但是要注意:如果函数定义里写了参数,那么调用函数的时候一定要写参数!!!!否则认为参数为nil。例如
<OnClick>if ( not this.lock ) then zOnClick(arg1) end</OnClick>

之所以有默认参数存在是因为在动态改变事件处理函数的时候不能写参数,例如
button:SetScript("OnClick", zOnClick)

考察默认参数的原理应该是:
对象触发事件时会调用对应函数,这时是有参数的,一般为公认的默认参数,例如:
<OnClick>zOnClick()</OnClick>
WoW虚拟机处理的时候,当事件触发,会调用
Object:OnClick(arg1)
其函数体就是上面XML代码定义的zOnClick()
function Object:OnClick(arg1)
    zOnClick()
end
到zOnClick()执行的时候,因为没写参数,原始的参数arg1没有改变,
而且zOnClick()被包含在Object:OnClick(arg1)的作用域中,也就是说arg1可以被访问
因此就好像是有默认参数在起作用了。

更正:其实这些所谓默认参数,是一些全局变量,在事件处理函数中被赋值

 楼主| 发表于 2007-5-10 11:19:27 | 显示全部楼层
工具介绍

WoW UI Designer
这个是首先必备的咚咚,用来看Blizzard的源代码,寻找可用的模板,很实用!!

注意:这个需要.net Framework支持,否则无法运行!

WoW SciTe LUA
编辑lua的利器,我一直在用,语法高亮,函数提示。字体、颜色也不错。
1.10最新API文件见:WoW SciTe 1.10全部函数事件代码提示

Ultra Edit 10.10
高手都用它,强大的文本编辑工具,支持多种语言高亮。用10.10或者11.00,不要用12.00新版,启动速度慢了不少,常用的功能还就是那些。
1.10语法高亮见:UltraEdit 1.10全部函数事件语法高亮
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-5-6 14:57

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表