为 XNA 游戏实现简单的基于 XML 的脚本语言
我正在与一个团队合作使用 C# 和 XNA 开发 RPG 引擎。我们计划以 Windows 和 Windows Phone 7 为目标,但在过场动画期间遇到了 AI 交互和控制玩家操作的问题。大多数情况下,所有内容都是使用 MVC 设计模式提取的,但将所有逻辑和运动抽象到控制器中可能会导致问题。因此,我们的想法是拥有一个接口(IScriptEngine),它接受 IScriptObject 并相应地更新地图模型中的数据。 我正在考虑将脚本放入 XML 类型的语法中:
<Script Name="MoveNPC_1">
<Action Command="MoveToTile" Target="NPC_1" Value="10,2"/>
</Script>
并让 IScriptEngine 相应地解析它。我非常怀疑解析一个巨大的 switch 语句是否是一个好主意,但这就是我一直在研究的。
switch(Action.Command)
{
case "MoveToTile":
{
doMovement(Action.Value, Action.Target);
break;
}
}
甚至我的高中编程经验也告诉我这是一个坏主意,但我想不出任何其他方法。
编辑: 我想以某种方式将这一切嵌入到地图文件中。在地图 XML 文件中,我们指定了 的区域,其中包含多个标签。然后会有一个部分,指定 NPC 在地图上的位置,以及它将使用哪些资源和脚本。然后会有一个部分,其中将定义所有战斗(再次定义资源和其他内容),然后可能还有一个部分,其中将定义这些脚本。我只是希望有一种方法可以使用 WP7 即时编译 C#。如果我能得到双方的支持,这就不成问题了。我想知道是否有任何 Mono 库可以移植到 WP7 来共享 CodeDom 和所有编译器类的功能?
I'm working with a team on a RPG engine in C# and XNA. We're planning on targeting Windows and Windows Phone 7, but are running into issues with AI interactions and controlling player actions during cutscenes. FOr the most part, everything is extracted using the MVC design pattern, but abstracting all logic and movement into a controller could cause issues down the line. So the idea is to have an interface (IScriptEngine) that takes an IScriptObject and updates data in the map model accordingly.
I was thinking about putting the scripts in an XML sort of syntax:
<Script Name="MoveNPC_1">
<Action Command="MoveToTile" Target="NPC_1" Value="10,2"/>
</Script>
And have an IScriptEngine parse it accordingly. I highly doubt parsing in a giant switch statement would be a good idea, but it's what I've been working with.
switch(Action.Command)
{
case "MoveToTile":
{
doMovement(Action.Value, Action.Target);
break;
}
}
Even my high school programming experience tells me that this is a bad idea, but I can't think of any other way around it.
Edit:
I'd like to somehow embed this all in the map file. In the map XML file, we have areas designated for , which contains multiple tags. Then there would be an section, designating where the NPC is on the map, and what resources and scripts it would use. Then there would be a section, where all battles would be defined (Again, defining resources and what not), and then possibly a Section, where these scripts would be defined. I just wish there was a way to compile C# on the fly using WP7. If I could get support on both sides, this wouldn't be an issue. I wonder if there would be any Mono library that could be ported to WP7 that would share the functionality of CodeDom and all of the Compiler classes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
XML 脚本!? 喘息!现在这是“可能会导致问题”的事情!
为什么不直接使用 C# 呢?我听说这很厉害。我已经给出了我的对此事的看法。
您需要问自己:您的脚本真的需要数据驱动吗?是不是有什么原因导致数据不能用C#表达呢?
它们真的需要在运行时解释吗?因为,如果他们真的这样做,可以使用 C# 来完成。
这是另一个我对一个几乎相同问题的回答,在 gamedev.stackexchange.com 上。我什至在那里放了一个可能实现的小例子。
如果您想要执行需要超过一帧的操作(基本上是协同例程),例如:“走到这里,说话,等待,走到那里”,您可以 在 C# 中使用
yeild
实现此功能也相当不错。编辑:如果您想混合使用 XML 级别和 C# 脚本,下面是我的意思的示例:
在 C# 中:
XML Scripting!? Gasp! Now that is something that "could cause issues down the line"!
Why not just use C#? I hear it's pretty terrific. I've already given my opinion on this matter.
You need to ask yourself: Do your scripts really need to be data driven? Is there a reason that data can't be expressed using C#?
Do they really need to be interpreted at runtime? Because, if they really do, that can be done with C#.
And here's another answer of mine to an almost identical question, over on the gamedev.stackexchange.com. I've even put a little example of a possible implementation in there.
If you want to have actions that take more than a frame to execute (basically co-routines), for example: "Walk over here, Talk, Wait, Walk over there", you can implement this with
yeild
in C# reasonably well, too.Edit: If you want to mix your XML levels, and C# script, here is an example of what I mean:
And in C#:
您可能希望考虑嵌入一种真正的语言,例如 Lua,而不是使用 XML 语法。您没有看到许多基于实际 XML 语法构建的编程语言,这是有原因的!对于实际的编程任务来说,这确实很尴尬。
You may wish to consider embedding a real language such as Lua instead of using an XML syntax. There's a reason why you don't see many programming languages built upon actual XML syntax! It's really awkward for actual programming tasks.
您可以使用现有的 XML 解析器,有很多不同的方法(SAX、StAX)并且解析器可用于多种语言。
然后您可以使用 XPath 来引用文档中的节点。
You could use an existing XML parser, there are a lot of different ways of doing it (SAX, StAX) and parsers available for many languages.
Then you could use XPath to reference nodes in your document.
您是否必须在运行时解释脚本?你说你的开发是内容驱动的,这是一件好事。但您不一定需要解释脚本才能利用 XML 或脚本语言所带来的速度和效率的提高。
我遵循 Shawn Hargreaves 创建 XML 数据并允许内容管道将其编译为 .XNB 的示例。如果您实现一个脚本系统或集成现有脚本系统并为其创建一个 ContentPipeline 项目,您可以只编译添加或修改的脚本,与重新编译整个该死的游戏相比,运行之间的停机时间非常少。
我绝对不会选择 XML,XNA 可能会自动为其提供一个导入器,但尝试使用它会非常丑陋。 XNUA 应该是 XNA 的 lua 库,应该可以很好地处理此类事情。
无论如何,让设计人员编译为 .XNB 与您在 Source 等引擎中必须做的废话并没有什么不同。
另外,我发现以下内容对于思考脚本事件很有用:
Riverman Media - 面向对象编程,脚本事件系统
布兰登·富特文格勒 - 第一印象很重要
Do you necessarily need to interpret the scripts at runtime? You say your development is content driven, which is a good thing to do. But you don't necessarily need your scripts to be interpreted in order to take advantage of the increase in speed and efficiency from using XML or a scripting language.
I'm following Shawn Hargreaves' example of creating XML data and allowing the Content Pipeline to compile it into a .XNB. If you implement a scripting system or integrate an existing and make a ContentPipeline project for it, you can compile just the scripts that were added or modified, very little downtime between runs in comparison to recompiling the whole darn game.
And I definitely wouldn't go for XML, XNA may automatically have an importer for it, but it will be ugly as hell trying to use it. XNUA was supposed to be a lua library for XNA that's supposed to work well enough for this sort of thing.
Making designers compile to .XNB isn't all that different from the crap you have to do in engines like Source anyway.
Also, I found the following useful for thinking about scripted events:
Riverman Media - Object Oriented Programming, the Scripted Event System
Brandon Furtwangler - First Impressions Matter
您还可以考虑使用名为 XNA Debug Terminal 的库,位于 http://www.protohacks.net/xna_debug_terminal 。
这允许您在运行时执行任意 C# 语句。它的工作原理基本上类似于脚本语言的 Eval() 方法。也许您可以允许用户在游戏运行时使用此库动态编写脚本操作,而不是制作 xml 脚本操作?或者您可以使用它来编写您自己的操作脚本,以查看每种情况下会发生什么。特殊的终端命令之一允许您获取包含 C# 代码的字符串并评估该代码。因此,您可以设置一些预设操作并让用户从中进行选择。
这些想法可能不适用于您的特定情况,但我只是想给您(以及阅读本文的其他人)一些更多的选择来考虑。
You may also consider a library called XNA Debug Terminal at http://www.protohacks.net/xna_debug_terminal .
This allows you to execute arbitrary c# statements at runtime. It basically works like an Eval() method for scripting languages. Maybe instead of making xml scripted actions, you can allow users to script actions on the fly while the game is running using this library? Or you can use it to script your own actions to see what happens in each case. One of the special terminal commands allows you to take a string that contains c# code and evaluate the code. So you could set up some preset actions and have the user choose from them.
These ideas may not work for your particular case, but just thought I would give you (and anyone else reading this) some more options to think about.