3

我有一个正在开发的 C# 游戏程序。它使用声音样本和winsock。

当我测试运行游戏时,大部分音频都可以正常工作,但有时如果顺序播放多个样本,应用程序表单会稍微晃动,然后回到原来的位置。

我该如何进行调试或以可管理的方式将其呈现给你们?我敢肯定,没有人会因为害怕病毒攻击而想要整个应用程序代码。

请指导我..

编辑:我无法确定产生此结果的任何代码部分。它就是这样,我无法解释。

编辑:没有 x/y 位置没有改变。窗口像晃动几个像素然后又回到晃动之前的位置。

if (audio)
{
    Stream stream;
    SoundPlayer player;

    stream = Properties.Resources.ResourceManager.GetStream("_home");
    player = new System.Media.SoundPlayer(stream);
    player.PlaySync();
    player.Dispose();

    string ShipID = fireResult.DestroyedShipType.ToString();
    stream = Properties.Resources.ResourceManager.GetStream("_" + ShipID);
    player = new System.Media.SoundPlayer(stream);
    player.PlaySync();
    player.Dispose();

    stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
    player = new System.Media.SoundPlayer(stream);
    player.PlaySync();
    player.Dispose();
}

你能在上面的代码中看到任何会产生这种震动的东西吗?

编辑:是的,代码正在执行中: this.Invoke(new Action(delegate(){ ....})); 会是这样吗?我该如何解决这个问题?

编辑:

           stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
           player = new System.Media.SoundPlayer(stream);
           player.PlaySync();
           player.Dispose();
           stream.Dispose();

如果取出上面的代码,那么它工作正常!有任何想法吗?

编辑:我将这一行替换为:

stream = Properties.Resources.ResourceManager.GetStream("_destroyed");

到不同的文件名,但问题仍然存在,但至少它不是音频文件已损坏。

编辑:当有人发送微动时的 MSN?它有点像那样,但只发生 2 或 3 次。

编辑:您是否使用任何 3rd 方库?- 不,我没有使用任何 3rd 方库。

编辑:似乎无论什么文件,第三个样本总是导致这个。

编辑:在我使用声音样本的任何地方都会发生。如果我播放 3 个样本,情况就会发生。

编辑:@nobugz:是的认为你是对的。问题是等待 UI 线程的时间过长。正如我尝试使用合并的音频文件一样,鉴于其原始持续时间,问题就在那里。

Application.DoEvents();编辑:我通过在每个示例播放命令之后放置来解决这个问题。没有震动:)

编辑:上述解决方案并没有真正起作用。随着播放器样本数量的增加,应用程序 GUI 再次卡住。而是采用了使用 QueueUserWorkItem 的解决方案。这仍然有待证明是一个令人满意的解决方案,因为会发生交叉处理,即可以在旧样本仍在播放时启动新的样本线程。

随着更多知识的曝光,将对此进行更新。

4

2 回答 2

5

在 UI 线程上调用 PlaySync 不是很好。当你的 UI 线程忙于等待声音结束时,它会使你的主窗口无响应,它不会像它应该做的那样发送消息。如果这需要足够长的时间,Windows 会介入并用“幽灵”覆盖窗口,它通常会在标题栏中显示“无响应”(如果有的话)。这个幽灵窗口可能与您自己的窗口不太匹配,这可以解释“抖动”。

改用 Play() 可以解决这个问题。但是给你一个新的,排序声音变得困难。从线程进行调用可以解决这两个问题。查看NAudio以更好地控制声音。

于 2010-03-24T20:45:04.607 回答
3

制作您的程序的副本。从副本中删除尽可能多的游戏元素。删除模块,删除游戏逻辑,在类之间转移函数以减少抽象(这样你就可以删除类),并且通常会破坏游戏。

每次这样做时,检查错误是否仍然存在。最初,您将删除较大的程序块,但随着时间的推移,删除量会减少。

如果您发现某些内容在删除后修复了该错误,则有两种可能性:您找到了该错误,或​​者与程序的其余部分存在某种协同作用导致了该错误。在后一种情况下,继续删除更多的程序。

最终,你会得到一个有 bug 的最小程序。把它贴在这里(或者如果它太大的话,放在一个粘贴箱里)。

这是我在遇到根本无法定位的错误时使用的最后手段之一。

于 2010-03-24T19:26:26.803 回答