我正在处理游戏对话文件(玩家和不可玩角色之间的对话),其中对话选择及其结果取决于某些条件并导致某些操作。现在,我可以编写一个简单的解析器来处理某种语言来指定前后条件,但我的一个朋友建议使用XML。条件可以存储为对话元素的属性,选择和动作是内在元素。然后我会使用eval函数来解析这些条件和语句(我使用Ruby来制作这个游戏)。为了使这种方法更简单,我可以编写一个简单的GUI来操纵这些文件,而不用担心丑陋的XML。
但是,它使我成为处理XML文件逻辑的奇怪选择。我的理解是,XML文件用于存储和交换数据,我总是看到关于人们如何过度使用XML的各种不适合的事情。我的朋友们通过注意XML是如何用于所有内容的,包括XHTML和this bullet description language(也说明了一些逻辑)。
说实话,使用XML可以为我简化很多事情。编写解析器可能是痛苦和耗时的,我的要求通常很简单。但是真的好还是后来我会后悔这样的选择?
对于对细节感兴趣的人,以下是XML文件中的基本对话交换:
<dialogue id="101" condition="!npc.carsFixed"> <message>Man,fix my car!</message> <choices> <choice condition="hero.carFixingSkill > 5" priority="7" id="Sure!"> <command>hero.carFixingSkills += 1</command> <command>npc.carFixed = true</command> <command>hero.playSmokeAnimation()</command> <command>nextDialogue = 104</command> </choice> <choice condition="hero.carFixingSkill <= 5" id="I can't..."> <command>nextDialogue = 105</command> </choice> <choice id="Fix it yourself"> <command>npc.likesHero -= 1</command> </choice> </choices> </dialogue>
用Ruby编写的相应代码将是:
def dialogue101 if !npc.carsFixed showMessage("Man,fix my car!") choices = [] if hero.carFixingSkill > 5 choices.push(Choice.new("Sure!",7)) else choices.push(Choice.new("I can't")) end choices.push(Choice.new("Fix it yourself")) choices = selectTopPriority(choices) if choices.size > 4 result = showChoices(choices) case result when "Sure" hero.carFixingSkills += 1 npc.carFixed = true hero.playSmokeAnimation dialogue104 when "I can't" dialogue105 when "Fix it yourself" npc.likesHero -= 1 end end end
像Hero和carFixingSkills这样的东西就是知识点播放器和NPC可以拥有的,这可能会被存储在真正实现中的哈希中。我发现对话文件的方法更加灵活,因为我可以使编辑器轻松编辑对话和条件/动作,并且由于游戏对话树的复杂性质。像Ruby或Lua这样的脚本语言有助于,但它需要复杂的结构来处理这些树的逻辑。
回到原来的问题,XML是工作的正确工具还是我缺少的东西?