我使用Visual C#2010 express。我正在开发一款游戏,并遇到了一个小小的新手问题。事实上,我想我们正在处理一个最佳实践类型的情况,并且没有一些我真正帮助它的初学者书籍,所以我希望你们能做到。
所以,我有两种形式,一种是启动画面/启动形式,另一种是主游戏窗口。我创建了一个包含所有世界数据的类,当第一个屏幕用户点击“新游戏”时,会生成此类的新实例并填充数据。
到目前为止一切顺利。
newgame按钮除了创建世界实例外,还打开了主游戏窗口。问题是,在主游戏窗口中,当我尝试使用gameworld实例的属性时,它说它在这种情况下不存在。
所以,如果我做对了,创建的实例只存在于第一个表单类中......这是正确的吗?
因此,如果我想移动整个数据,我应该实际序列化并保存世界级实例数据,并以第二种形式加载它吗?或者我应该如何处理这个问题。
我知道这是一个非常新手的问题,而且我可以将它破解成工作,但问题是 - 我真的觉得我必须了解我正在做的一切。
提前致谢!
答案 0 :(得分:3)
您需要在游戏表单上创建一个构造函数,该构造函数接受您的世界类的实例并将其分配给相同类型的字段 - 游戏表单方法可以访问该字段。
World world;
// constructor
public GameForm (World world)
{
this.world = world;
}
// Can now use `world` in all `GameForm` methods
而不是构造函数注入(正如我在我的示例中所示),您可以使用property injection,尽管我更喜欢前者(倾向于确保正确初始化 - 尽管您可能想要检查{{1传入)。
答案 1 :(得分:1)
如果在启动画面中有世界数据对象的引用,您可以在主屏幕中将其分配给公共成员,或通过构造函数将其传递给主屏幕。
所以在启动画面
FrmMain frmMain = new FrmMain();
frmMain.WorldData = this.WorldData;
如果它是启动画面的实例成员
或者类似
之类的东西FrmMain frmMain = new FrmMain();
frmMain.WorldData = new WorldData();
甚至
FrmMain frmMain = new FrmMain(this.WorldData);
或
FrmMain frmMain = new FrmMain(new WorldData());
使用FrmMain构造函数
public FrmMain(WorldData worldData)
{
this.m_WorldData = worldData;
}
答案 2 :(得分:1)
假设您只使用Windows窗体,而不是XNA或类似框架,那里没有winforms。
启动表单:
void StartButton_Click(object sender, EventArgs e)
{
GameWorld gw = new GameWorld();
// Initialize gw instance here
GameForm mainForm = new GameForm(gw);
mainForm.Show();
}
并在游戏表单中添加构造函数:
public class GameForm
{
private GameWorld _gw;
public GameForm()
{
InitializeComponent();
}
public GameForm(GameWorld gw) : this()
{
_gw = gw;
}
}
此时您可以在游戏表单中使用私有变量_gw。
另外,我建议通过构造函数传递GameWorld实例,而不是属性,因为该值对于表单至关重要。通常,属性可能更适合提供调整某些行为的方法,并且任何构造函数参数都可以被视为对象按预期工作所必需的。 您还可以将默认构造函数(没有参数的构造函数)设为私有。
答案 3 :(得分:0)
根据数据的大小以及世界对象类是否可序列化,您可能会考虑缓存它。然后,每个需要数据的表单都可以在需要时从缓存中获取它。