0

ここで質問するのは初めてなので、間違っていたら訂正してください。

私のチェスセットの写真:

駒を動かすたびに、約 1 秒遅れます。すべてのピースとタイルには画像があり、正確に 96 個の画像があります。ピースを移動するたびに、すべてが黒でクリアされ、グラフィックが更新されます。

チェスの初期の段階では、私は画像を持たず、代わりに異なる色を使用していましたが、数個の駒だけで目立ったラグはなく、駒は一瞬で動きました。

        public void updateGraphics(PaintEventArgs e, Graphics g, Bitmap frame)
    {
        g = Graphics.FromImage(frame);
        g.Clear(Color.Black);


        colorMap(g);

        g.Dispose();
        e.Graphics.DrawImageUnscaled(frame, 0, 0);
    }

関数 colorMap(g) は次のようになります。

        private void colorMap(Graphics g)
    {
        for (int y = 0; y < SomeInts.amount; y++)
        {
            for (int x = 0; x < SomeInts.amount; x++)
            {
                //Tiles
                Bundle.tile[x, y].colorBody(g, x, y);

                //Pieces
                player1.colorAll(g);
                player2.colorAll(g);
            }
        }
    }

colorAll 関数は、次のような colorBody(g) 関数をすべて実行します。

        public void colorBody(Graphics g)
    {
        //base.colorBody() does the following: body = new Rectangle(x * SomeInts.size + SomeInts.size / 4, y * SomeInts.size + SomeInts.size / 4, size, size);
        base.colorBody();

        if (team == 1)
        {
            //If its a white queen
            image = Image.FromFile("textures/piece/white/queen.png");
        }
        if (team == 2)
        {
            //If its a black queen
            image = Image.FromFile("textures/piece/black/queen.png");
        }
        g.DrawImage(image, body);
    }

最後に、駒を動かす関数:

        public void movePiece(MouseEventArgs e)
    {
        for (int y = 0; y < SomeInts.amount; y++)
        {
            for (int x = 0; x < SomeInts.amount; x++)
            {
                if (Bundle.tile[x, y].body.Contains(e.Location))
                {
                    //Ignore this
                    for (int i = 0; i < queens.Count; i++)
                    {
                        Queen temp = queens.ElementAt<Queen>(i);
                        temp.move(x, y);
                    }
                    //Relevant
                    player1.move(x, y);
                    player2.move(x, y);
                }
            }
        }
    }

これをすべて読んでくれてありがとう!コーディング例が不十分な場合は、プログラム全体へのリンクを作成できます。

4

4 に答える 4

7

すべての画像に対して、すべての更新を呼び出しImage.FromFileています。ディスクから毎回すべての画像ファイルを効果的にリロードしています。

画像を一度ロードし、結果Imageの を便利な場所に保存することを検討しましたか? (たとえば、配列でImage[2,6]十分です)

于 2012-07-05T14:36:52.357 に答える
3

なぜ毎回ボードを描き直すのですか?ボードをそのままにして、背景を透明にした画像を表示することはできませんか? そうすれば、背景 (ボード) として 1 つの画像があり、さらに 64 個の小さな画像がボード上にグリッド状に配置され、移動ごとに表示される画像を変更するだけです。

そうすれば、ウィンドウに描画を処理させることができます...

また、アプリケーションの開始時にピースの画像を読み込みます。

于 2012-07-05T14:36:57.427 に答える
1

Image.FromFile()内部に電話をかけないことに加えてupdateGraphics() (これは間違いなくあなたの最大の問題です)、電話をかけるたびにボード全体を再描画しようとすべきではありませんupdateGraphics()-ほとんどの場合、ボードのごく一部だけが無効になります。

には、ボードのどの部分を再描画する必要があるかを指定PaintEventArgsするパラメータ、が含まれています。ClipRectangleどのタイルがその長方形と交差しているかがわからないかどうかを確認し、それらのタイルのみを再描画します:)

ヒント:Point ScreenToTileCoords(Point)画面座標を取得し、その座標にあるボードタイルを返す関数を記述します。次に、再描画する必要があるタイルは次のとおりです。

Point upperLeftTileToBeDrawn = ScreenToTileCoords(e.ClipRectangle.Left, e.ClipRectangle.Top);
Point lowerRightTileToBeDrawn = ScreenToTileCoords(e.ClipRectangle.Right - 1, e.ClipRectangle.Bottom- 1);

また、ティアリングを回避するために、コントロールがダブルバッファリングされていることを確認してください。これは、上記のコメントにある@SteveBのリンクよりもはるかに簡単です。これがであると仮定するとUserControl、単純に設定します

this.DoubleBuffered = true;
于 2012-07-05T15:32:52.293 に答える
0

さて、これはどうですか:

ボード全体をクリアするのではなく、クリアする必要がある部分だけをクリアします。

別:

WPF に更新 - 描画をグラフィックス カードに移動 - スマートな方法でピースを移動するだけです (つまり、すべてのピースにコントロール/オブジェクトがあります)。

于 2012-07-05T14:37:05.550 に答える