0


2

カウンターを移動させることはできません(PictureBoxを使用したC#のゲーム)。

私はC#を学ぼうとしているので(簡単です!)、授業の一環として、ストライクアウトと呼ばれるゲームを作成するように求められました。

ゲームのルールは非常に簡単です。 これは、1つのカウンターを画面に残しておくことを目的として、1つのカウンターを別のカウンターにノックする場合です。

あるカウンターを別のカウンターに移動するだけで問題が発生します。 ループを使用して(ボードを構成するために)多数の画像ボックスを作成し、ループを使用してイベントハンドラーを作成しました。 単一の偶数ハンドラーを使用してすべてのカウンターを移動するにはどうすればよいですか?

{
    (...)
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            int x = j * (75);
            int y = i * (75);

            pictureBoxCounter[j, i] = new PictureBox();
            pictureBoxCounter[j, i].Location = new System.Drawing.Point(x, y);
            pictureBoxCounter[j, i].Size = new System.Drawing.Size(75, 75);
            pictureBoxCounter[j, i].BackColor = System.Drawing.Color.Transparent;
            panelGame.Controls.Add(pictureBoxCounter[j, i]);
            this.pictureBoxCounter[j, i].Click += new System.EventHandler(this.pictureBoxCounter_Click);
        }
    }
} // end of some function

private void pictureBoxCounter_Click(object sender, EventArgs e)
{
     //I need some code here but nothing seems to work :(
}

私はこの問題に長い間費やしました。 私の家庭教師に手伝ってほしいとさえ頼みました。 彼が私のコードのほとんどを壊すのを手伝う代わりに。 だから彼が引き起こした問題を修正した後、私は今、コンパイルプログラムで戻ってきました!

(プログラムを実行するときは、プレイヤー情報を入力してゲーム開始ボタンを有効にする必要があります。)

私が他の情報を手伝うことができるならば、尋ねることをheしないでください!

2 Answer


2


このプログラミングの問題は、懸念の分離について説明することを目的としているようです。 そうでない場合は、あるはずです。 (今だ!)

1つではなく2つの問題があります。 (実際には3つ以上ありますが、2つは大きなものがあります。)1つの問題は、このゲームでカウンターを表すオブジェクトのセットを作成する方法と、それらのオブジェクトが従うルールです。 もう1つの問題は、画面上のカウンターをどのように表示するかです。

最初の問題の解決策が「PictureBox」の束を作成することである場合は、抜け出すのが難しいウサギの穴を下って行くことになります。 最初に最初の問題を解決してから、2番目の問題を解決する必要があります。

最初の問題に対処するオブジェクトモデルのラフスケッチ(このゲームのルールがわからないため、非常にラフです):

public class Board
{
   public const int Height = 8;
   public const int Width = 8;
   private Counters[Height][] Counters { get; set; }

   public Counter GetCounter(int row, int col)
   {
      return Counters[row][col];
   }
   public void Initialize() { }
   public void ExecuteMove(Counter c) { }
}

public class Counter
{
   public int Row { get; set; }
   public int Column { get; set; }
}

ですから、 Counter`オブジェクトはそれがどこにあるか(その Row`と Column)を知っています。 「Board」オブジェクトは、すべての「Counter」オブジェクトを知っており、行と列を指定して「Counter」を見つける方法を知っており、カウンターがクリックされたときに移動を実行する方法を知っています。 (ゲームのルールについては何も知りませんが、それらは `ExecuteMove`メソッドで実行します。

これで、ボードをコンソールに出力するメソッドを簡単に作成できます。

public void PrintBoard(Board b)
{
   for (int col = 0; col < board.Width; col ++)
   {
      for (int row = 0, row < board.Height; row++)
      {
         Counter c = board.GetCounter[row][col];
         Console.Write(c == null ? " " : "*");
      }
      Console.WriteLine();
   }
}

そして、動きを入力する方法:

public Counter InputMove(Board b)
{
   string s;
   Console.Write("Row: ");
   s = Console.ReadLine();
   int row = Convert.ToInt32(s);
   if (s == "") return null;
   Console.Write("Column: ");
   s = Console.ReadLine();
   if (s == "") return null;
   int column = Convert.ToInt32(s);
   return b.GetCounter(row, column);
}

…​and now you have everything you need in order to code and test the `ExecuteMove`メソッド。 それを動かしなさい。 待ちます。

できた? 良い。 あなたがたぶん遭遇したいくつかの問題がありますが、私は対処していません。 たとえば、「カウンター」を移動するとき、ボードのアレイとカウンター自体の両方を更新する必要があることをおそらく発見しました。 また、おそらく、カウンターが破壊されたときに何が起こるかを追跡する何らかの方法を考え出す必要があることを発見しました。 マウスのクリックやUI要素の操作に煩わされていなかったことを嬉しく思いませんか?

パート2では。 理事会と話す方法を知っているUIを作りましょう。 フォーム内で、ボード内のカウンターをループし、それぞれに対して PictureBox`を作成し( Row`および Column`プロパティに基づく位置で)、たとえば Countersと呼ばれる Dictionary`に追加します。 また、「PictureBoxes」と呼ばれる「Dictionary」も必要になります。 これらのマップを使用すると、「PictureBox」が指定された「Counter」を検索できます。逆の場合も同様です。

このイベントハンドラーを各 `PictureBox`にアタッチします。

private void PictureBox_Click(object sender, EventArgs e)
{
   PictureBox p = (PictureBox) sender;
   Counter c = Counters[p];
   Board.ExecuteMove(c);
}

(ところで、これは元の質問に対する答えです。)

まあ、それはすべてうまくいきます: PictureBox`をクリックして、その Counter`を見つけ、移動を実行できます。 しかし、UIでゲームの視覚状態をどのように更新しますか? それは、ゲームの実際のルールに大きく依存します。

たとえば、カウンターをクリックして消える場合、「Visible」プロパティを「Counter」クラスに追加し、「Board」クラスの「ExecuteMove」でそれを更新します。 「Counter」が非表示になり、その行にある他の「Counter」が左または右に移動した場合、「ExecuteMove」メソッドは「Row」と「Column」を更新し、現在表示されていないもので何かを行う必要がありますその位置にあった「カウンター」。

しかし、すべてのゲームロジックをテストしたとき、あなたはすでにこのすべてを解決しましたよね? UIに実装する必要があるのは、コンソールに印刷するために構築したメソッドと同等のメソッドだけです。 これだけがボード内のすべての「Counter」を反復処理し、状態に基づいて「PictureBox」を更新します。

主にa)あなたの問題を完全に理解していない、b)実際にあなたのために宿題をしようとしているわけではないからです。


1


Clickイベントハンドラーでクリックした画像ボックスを見つける必要があります。 そのためにsender引数を使用できます。 簡単に:

    private void pictureBoxCounter_Click(object sender, EventArgs e)
    {
      PictureBox box = sender as PictureBox;
      box.BackColor = System.Drawing.Color.Coral;
    }

ただし、ゲームロジックも実装する必要があります。これには、ゲームボード上のボックスの位置を知る必要があります。 そのためにPictureBox.Tagプロパティを使用できます。 たとえば、Pointを保存できます。

...
                    pictureBoxCounter[j, i].BackColor = System.Drawing.Color.Transparent;
                    pictureBoxCounter[j, i].Tag = new Point(j, i);
                    panelGame.Controls.Add(pictureBoxCounter[j, i]);
...

    private void pictureBoxCounter_Click(object sender, EventArgs e)
    {
      PictureBox box = sender as PictureBox;
      box.BackColor = System.Drawing.Color.Coral;
      Point pos = (Point)box.Tag;
      int row = pos.X;
      int col = pos.Y;
      //etc...
    }

ただし、おそらく行と列の番号だけでなく、より多くの情報を格納するヘルパークラスを使用することをお勧めします。