用C#+XML技术开发游戏Sokoban Pro
http://tech.ddvip.com 2006年08月02日 社区交流
本文详细介绍用C#+XML技术开发游戏Sokoban Pro
下面是所发生的事情:
我们使用XPath来选择在一个XML文件中的结点。这样,我们不必逐行读取XML,直到我们在我们想要添加一新的元素或更新现有的一个元素的地方找到正确的元素。见下面一行:
XmlNode setName = doc.SelectSingleNode("/savegame/levelSets/"+"levelSet[@title = \"" + level.LevelSetName + "\"]");
选择我们当前玩的级别的级别集合结点。(记住,Sokoban Pro支持多个级别集合,因此在XML中可能有多于1个的级别集合)。然后,请看下面一行:
XmlNode nodeLevel = setName.SelectSingleNode("level[@levelNr = "+ level.LevelNr + "]");
从当前级别集合中选择我们正在玩的级别数。
如果我们没有找到当前级别结点,这意味着我们在前面没有完成这个级别而我们添加一新的级别结点。如果我们的确找到了级别结点,这意味着我们在前面已经玩完了这个级别并且我们检查是否我们的当前得分更高些。而如果是这样,让我们更新得分。
该游戏大量使用读取和写XML文件,并且如你看到的,使用了Xpath作为一个强有力的工具。
我想说明的另外一件事情是我是怎样加载级别的。我已经说过,我们把级别存储在XML中。一个级别包含不同的项:一个墙,一个地板,一个箱子,等等。当我们加载一个级别时,我们读取XML中的行-该XML中包含级别数据。一个级别中的每一项是以一个ASCII字符来描述的。当我们读取级别数据时,我们把项存储到一个二维数组中。
在我们想绘制该级别时,我们读取这个数组,然后我们就可以如下方式进行级别绘制:
//绘制级别
for (int i = 0; i < width; i++){
for (int j = 0; j < height; j++){
Image image = GetLevelImage(levelMap[i, j], sokoDirection);
g.DrawImage(image, ITEM_SIZE + i * ITEM_SIZE, ITEM_SIZE + j * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE);
//设置Sokoban的位置
if (levelMap[i, j] == ItemType.Sokoban || levelMap[i, j] == ItemType.SokobanOnGoal){
sokoPosX = i;
sokoPosY = j;
}
}
}
我们逐行逐字符地读取数组。根据我们遇到项的不同情况,我们得到一个从GetLevelImage方法返回的图像-该方法检查我们拥有哪一项并且返回相应的图像。最后,在已知项的位置、宽度和高度的情况下,我们绘制图像。大小被存储在ITEM_SIZE变量中。如果我们想要把级别绘得更小些(也许针对低分辨率的监视器),我们可以减少ITEM_SIZE的值(默认是30)。
另外一个有趣的地方是检查是否允许Sokoban移动。只有他前面的项是一个空的位置或者是一个后面是空的位置的盒子时,他才能移动。当他移动时,我们用三个独立的项对象存储盒子,Sokoban留下的空位置以及Sokoban的新位置,并且我们使用这些对象来重绘这个级别的这三个项,而不是重绘整个级别。对于恢复最后推动作的情况,也是相同的实现方式。
来源:天极开发 作者:朱先忠 责编:豆豆技术应用