4

私のマインスイーパゲームでは、イーパ-ミディアム-ハードを切り替えるために、動的にコントロールを作成する必要があります。質問のために、ハードは100個のボタンで構成されているとしましょう。

これが私がそれらを作成する方法です:

this.SuspendLayout(); //Creating so many things that I assume it would be faster to suspend and resume.
foreach (string i in playingField)
{

    Button button = new Button();
    button.Name = i;
    button.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
    button.Margin = new Padding(0);
    button.TabIndex = 0;
    button.Location = new System.Drawing.Point(3, 3);
    button.Size = new System.Drawing.Size(25, 25);
    button.BackgroundImage = blockImage; //##//
    button.MouseDown += new System.Windows.Forms.MouseEventHandler(this.GetUnderSide);
    button.UseVisualStyleBackColor = false;
    minesPanel.Controls.Add(button); //Adding the controls to the container
}
this.ResumeLayout(); //Refer to above. Correct me if I'm wrong please.

ご覧のとおり、forループを介してすべてのコントロールを作成し、それらを追加しています。その結果、各ボタンが一度に1回ペイントされます。私も試しname.Controls.AddRange(arrayButtons)ましたが、それでも同じ問題が発生しました。個別の絵画。

私が必要としているのは、すべてのアイテムを作成し、その後、単一のビットマップをでペイントするように、それらをすべてペイントする方法ですがDoubleBuffered、残念ながら、それも機能しません。

さらに、私はこれを試しました:

    protected override CreateParams CreateParams
    {
        get
        {
            // Activate double buffering at the form level.  All child controls will be double buffered as well.
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
            return cp;
        }
    }

どのような作品。アプリケーションの起動時にのみ機能します。ただし、実行時にグリッドサイズを変更し、コントロールを追加することを考えると、これは実行可能なオプションではありません。

Graphicsクラスのメソッドを使うのと同じくらい簡単だと言われました。問題は、どこから始めればいいのかわからないということです。

誰かが私のすべてのコントロールを同時にペイントするための助けを提供できれば、それは素晴らしいことです。

4

2 に答える 2

8

悲しいことに、WinFormsは、特に数百に入るときに、あまりにも多くのコントロールを持つことを好みません。各コントロールは独自のペイントメッセージをウィンドウに送信するため、各コントロールを同時にペイントすることはできません。

マインスイーパのようなゲームボードにアプローチする最良の方法は、1つのコントロールを使用してボタンのグリッドを描画することだと思います。

シンプルマインクラス:

public class Mine {
  public Rectangle Bounds { get; set; }
  public bool IsBomb { get; set; }
  public bool IsRevealed { get; set; }
}

次に、Panelコントロールから継承する新しいコントロールを作成し、ちらつきを防ぐためにDoubleBufferedプロパティを設定します。

public class MineSweeperControl : Panel {
  private int columns = 16;
  private int rows = 12;
  private Mine[,] mines;

  public MineSweeperControl() {
    this.DoubleBuffered = true;
    this.ResizeRedraw = true;

    // initialize mine field:
    mines = new Mine[columns, rows];
    for (int y = 0; y < rows; ++y) {
      for (int x = 0; x < columns; ++x) {
        mines[x, y] = new Mine();
      }
    }
  }

  // adjust each column and row to fit entire client area:
  protected override void OnResize(EventArgs e) {
    int top = 0;
    for (int y = 0; y < rows; ++y) {
      int left = 0;
      int height = (this.ClientSize.Height - top) / (rows - y);
      for (int x = 0; x < columns; ++x) {
        int width = (this.ClientSize.Width - left) / (columns - x);
        mines[x, y].Bounds = new Rectangle(left, top, width, height);
        left += width;
      }
      top += height;
    }
    base.OnResize(e);
  }

  protected override void OnPaint(PaintEventArgs e) {
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    for (int y = 0; y < rows; ++y) {
      for (int x = 0; x < columns; ++x) {
        if (mines[x, y].IsRevealed) {
          e.Graphics.FillRectangle(Brushes.DarkGray, mines[x, y].Bounds);
        } else {
          ControlPaint.DrawButton(e.Graphics, mines[x, y].Bounds, 
                                  ButtonState.Normal);
        }
      }
    }
    base.OnPaint(e);
  }

  // determine which button the user pressed:
  protected override void OnMouseDown(MouseEventArgs e) {
    for (int y = 0; y < rows; ++y) {
      for (int x = 0; x < columns; ++x) {
        if (mines[x, y].Bounds.Contains(e.Location)) {
          mines[x, y].IsRevealed = true;
          this.Invalidate();
          MessageBox.Show(
            string.Format("You pressed on button ({0}, {1})",
            x.ToString(), y.ToString())
          );
        }
      }
    }
    base.OnMouseDown(e);
  }
}

ここに画像の説明を入力してください

于 2012-11-04T13:56:38.710 に答える
2

非表示minesPanel、ボタンのペイント、表示minesPanel

于 2012-11-02T12:06:15.473 に答える