C# 单一游戏窗口在拖动时冻结
我正在用MonoGame开发一款网络游戏,每当拖动窗口时,我都会遇到游戏冻结的问题。在寻找解决方案的过程中,我找到了一个描述如何注入自定义tick系统的方法C# 单一游戏窗口在拖动时冻结,c#,xna,monogame,C#,Xna,Monogame,我正在用MonoGame开发一款网络游戏,每当拖动窗口时,我都会遇到游戏冻结的问题。在寻找解决方案的过程中,我找到了一个描述如何注入自定义tick系统的方法 然而,虽然这个答案适用于XNA,但所需的反射调用会在MonoGame中引发异常。有没有人有其他解决方案可以让游戏在被拖动时继续更新 引发异常的代码部分是: // Exception on this line object host = typeof(Game).GetField("host", BindingFlags.
然而,虽然这个答案适用于XNA,但所需的反射调用会在MonoGame中引发异常。有没有人有其他解决方案可以让游戏在被拖动时继续更新 引发异常的代码部分是:
// Exception on this line
object host = typeof(Game).GetField("host", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this);
host.GetType().BaseType.GetField("Suspend", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(host, null);
host.GetType().BaseType.GetField("Resume", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(host, null);
例外情况如下:
CardCatacombs.exe中发生类型为“System.NullReferenceException”的未处理异常
其他信息:对象引用未设置为对象的实例
据我所知,这个问题是通过在项目引用中导入System.Windows.Forms程序集并忽略XNA提供答案的反射组件来解决的,因为MonoGame不再使用游戏中的“主机”字段
感谢Sahuagin的支持。由于MonoGame不再使用游戏中的“主机”字段,因此通过在项目引用中导入System.Windows.Forms程序集并忽略为XNA提供的答案中的反射组件,此问题得以解决
感谢Sahuagin的支持。基于另一个答案,使用
System.Timers.Timer
而不是System.Windows.Forms.Timer
:
public class MyGame : Game {
bool manualTick;
int manualTickCount = 0;
Timer mTimer;
public MyGame() {
mTimer = new Timer {
Interval = (int)(TargetElapsedTime.TotalMilliseconds)
};
mTimer.Elapsed += (s, e) => {
if (manualTickCount > 2) {
manualTick = true;
Debug.Print("manual tick");
Tick();
manualTick = false;
}
manualTickCount++;
};
// required to prevent exception on exit
// otherwise the timer keeps running after the window closes
Exiting += (s, e) => mTimer.Dispose();
// it might be needed to do something similar in the Dispose event
// if the game can be disposed without exiting
}
// the constructor is too early to start the timer, so put it in initialize
protected override void Initialize() {
mTimer.Start();
base.Initialize();
}
// and lastly, in Update
protected override void Update(GameTime pGameTime) {
if (!manualTick) {
manualTickCount = 0;
Debug.Print("not manual");
}
base.Update(pGameTime);
}
根据另一个答案,使用
System.Timers.Timer
而不是System.Windows.Forms.Timer
:
public class MyGame : Game {
bool manualTick;
int manualTickCount = 0;
Timer mTimer;
public MyGame() {
mTimer = new Timer {
Interval = (int)(TargetElapsedTime.TotalMilliseconds)
};
mTimer.Elapsed += (s, e) => {
if (manualTickCount > 2) {
manualTick = true;
Debug.Print("manual tick");
Tick();
manualTick = false;
}
manualTickCount++;
};
// required to prevent exception on exit
// otherwise the timer keeps running after the window closes
Exiting += (s, e) => mTimer.Dispose();
// it might be needed to do something similar in the Dispose event
// if the game can be disposed without exiting
}
// the constructor is too early to start the timer, so put it in initialize
protected override void Initialize() {
mTimer.Start();
base.Initialize();
}
// and lastly, in Update
protected override void Update(GameTime pGameTime) {
if (!manualTick) {
manualTickCount = 0;
Debug.Print("not manual");
}
base.Update(pGameTime);
}
“所需的反射调用在MonoGame中引发异常”哪个异常?你的代码是什么样子的?可能是你想要的:我已经用更多的信息更新了我的问题。不幸的是,第二篇文章提到的是图形缩放,而不是游戏逻辑更新。例外是因为
game
对象上不再有host
字段。这可能意味着取消钩挂Suspend
和Resume
的第一步是不必要的。您是否尝试过在不执行第一部分的情况下设置计时器?在尝试实现计时器时,我注意到MonoGame不允许使用System.Windows.Form.timer类。当我尝试从timer Appeased事件(使用System.Timers.timer)中调用Tick()时,会从Tick()中引发“NullReferenceException”错误。“所需反射调用在MonoGame中引发异常”哪个异常?你的代码是什么样子的?可能是你想要的:我已经用更多的信息更新了我的问题。不幸的是,第二篇文章提到的是图形缩放,而不是游戏逻辑更新。例外是因为game
对象上不再有host
字段。这可能意味着取消钩挂Suspend
和Resume
的第一步是不必要的。您是否尝试过在不执行第一部分的情况下设置计时器?在尝试实现计时器时,我注意到MonoGame不允许使用System.Windows.Form.timer类。当我尝试从timer Appeased事件中调用Tick()时(使用System.Timers.timer),会从Tick()中抛出一个“NullReferenceException”错误