【发布时间】:2017-10-20 17:53:25
【问题描述】:
我正在使用 MonoGame 框架制作游戏引擎。由于这是一款多人游戏,其他玩家需要知道其他玩家的某些信息,例如位置和速度,通常用于 AI 反应。
我即将为玩家操作实现 Lua 脚本。但是,我目前想不出办法让玩家无法修改其他玩家的信息,例如位置和姓名。
例如,假设我在 C# 中有以下属性:
public Vector2 Pos { get { return pos; } private set { this.pos = value; } }
private Vector2 pos;
看起来不错,对吧?不完全是。假设我有一个函数返回最近的敌人GetNearestEnemy(),它返回另一个玩家。因为 Player 类可以访问它自己的属性,所以我可以在其他方法中轻松地做这样的事情:
public void DoStuff()
{
Player otherPlayer = GetNearestEnemy();
otherPlayer.Pos = new Vector2(34,151);
}
所以我认为“也许我可以将实例作为参数传递。”
public void SetPos(Player instance, Vector2 pos)
{
if (instance != this)
return;
else
this.pos = pos;
}
...并且始终将“this”作为参数传递。但是,这也有同样的问题:我可以很容易地将GetNearestEnemy() 传递给该方法,并且可以设置敌人的位置。
这是我试图阻止的行为类型。有没有办法最好:
- 获取调用该方法的实例?
- 在调用对象不知情的情况下隐式设置参数?
或者是否有其他我没有看到的方法来处理它?
【问题讨论】:
-
我不认为
otherPlayer.Pos = new Vector2(34,151);应该工作 - 你真的测试过吗? -
不,这里没有语言支持来处理您想要的内容。据推测,既然你正在编写这个类,你就可以确保它不会做不应该做的事情。
-
@MetaColon 是的。由于 DoStuff 是 Player 中的一个方法,它可以访问 Player 类所做的一切。
-
使
GetNearestEnemy返回源引用的克隆。这样一来,任何修改都会在克隆上执行,并且无法修改源引用。 -
假设同一个程序员做这两个类,这只是设计的一部分。如果有两个相互竞争的程序员,语言特性不会阻止他们在同一个进程中访问状态。然而,CLR 具有一些隔离功能,例如应用程序域(仅限完整的 .NET Framework)。 (参见 .NET 容器)