2

同じフォームに2つのオブジェクトがあり、数秒ごとに別々に再描画する必要があるゲームを作成しています(アニメーションの場合)。別のスレッドに1つあります。時々、グラフィックスオブジェクトがすでに使用されているというエラーが発生します。同じフォームに2つのグラフィックオブジェクトを作成したため、エラーが発生する頻度は低くなります。

Graphics sprite1 = this.CreateGraphics();
Graphics sprite2 = this.CreateGraphics();

次に、これらのオブジェクトを適切なメソッドに渡します。これがおそらく非常に悪い習慣であるのではないかと心配しています。この問題を解決するための助けをいただければ幸いです。

4

3 に答える 3

4

はい、問題があります。表示されている実際のエラーは、同じ Graphics オブジェクトを複数のスレッドで使用できないようにする GDI+ 内のコードからのものです。これはより深刻な問題ですが、ウィンドウを直接参照する Graphics オブジェクトを作成しています。基になる Windows オブジェクトは、デバイス コンテキストへのハンドルである HDC です。デバイス コンテキストはスレッド セーフではありません。偶発的なペイント アーティファクト、デッドロック、アクセス違反などの事故が発生します。

FromImage () 画像で作成された Graphics オブジェクトは、異なるビットマップから作成されているか、2 つのスレッドが同じ Graphics オブジェクトを同時に使用しようとしない限り、動作させることができますこれは、ゲーム プログラミングではあまり役に立ちません。

32bppPArgb ピクセル形式でビットマップを作成することにより、高速に描画するスプライトを作成できます。ほとんどのマシンで、他のどのフォーマットよりも 10 倍速く描画します。プレーン GDI+ でプッシュできるのはこれだけです。次のステップは、ビデオ メモリに常駐するビットマップを使用し、GPU ハードウェアを使用するグラフィック ライブラリを使用することです。このようなライブラリの一般的なマネージド ラッパーは、XNA、SlimDX、SharpDX です。

于 2012-04-28T18:00:02.730 に答える
3

通常、ゲームはマルチスレッドではありませんが、ゲームループがあります。反復ごとに、すべてのオブジェクトの位置が現在の時間に従って再計算されます。その後、それらは再描画されます。

マルチスレッドの方法で計算を行うことを検討してください。ただし、すべての描画はゲーム ループ内のメイン スレッド (いわゆる UI スレッド) で実行する必要があります。


ウィキペディアのゲーム プログラミングの「ゲーム構造」の章を参照してください。

于 2012-04-28T17:11:12.480 に答える
1

前述のように、this.CreateGraphics()実際にはフォーム全体である同じグラフィックス オブジェクトへの参照を作成しています。スレッドの問題はさておき、さまざまな画面を表すために、描画が事前定義された描画領域の外に出ないようにすることで、(理論的には) コードでこれを処理できます。これには少しハードコーディングが必要であり、私のスタイルでも好みでもありません。

私見、はるかに良い方法は、メモリ内に2つの Image オブジェクトを作成することです...

    Image screen1 = new Bitmap(100, 100); // (width, height)
    Image screen2 = new Bitmap(100, 100); // (width, height)

次に、各画像面に個別に描画し、画像ビューアのような単純なものを使用して各「ビュー」を保持できます...

    private void DrawGame()
    {
        DrawSprite1(Graphics.FromImage(screen1));
        DrawSprite2(Graphics.FromImage(screen2));
    }
    public void DrawSprite1(Graphics g)
    {
        g.FillEllipse(Pens.Blue, screen1.GetBounds());
    }
    public void DrawSprite2(Graphics g)
    {
        g.FillRect(Brushes.Red, screen2.GetBounds());
    }

明らかに、これがこの問題に取り組む唯一の方法ではありませんが、独自の解決策に向けて刺激を与えるためのガイドとして使用する必要があります。:)

于 2012-05-17T18:35:15.540 に答える