【问题标题】:How do I store if statements as strings? C#如何将 if 语句存储为字符串? C#
【发布时间】:2017-02-28 04:30:35
【问题描述】:

我正在使用 OpenTK (OpenGL) 在 C# 中创建游戏引擎。我的游戏更新系统在事件队列中工作,当发生某些事情时,它会被添加到事件队列中。每个事件都有一组触发器和一组动作。

假设玩家走路。 “PlayerWalked”触发器运行。列表中包含“PlayerWalked”触发器的游戏中的每个事件都会添加到队列中。

现在,游戏上的更新功能每秒会调用几次。每次调用它时,都会运行队列中最旧的事件。事件的动作列表中的每个动作都会运行。

现在,我想添加一个条件系统。在触发器“PlayerWalked”上,它不只是将其添加到列表中,而是检查触发器、检查条件,然后将其添加到队列中。

例子:

事件 名称:event1
触发器:'ChestOpened'、'PlayerDigs'
条件:玩家位置为 1, 1(2D 游戏)。
行动:给玩家10金币。

现在,我已经完成了触发器检查和操作。现在我只需要添加条件。这是我的困境:

当我存储地图时,我需要一种将条件存储在事件条件文件中的方法。我在想该文件将包含以下内容: '玩家位置|(1,1)' 但这非常宽泛,变量“playerPosition”可能不存在,我不得不对其进行奇怪的解析。

问题:如何将对比(条件、if 语句)存储在映射文件(字符串)中?

更多信息: 地图是存储在游戏可执行文件旁边的地图存储文件夹中的目录。在地图文件夹中,有一个事件文件夹。在事件文件夹中,每个事件都有一个文件夹。在每个事件文件夹中都有一个触发器文件、一个条件文件和一个动作文件。触发器和操作现在正在工作,但条件是我要添加的。

文件结构:

Maps (Directory)
    Map1 (Directory)
        Events (Directory)
            Event1 (Directory)
                Triggers (File)
                Conditions (File)
                Actions (File)
            Event2 (Directory)
                Triggers (File)
                Conditions (File)
                Actions (File)
            Event3 (Directory)
                Triggers (File)
                Conditions (File)
                Actions (File)

我使用 OpenTK 作为 OpenGL 的包装器,但还没有声音引擎。这是一款2D RPG游戏。

编辑:有人提请我注意,我似乎在问如何用 C# 写入文件。我知道。
我要问的是:如何

if (playerPosition == new Point(0, 0)) { }

翻译成我会解析并存储在变量中的文本文件?如何将 If 语句存储在变量中,以及如何将该变量存储在文件中?

解决:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Windows.Forms;

namespace Entropy
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();

            a b = new a { s = ":D" };

            string json = new JavaScriptSerializer().Serialize(b);

            Dictionary<string, object> c = (Dictionary<string, object>)new       JavaScriptSerializer().DeserializeObject(json);
            MessageBox.Show(c["s"].ToString());
            //Out: ':D'
         }
    }

    public class a
    {
        public string s = string.Empty;
    }
}

【问题讨论】:

  • 如何创建类似public class PlayerAtPositionCondition 的东西并创建一个方法public bool IsSatisfied(),其中您的if 逻辑在其中?因此,与其将if 语句存储在某处,不如存储类名以通过反射进行实例化,或者您可以稍后使用一些代码使用FactoryMethod 模式实例化正确的类?您将为每个条件创建一个类,并可能将参数传递给该类...
  • 嗯,会有很多比较。 PlayerLocation、PlayerHasInventoryItem、GameIsOver、GameHasStarted 等。可能有数百个。现在,我可以为所有这些使用枚举。马贝...

标签: c# game-engine


【解决方案1】:

将比较结果存储在字符串中,然后将它们转换为代码......这就是所谓的编写编译器!计算机科学支持您!

所以你问的是,对于我的领域特定语言,我可以使用的最简单的编译器是什么?

你的迷你语言非常迷你:它只有谓词(可能是嵌套的谓词)

您可以查看 C# 编译器解析器/生成器。你有一些有趣的阅读在你面前。

或者,您可以创建一个包含这些嵌套谓词的类结构,然后将它们序列化为 json,并存储 json。

所以你可能有

var condition = new Condition { 
    Object = Objects.Player, 
    Comparison = Comparisons.Equals, 
    Value = new Value { type = Position, innerValue = "2,1" }
};

然后你把它序列化成一个可以保存的字符串...

var json = new JavaScriptSerializer().Serialize(obj);

然后您可以稍后通过将 json 反序列化回一个对象来再次加载它。

您在比较对象上调用了一些“评估”方法,它会遍历对象层次结构,为您计算答案。

我过去通过引用脚本语言来完成此类事情,Lua 在游戏中的此类活动中很受欢迎,但 Python 也有利于互操作性。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
相关资源
最近更新 更多