向WoW学习游戏设计(1)
2010-11-29 15:41 凌云健笔 阅读(788) 评论(0) 编辑 收藏 举报当一种艺术形式形成一种现象的时候,我们就可以认为它已经超越了本身,无论这种艺术是小说,是电影,还是被一些人视为“洪水猛兽”的游戏。史诗级的WoW就是一个很好的例子。WoW作为一个游戏所具备的厚度和深度开始得到更多人的认同,游戏不是玩物丧志,游戏并不只是游戏,游戏里也有很多可以学习和挖掘的东西。相较于其他的一些游戏,暴雪喜欢在自己的作品里给玩家提供了更多的自由度;在WoW里暴雪开放了API调用接口,玩家可以自由开发各种有用的插件,玩家可以充分发挥自己的创造力去创造有趣的游戏元素。
理论上,插件只是放在WoW游戏文件夹里的一些文件,应用它们增强玩家在WoW世界中的人机交互功能;换句话说,就是帮助你简化游戏操作,辅助你获得更多游戏信息。从这个意义上说,游戏增强程序(modification)就是一种插件(AddOn),游戏增强程序就是一个用来改变或者增强WoW游戏界面外观的第三方插件。插件接口的开放,极大的促进了WOW的繁荣,吸引了一大批热衷开发,热衷创造的高端玩家进入游戏,这些玩家丰富了WOW的玩家群体,也使得WOW的玩家群体比起其它网游更加地精英化。同时,这些插件开发爱好者们开发的众多插件使得其它玩家能更好的体验WOW,保证了游戏的人气。
古人云,只有爬到巨人的肩膀上,俺才能看得更远。所以,要做出好游戏,就必须研究这个史诗级的游戏WoW,当然包括但是不是只包括俺所关注的程序设计这一方面。
用Google百度了一下相关的资料,有用的结果不是很多,更不用说用着较为方便的中文资料。遂花了近百大元买了《魔兽世界编程宝典:World of Warcraft Addons完全参考手册》(英文原版名字为《World of Warcraft Programming: A Guide and Reference for Creating WoW Addons》,作者为James Whitehead II、Bryan McLemore、Matthew Orlando)。大略地翻阅了以下,感觉并非自己原来期待的那样精彩有收获,它只是简单地着笔与插件的设计,解释WoW开放的那些API们,是“参考手册”,但绝非“编程宝典”;(World of Warcraft Programming中也没有那个词对应“宝典”二字啊,轻轻的鄙视一下译者)它缺少了对插件系统设计原理的阐述,估计暴雪的大牛们也不想拿出来分享。
一个能够正常运行WoW插件必须放在插件目录"{WoW_install_Dir}\Interface\AddOns\ AddOnDemoName \"下,一般由三个文件组成:
一个名为"<AddOnDemoName>.toc"的文件:
.toc 是 "table of contents"的缩写。这个文件应该包含以下两点内容:包含正确插件版本号的插件关键字,以及需要加载的文件清单。暴雪要求你的文件至少包含以下三行客户端识别标志:
## Interface: 20400 (版本控制)
## Title: My Add On(确认插件名后没有额外的空格)
## Notes: A short description of my AddOn
客户端通过toc文件对设计的插件进行加载。小退,.toc文件不会重新加载。如果你对这个文件作了修改,只有重新启动游戏这个修改才会生效。
示例:
## Interface: 30200
## Title: WowDemo01
## Author: 凌云健笔
## Version: 1.0
## Notes: A Wow UI Demo
## eMail: lijian8409@gmail.com
## DefaultState: Enabled
## LoadOnDemand: 0
##SavedVariables:
WowDemo01Form.xml
WowDemo01.lua
XML文件:
XML是一种可以构建图形框架的语言,用以描述定义用户界面。这个文件是非必须,当用Lua动态的创建窗口时,此文件可不用。
示例:
<Ui xmlns="http://www.blizzard.com/wow/ui" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!--Autogenerated by wowuides, Version=1.0.300.0, Culture=neutral, PublicKeyToken=null-->
<Frame name="WowDemo01Form">
<!--<FrameSkin skinid="dcb143e1-a4ab-4e7c-b934-1efa40101d21" frameid="2d508883-59c2-4f83-ae10-27aaad48391b" />-->
<Size>
<AbsDimension x="400" y="400" />
</Size>
<Anchors>
<Anchor point="CENTER" relativeTo="UIParent">
<Offset>
<AbsDimension x="0" y="0" />
</Offset>
</Anchor>
</Anchors>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
<BackgroundInsets>
<AbsInset left="11" right="12" top="12" bottom="11" />
</BackgroundInsets>
<TileSize>
<AbsValue val="32" />
</TileSize>
<EdgeSize>
<AbsValue val="32" />
</EdgeSize>
</Backdrop>
<Layers>
<Layer>
<Texture name="$parentTitleBorder" file="Interface\DialogFrame\UI-DialogBox-Header">
<Size>
<AbsDimension x="160" y="32" />
</Size>
<Anchors>
<Anchor point="TOP">
<Offset>
<AbsDimension x="0" y="5" />
</Offset>
</Anchor>
</Anchors>
<TexCoords left="0.2" right="0.8" top="0" bottom="0.6" />
</Texture>
<FontString name="$parentTitleString" font="Fonts\ZYKai_T.TTF" text="Welcome">
<Size>
<AbsDimension x="140" y="0" />
</Size>
<Anchors>
<Anchor point="TOP">
<Offset>
<AbsDimension x="0" y="-4" />
</Offset>
</Anchor>
</Anchors>
<FontHeight>
<AbsValue val="15" />
</FontHeight>
<Color r="1" g="0.8196079" b="0" />
<Shadow>
<Color r="0" g="0" b="0" />
<Offset>
<AbsDimension x="1" y="-1" />
</Offset>
</Shadow>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="OKButton" text="OK">
<!--<FrameSkin skinid="dcb143e1-a4ab-4e7c-b934-1efa40101d21" frameid="2d508884-59c2-4f83-ae10-27aaad48391b" />-->
<Size>
<AbsDimension x="158" y="45" />
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="124" y="-305" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>WowDemo01Form:Hide();</OnClick>
</Scripts>
<NormalTexture file="Interface\Buttons\UI-Panel-Button-Up">
<TexCoords left="0" right="0.625" top="0" bottom="0.6875" />
</NormalTexture>
<PushedTexture file="Interface\Buttons\UI-Panel-Button-Down">
<TexCoords left="0" right="0.625" top="0" bottom="0.6875" />
</PushedTexture>
<DisabledTexture file="Interface\Buttons\UI-Panel-Button-Disabled">
<TexCoords left="0" right="0.625" top="0" bottom="0.6875" />
</DisabledTexture>
<HighlightTexture file="Interface\Buttons\UI-Panel-Button-Highlight" alphaMode="ADD">
<TexCoords left="0" right="0.625" top="0" bottom="0.6875" />
</HighlightTexture>
<ButtonText name="$parentText">
<FontHeight>
<AbsValue val="10" />
</FontHeight>
</ButtonText>
<NormalFont style="GameFontNormal" />
<HighlightFont style="GameFontHighlight" />
<DisabledFont style="GameFontDisable" />
</Button>
<Frame name="$parentLabel1">
<!--<FrameSkin skinid="f15d4970-d66d-444e-bb2d-1ad102c87fed" frameid="f15d4978-d66d-444e-bb2d-1ad102c87fed" />-->
<Size>
<AbsDimension x="293" y="70" />
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="52" y="-103" />
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer>
<FontString name="$parentLabel" setAllPoints="true" font="Fonts\FRIZQT__.TTF" text="Hello, I am from China!">
<FontHeight>
<AbsValue val="12" />
</FontHeight>
<Color r="1" g="0.8196079" b="0" />
<Shadow>
<Color r="0" g="0" b="0" />
<Offset>
<AbsDimension x="1" y="-1" />
</Offset>
</Shadow>
</FontString>
</Layer>
</Layers>
</Frame>
</Frames>
<Scripts>
<OnLoad>this:RegisterEvent("VARIABLES_LOADED");</OnLoad>
<OnEvent>WowDemo01Event()</OnEvent>
</Scripts>
</Frame>
</Ui>
Lua文件(非必须):
一般用于定义插件的行为。当然也可以用Lua动态的创建窗口。
示例:
--[[ 随意的定义自己的响应函数 ]]--
function WowDemo01Event(arg)
DemoText = {}
end
自己动手,做一个插件:(应用工具Wow UI Designer)
Step1:打开Wow UI Designer,新建工程WoWDemo01,添加toc:
Step2:添加界面 WoWDemo01Frame.xml,Wow UI Designer提供了类VS的控件设计方式,方便。
针对OK Button控件设置事件相应,在控件属性栏OnEvent项输入响应函数。
Step3:添加Lua文件
因为本例中没有涉及复杂的事件处理,所以此文件可以不添加。但是为了完整的演示插件设计过程,添加WoWDemo01.lua文件。
打开WoW,进入游戏世界,你会发现刚刚设计的插件出现在了你的游戏界面中,如图所示:
WoW客户端支持动态重新载入UI。如果在游戏进行过程中修改了XML和Lua文件,只需在游戏中输入/script ReloadUI();命令即可重新载入UI。如果客户端在载入过程中发现语法错误,你只需修改错误并重新载入界面,即可继续正常游戏。如果脚本中出现错误,你又无从下手的话,就用message()函数显示各个变量。对话框的出现并不停止脚本的执行,但在你点击确定前,其它message()产生的对话框不会显示。
猜测一些其设计原理:
当一个框架,材质,或字符串在XML中被定义后,它们将会被作为相应类型对象加入Lua命名空间。每类对象都有专门用来修改该类对象的成员函数。每一个框架都有在指定情况下被调用的脚本处理器。例如在框架载入后立即被调用的OnLoad处理器;每次世界被更新都会被调用的OnUpdate处理器;每次框架被显示时都会被调用的OnShow处理器。还有处理游戏世界事件的OnEvent处理器。
在加载UI过程中,每个框架都注册了它们相应的事件,客户端会生成相应的 <事件> - <处理器> 对应关系表。在游戏过程中,每当有事情发生之后,游戏世界就会产生一个事件。而不是直接调用界面,这样使得游戏世界本身对界面的依赖性极小。当那些事件发生之后,通过对应关系表,相应框架的处理器会被调用,这样也就实现了游戏本身与UI交流。
作者: 凌云健笔
出处:http://www.cnblogs.com/lijian2010/
版权:本文版权归作者和博客园共有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任