创建模块化游戏的步骤
Creating Moddable Games with XML and Scripting Part I
作者:
In this short series of articles, I will explore in how XML and scripting can be combined and used to create modifiable content for games. Game modification is nothing new, being popularised by titles such as Quake 2 and Half-Life. However, despite its popularity there seems to be a lack of articles discussing how to mod-enable your own games. With this series of articles I will explore the use of a JavaScript environment combined with XML to store your game data to allow you to mod-enable your own games.
Roadmap for the series
This series will span the development of a small game, "jsInvaders" and focus solely upon creating and embedding the script and XML parsing interfaces that serve as a facility to modify (mod) the content and behaviours within the game.
To follow this series, I am assuming that you have knowledge of C++, OpenGL and understand the principles of game creation. This series is not a game creation tutorial, so I will not be focusing on normal game aspects such as graphics, sound, game logic, et al. Here's a brief outline of how you can expect this series to progress:
-
Part I
Serves as an introduction to the series; briefly explains what XML is and discusses the use of XML in games. Introduces TinyXml, a small open-source XML parser and shows you how to use it for parsing the basic data required by the game.
-
Part II
A brief introduction to JavaScript (using the Mozilla "SpiderMonkey" engine). Discusses the development of a scripting API and how to write the 'glue' code that sits between the game and the scripting engine.
-
Part III
Brings the series to a close with expansion of the basic scripting API developed in Part II and discusses how to develop a Game Object Model to effectively link XML with your scripted components.
Brief Introduction to XML
XML的简要介绍:
Now that you understand where this series will be headed, I will now introduce you to the basics of XML documents. After reading this section, you should understand exactly what XML is, how to create it and be thinking of ways you can apply XML to your games. I suggest that you read Richard Fine's "XML in Games" available on GameDev.net, as it serves as an excellent introductory text on the subject.
现在你知道这个系列的教程开头会讲什么,我现在要向你介绍基本的XML文档。读完这一小节过后,你应该完全明白XML是什么,以及如何创建它,并以模块化的思维把它应用到你的游戏中去。我建议你先读一下 Richard Fine 在GameDev上的<XML in Games>一文,它对这一节里我要说的话题进行了很精彩的描述。
The XML document specifications require each valid document to begin with an XML file declaration:
XML规范描述每一个有效的XML文件都由一个XML文件声明开头:
<?xml version="1.0" encoding="utf-8"?>
Quite simply, this declaration is stating that the document is XML version 1.0 and is encoded with the UTF-8 character set.
非常简单,这个声明描述了这个XML文件遵循XML规范1.0版,并且使用UTF-8编码。
XML is a meta-language; in short you are able to define your own set of tokens (or 'tags'), rules and structures. Most XML files are defined by a DTD, or Document Type Definition which dictates the rules and structure of the document by supplying a list of legal tokens. DTD rule creation is important as it allows the XML parser to quickly accept or reject documents on loading. With that said, we are using TinyXml and it is a non-validating parser; it will ignore any DTD it finds and just processes the document elements with no rules. This is fine for our purposes as we can build our own validation rules into the parsing stage.
XML是一种元语言;简单地说你可以使用它来定义你自己的标记(它是一种标记性语言),规则以及结构体。大多数XML文件由DTD来定义,DTD是Document Type Definition的缩写,DTD用来检测XML文件是否规范,标记是否正确。DTD的创建规则可以让XML分析器很快地进行正确地分析。根据这样的说法,我们决定使用TinyXml,TinyXml就是一种XML分析器,它不处理DTD,它对XML进行分析时不依照任何DTD的规则(实际上忽略了DTD)。
XML documents have a strict hierarchical structure; elements are contained within other elements, which in turn are contained within higher elements in the document tree. This tree-like structure needs a root, the document root, and is the single element which all other elements are descended from. Every element on the next hierarchical level is called a child of an element and elements with the same root element are said to be siblings.
XML文件拥有很严格的层次结构;元素被其他元素包含,其他元素又被更高层次的元素包含。XML文件里的元素是以树型结构组织的。这个树的根部就是文档(XML文档本身)。在树型层次中,低一层的元素是其高层元素的孩子,高层元素就是其父母;拥有相同父母的元素就是兄弟。(与树数据结构一样)
The hierarchical structure of XML allows for easy parsing of the tree and can introduce great flexibility when it comes to manipulating the data. Whole branches can be detached and placed elsewhere with little difficulty.
XML的树型结构使得分析起XML文件时很容易,且在操作数据时也很方便。整个层次结构中的任一分支都可以很容易地被方在任何地方。
Let's take a look at a basic declaration of a jsInvaders level:
让我们看一下jsInvaders层次的定义:(作者在这一系列教程中,将开发一个名为jsInvaders的示例游戏)
<?xml version="1.0" encoding="utf-8"?>
<invadersgame>
<level>
<alien />
<alien />
<alien />
</level>
</invadersgame>
You should be able to see that the document root element is <invadersgame>. The root then contains a level element, which in turn contains three alien elements. In order to clarify this, I'll break down the basic jsInvaders level document:
你应该可以看到,文档元素(最顶层的元素,也就是根元素)就是<invadersgame>,然后根元素包含了一个 level 元素,这个 level 元素又包含了三个 alien 元素。为了更为清晰地说明这一点,我把以上文档分开来说:
-
<invadersgame> is the document root <invadersgame>是文档根元素
-
<level> is a child of <invadersgame> <level>是<invadersgame>的一个孩子。
-
<alien> is a child of <level> <alien>是<level>的孩子。
-
The <alien> elements in a <level> element are siblings to each other
<level>包含的每一个<alien>是其他<alien> 的兄弟。
If you're used to Object Oriented Programming (OOP), then you'll probably be able to picture how you'd map these elements into classes. By referring to the code attached to this article, you'll see how I've begun mapping these objects into C++ classes for use in the game. So far in the code I have the game classes sketched out for dealing with levels, aliens and the player ship. I won't go into detail about much of the rest of the game classes as it is beyond the scope of this article.
如果你习惯了面向对象编程,那么很有可能你会把上面那种结构抽象为类结构。在这篇文章里,我就是把这样的结构对应地抽象为C++类的。我已经有了对应于level, alien 以及 player的类。在这个教程里,我不会讲太多游戏编程方面的东西,那不在本教程讨论的范围内。
If you examine the file jsiAlien.h, you'll see that I have defined several properties for the object. Things like 'color', 'position' and 'points value' are all properties of the Alien object that will need values to be of use in the game. XML document elements can also have attributes assigned to them, meaning that you can represent the data for objects such as the Alien object with an XML element tag.
如果你查看 jsiAlien.h 这个文件,你就会看到我为一个类定义了很多属性。颜色,位置,以及会给玩家多少分数都是游戏中 alien 对象需要的属性。XML文件的元素也可以拥有属性,这意味着你可以把游戏中alien对象的属性设置进XML文件对应的元素中去:
<alien xpos="0" ypos="100" color="red" points="10" />
If you look at the declaration above you will see that I have assigned 4 properties to the XML element that represents the Alien. In this example the alien is red, is positioned at (0, 100) and awards 10 points to the player when killed. Taking this forward, we begin to build the XML file that defines a basic game level.
你会看到以上定义中我为XML元素alien分配了4个属性。在这个例子中,alien是红色,位置在(0,100)处,而且当被玩家杀死后它会给玩家奖赏10点分数。我们来定义一个基本的游戏关卡:
<?xml version="1.0" encoding="utf-8"?>
<invadersgame>
<level>
<!-- here's where we declare the aliens -->
<alien xpos="0" ypos="100" color="red" points="10" />
<alien xpos="100" ypos="100" color="green" points="10" />
<alien xpos="200" ypos="100" color="blue" points="10" />
</level>
</invadersgame>
It should be apparent that we now wish to have 3 aliens of different colours, each 100 units apart horizontally. You'll notice that I've begun commenting my XML document with the XML comment tags, <!-- this is a comment -->. I personally find commenting all of my code to be good practice, even in this simple example :). The benefits of good commenting will reveal themselves later on when the files start getting bigger.
很显然,我们在这个文件里希望有3个alien,每一个拥有不同的颜色,且在横坐标上相隔100个单位。在这个文件里我加入了注释<!-- this is a comment -->。我个人觉得加入注释是很好的习惯。
Parsing the XML
分析XML
Now that you understand the concept of XML and how document elements relate to the data contained within class objects, I will take you through the process of parsing the XML document. The act of 'parsing' is when the raw document is read in by your program and transformed into the elements that make up the document tree. With jsInvaders, the parsing stage will consist of reading the XML document into memory and creating objects within the game environment based on the data within it.
现在你已经知道了XML的基本概念,并知道XML中的元素如何对应着C++中的类,我将要告诉你如何去分析一个XML文件。分析也就在你的程序中读进XML文件,然后得到其内表达的树型结构。在jsInvaders里,程序需要先把XML文件读进内存,然后设置游戏相关数据。
For this section you will require an XML parser; I am using TinyXml, a small open-sourced library that was developed for easy handling of XML documents. Bear in mind that there are several XML parsers available which all follow the basic concepts, so pick one you feel comfortable with if you don't wish to use TinyXml.
在这一节里,你需要个XML分析器;我使用TinyXml,它是一个小巧的并且开源的XML分析库。记住其实有很多XML的分析器,如果你不喜欢TinyXml,你完全可以使用你自己喜欢的。
With TinyXml, all of the elements are contained within a TiXmlDocument structure. The first thing you need to do is create an instance of this object and use it to load and parse the XML file. This is shown in the code fragment below (taken from jsiGame.cpp):
使用TinyXml,所有的元素都被包含在一个TiXmlDocument的结构体中(其实是一个类,但是基本一样)。你需要做的第一件事情就是创建一个该类(TxXmlDocument)的对象,然后使用它装载一个XML文件并分析。以下是示例代码(选自jsiGame.cpp):
int jsiGame::loadXmlLevels(const char *filename)
{
TiXmlDocument *xmlDoc = new TiXmlDocument(filename);
if (!xmlDoc->LoadFile())
{
// Fatal error, cannot load
return 0;
}
// Do the document parsing here
xmlDoc->Clear();
// Delete our allocated document and return success ;)
本文地址:http://www.45fan.com/dnjc/70614.html