假设我有一个 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/