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();
}

上記のコードで、この揺れを引き起こす何かがわかりますか?

編集: はい、コードは a: 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回しか起こりません。

編集:サードパーティのライブラリを使用していますか? - いいえ、サードパーティのライブラリは使用していません。

編集:どのファイルでも、3番目のサンプルが常にこれを引き起こしているようです。

編集: サウンド サンプルを使用するすべての場所で発生します。3 つのサンプルを再生すると、状況が発生します。

編集: @nobugz: はい、あなたが正しいと思います。問題は、UI スレッドを長時間保持していることです。マージされたオーディオファイルを使用してみましたが、元のデュレーションを考えると問題があります。

Application.DoEvents();編集:各サンプル再生コマンドの後に置くことで、この問題を解決しました。揺れません:)

編集:上記の解決策は実際には機能しませんでした。プレーヤーのサンプル数が増えると、アプリケーションの GUI が再び動かなくなりました。代わりに QueueUserWorkItem を使用したソリューションが採用されました。これはクロスセレーディングが発生するため、満足のいく解決策としてまだ証明されていません。つまり、古いスレッドがまだ再生されている間に、サンプルの新しいスレッドを開始できます。

より多くの知識が明らかになるにつれて、これを更新します。

4

2 に答える 2

5

UI スレッドで PlaySync を呼び出すのは、あまりうまくいきません。UI スレッドがサウンドが終了するのを待ってビジー状態になるため、メイン ウィンドウが応答しなくなります。本来のようにメッセージをポンピングすることはできません。これに時間がかかると、Windows が介入し、ウィンドウに "ゴースト" が重なって表示されます。通常、タイトル バーに "応答していません" と表示されます (存在する場合)。このゴースト ウィンドウは、自分のウィンドウと完全には一致しない可能性があり、それが「揺れ」を説明している可能性があります。

代わりに Play() を使用すると、その問題が解決します。しかし、新しいものを手に入れると、サウンドのシーケンスが難しくなります。スレッドから呼び出しを行うと、両方を解決できます。サウンドをより適切に制御するには、NAudioをチェックしてください。

于 2010-03-24T20:45:04.607 に答える
3

プログラムのコピーを作成します。コピーからできるだけ多くのゲーム要素を削除します。モジュールを削除し、ゲーム ロジックを削除し、関数をクラス間で移動して抽象化を減らし (クラスを削除できるように)、一般的にゲームをハックします。

そうするたびに、バグがまだ存在するかどうかを確認してください。最初は、プログラムのより大きなチャンクを削除しますが、時間の経過とともに削除の量が減少します。

削除するとバグが修正されるものを見つけた場合、2 つの可能性があります。バグを発見したか、プログラムの残りの部分と何らかの相乗効果があり、バグが発生したかのいずれかです。後者の場合、さらにプログラムを削除し続けます。

最終的には、バグのある最小限のプログラムになってしまいます。それをここに投稿してください (大きすぎる場合はペーストビンに投稿してください)。

これは、見つけられないバグに遭遇したときに使用する最後の手段の 1 つです。

于 2010-03-24T19:26:26.803 に答える