c# - 允许用户安排方法

标签 c# winforms events delegates

假设我有一个 Player 类。它有一个接受方向参数的 Move 方法、一个接受两个 int 的 ChangePosition 方法、一个 Disappear void 方法,等等。

我想让用户(可能使用列表框)能够将其中一些方法添加到 Player 对象的行为中。例如,他们可以选择让它向右移动然后向下移动然后消失。然后,他们选择的方法将添加到一个事件中,这样当该事件发生时,他们选择的方法就会执行。

有没有人做过这样的事情?做这个的最好方式是什么? (我13岁,我对设计模式了解不多)

最佳答案

首先,您应该将所有游戏逻辑放入一个 Engine 项目中,并使用一个 Engine 类单独负责(处理所有游戏逻辑并与 UI 和框架 [以及较低层,如果有的话)进行通信是任何]).

其次,您可以拥有一个 EngineAction 类,它具有一个枚举 EngineActionType(Move、ChangePos、Disappear,...)和其他属性。总体思路是这样的:

有一个枚举来保存类型:

public enum EngineActionType
{
    Move,
    ChangePos,
    Disappear,
    ...
}

创建一个抽象类对所有引擎操作类进行逻辑分组,并使用公共(public)类型属性添加它们:

public abstract class EngineAction
{
    public readonly EngineActionType Type;

    protected EngineAction(EngineActionType type)
    {
        this.Type = type;
    }
}

为每个引擎操作创建一个类,将所有需要的参数作为属性保存。它应该派生自 EngineAction 并将适当的 EngineActionType 发送到基本构造函数:

public class EngineActionMove : EngineAction
{
    public int XDelta;
    public int YDelta;

    public EngineActionMove() : base(EngineActionType.Move)
    {
    }
}

public class EngineActionChangePos : EngineAction
{
    ...
}

...

毕竟,您可以将这些对象放在一个列表中,作为用户的命令,并对其进行迭代,根据它们的类型一个一个地执行它们:

foreach (EngineAction action in actionsToDo)
{
    switch (action.Type)
    {
        case EngineActionType.Move:
            EngineActionMove mvAction = (EngineActionMove)action;

            // Example:
            player.Position = player.Position.Offset(mvAction.XDelta,
                                                     mvAction.YDelta);
            break;
        case EngineActionType.ChangePos:
            EngineActionChangePos cpAction = (EngineActionChangePos)action;

            // Example:
            player.Position = new Point(cpAction.X, cpAction.Y);
            break;
        case EngineActionType.Disappear:
            // Just make the player disappear,
            // because the operation needs no parameters
            player.Disappear();
            break;
        case ...:
        default:
            // maybe throw an error here, to find errors during development
            // it helps you find non-handled action types
    }
}

进一步提示:UI 中的逻辑越少越好。总是。

编辑:Charleh 的好主意:

public interface IEngineAction
{
    void Do(Player target);
}

public class EngineActionMove : IEngineAction
{
    public int XDelta;
    public int XDelta;

    public void Do(Player target)
    {
        // Example
        target.Position = ...
    }
}

public class EngineActionDisappear : IEngineAction
{
    public void Do(Player target)
    {
        // Example
        target.Visible = false;
    }
}

...

添加到列表示例:

var actionsToDo = new List<IEngineAction>();

actionsToDo.Add(new EngineActionDisappear());
actionsToDo.Add(new EngineActionMove { XDelta = 10, YDelta = 20 });

和迭代:

foreach (IEngineAction action in actionsToDo)
{
    action.Do(player);
}

关于c# - 允许用户安排方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12769721/

相关文章:

c# - 使用网格中的文本框和带有属性的标签设计用户控件

python - 当滚动条已设置时更新 WheelEvent 上的 QLineEdit

c# - 你如何控制 C# 中的事件触发?

C# 将文件读入字符串数组并将其打印到文本框中

c# - 在 asp.net 服务器端代码中?

c# - 低帧率下的缓慢碰撞检测

c# - 通用表达式树,每个提供的属性都有 'OR' 子句

c# - TabControl C# 中的图标 - 如何?

c# - Foreach 控件在窗体中,我怎样才能对我的窗体中的所有文本框做些什么?

Python 和 PyQt : Catch Minimize Event