Visual StudioとC#を初めて使ってブロック崩しゲームを作ってみた②


![u9N4og9PN6gH1A7Lxa6o1586313765-1586313833.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/e622c859-441a-fd14-baa1-a4c0a814679b.gif)
前回の続きになります。

ホーム画面からプレイ画面をダイアログ表示し
ゲームを失敗したらリザルト画面へ遷移するようにします。
丁寧に解説している故に記事が長くなってしまうのでリザルト画面は第3回に投稿します。

ダイアログ表示だけを学びたい人は
前回の参照サイトをプロジェクト(Form1)の作成まで実施してください。

前回：[参照](http://nn-hokuson.hatenablog.com/entry/2017/08/17/200918)
ブロック崩しゲームを始めから作りたい人は→：[Visual StudioとC#を初めて使ってブロック崩しゲームを作ってみた①](https://qiita.com/oh_yeah_sayryo/items/a25bddf030dcc9d9f864)



まずはForm1の画面に別ウィンドウを追加しようと思います。
##画面追加
画面右側の「ソリューションエクスプローラー」の「プロジェクト名」を右クリック
「追加」→「新しい項目の追加」を選択。
Windowsフォームを選択し、名前は「Form2.cs」で追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/e9b8f923-e364-a354-6fce-13bf40a9da7f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/8fdc6172-6e53-4c4e-1a58-127fd38e6581.png)
すると、Form2が作成されます。
これで表示される画面の準備はOK！

次はボタンを設置します。
Form1からForm2に遷移させたいのでForm1の画面にボタンを設置します。
Form1のデザイン画面(Form1.cs)を表示し、「表示(V)」→「ツールボックス」→「コモンコントロール」
→「Button」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/e7b277f5-ad21-469f-6f40-344eec421112.png)
画面にマウスホールドして適当な四角形を作ったらボタンフォームが表示されます。
（「Button」クリック後画面任意箇所クリックしても設置できます。）

ボタンを右クリック→「プロパティ」でプロパティが右下に表示されるので、
ここでボタンに表示されるテキストを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/71f1ed61-0cc1-3c09-b8d0-3d5589f6ddf6.png)

ボタンをクリック時に動作させたいので
⚡マークのイベントをクリック→アクション欄にある「Click」で処理を行うメソッド名を決めます。
Form2をホーム画面にするので、ここでは「home_Click」と命名します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/b690c004-dfcb-2f0e-9827-63ffb7bf6df0.png)

すると、Form1.csにメソッドが自動生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/ad650066-218d-3d91-95d6-8dd3c87b5349.png)

生成されたメソッドにForm2を表示する処理を記述します。

```Form1.cs
private void home_Click(object sender, EventArgs e)
        {
            // Form2のインスタンスを生成
            Form2 form2 = new Form2();
            // form2を表示
            form2.Show();
        }
```


実行(F5)してみてください。
ボタンを押すと別ウィンドウが表示されるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/cb50cb9d-ebf9-2910-88bb-0fa2a5ed36bc.png)
***※実はここでパドルの操作が効かなくなっています。
後のホーム画面作成時に原因・対策を追記しましたのでこのまま進めてください。***
##ダイアログ表示
一応完成しましたが、このままではボタンを押下する毎にウィンドウが表示されます。
開いた画面を閉じないと元の画面を触れないのが一般的だと思うのでダイアログ表示にします。

`form2.Show() → form2.ShowDialog()`に変更するだけです。
初心者向け支記事なので文字補完を使ってみましょう。
「Show」にカーソルを合わせ　Ctrlとスペースキーを同時に押下すると候補が表示されるので、
ここから「ShowDialog」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/3acc9cf3-4626-e012-da88-aad6a96ba716.png)

実行してみてください。
Form2を閉じないとボタンをクリックできなくなっています。

##ホーム画面作成
Form2の画面をスタート画面にします。

Form1のときと同じようにForm2にボタンを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/20635a9f-89c5-e31e-e032-df3f9f86a17a.png)
ボタン名はスタート。
メソッド名はstart_Clickにします。

メソッドが自動生成されたはずなので、
Form1へ遷移する処理を記述します。

```Form2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Breakout
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void start_Click(object sender, EventArgs e)
        {
            // 以下の処理を追記する！!

            // Form1のインスタンスを生成 
            Form1 form1 = new Form1();
            // form1を表示
            form1.ShowDialog();
        }
    }
}
```
実行すると遷移できましたね。
![CriILA193PpPJSG6Q5v01586149345-1586149356.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/e0a09578-ab38-d2da-8607-f42746c79985.gif)

初期起動時にスタート画面を表示するようにします。
ソリューションエクスプローラーから「Program.cs」を開きます。
ここで最初に開く画面を設定しています。
Form1から2へ変更します。
`Application.Run(new Form1()); → Application.Run(new Form2());`
実行してみてください。
ホーム画面が最初に表示されたらOKです。

###※追記
試しにゲームをしてみたらパドルが動きませんでした。
キーイベント処理がある画面でボタンを設置すると
キーイベントが発生しなくなるようです。
home_Clickとボタンを削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/82aba523-67a6-d9b7-74d0-b79ee0ba67b5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/cfe13df5-d93b-b55b-591c-f272fdfd3378.png)


##ボール速度変更ボタン


Form2デザインから「表示」→「ツールボックス」
→「ComboBox」と「Label」を選択して画面に設置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/1d355672-7e72-adfb-cc4f-f1d9f41620ce.png)


各テキストは以下のように設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/844e592b-f3e2-90de-10fb-3ae1c6d9c8d5.png)

コンボボックスにリストを作成します。
作成したコンボボックスを右クリックしプロパティを開いて
「item」の「コレクション」をクリックすると
右端に「・・・」メニューが現れるのでクリック。
エディターが開くので、1行毎に選択リスト用テキストを入力します。
「Easy」「Normal」「Hard」「Expert」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/11d286d1-0e86-cd6b-5add-e181eb60686f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/469fec46-08ac-0e73-e763-928811082d9c.png)

コンボボックスにイベントを設定します。
以下のイベントはリスト選択する毎に処理が流れて値を取得してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/b837b494-bed3-f825-b7c0-6652893dd246.png)


ホーム画面(Form2)のコードは以下になります。

```Form2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;

namespace Breakout
{
    public partial class Form2 : Form
    {
        //ボールの速度(x, y)
        public static int x { get; set; }
        public static int y { get; set; }


        public Form2()
        {
            InitializeComponent();
        }

        private void start_Click(object sender, EventArgs e) //スタートボタン
        {
            mode_Select(sender, e);

            // Form1のインスタンスを生成
            Form1 form1 = new Form1();
            // form1を表示
            form1.ShowDialog();
           
        }

        private void mode_Select(object sender, EventArgs e) //モードセレクト
        {
            int selectedMode = comboBox1.SelectedIndex;
            switch (selectedMode)
            {
                case 0:
                    //Easy
                    x = -2;
                    y = -4;
                    break;
                case 1:
                    //Normal
                    x = -3;
                    y = -6;
                    break;
                case 2:
                    //Hard
                    x = -5;
                    y = -10;
                    break;
                case 3:
                    //Expert
                    x = -8;
                    y = -16;
                    break;
                default:
                    //未選択時はNormal
                    x = -3;
                    y = -6;
                    break;
            }
        }
    }
}
```
解説をします。
選択したボール速度を次のForm1画面へ渡すため、
x軸をx、y軸をyとします。
C#にグローバル変数はないので、どうやってこのxy値を渡すかは以下記事参考にしました。
　　[C#にグローバル変数がない！対応策](https://www.sejuku.net/blog/102720)
`comboBox1.SelectedIndex`で要素を取得できます。
中身のテキストを抜き出すコードもあるようです。
今回は要素だけを抜き出し、どのモードを選んだのかswich文で分岐させます。
後はスタートボタンクリック時の処理を書いて終わりです。

Form1画面でxyを受け取れるようにします。
1行変更するだけで簡単です。
`this.ballSpeed = new Vector(-4, -8)　→　this.ballSpeed = new Vector(Form2.x, Form2.y)`
form2.xのようにインスタンス参照ではなく、
Form2.xであることに注意。詳細は以下「グローバル変数がない！対応策」記事を読んでください。

モードを変更して実行してみてください。
Expertだと早くて、Easyだと遅ければ***OK***です！

#####次はセキュリティ面です。
モード選択時にテキストを書き換えられるのでこれを不可にします。

コンボボックスを入力不可にするにはプロパティから
DropDownstyleの「DropDown」を「DropDownList」へ変更するだけです。

(プログラムから設定する場合は以下のようにします。
`comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;`)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/985dda2c-d58d-5606-4d4f-b738fbd8d774.png)

するとグレーアウトし入力不可になっています。
デフォルト(Normal)とボックス内に書いていましたが消えてしまったので
ラベルを「Modo：デフォルト(Normal)」へ書き換えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/23bc17b1-8aeb-ca92-c87c-d3f2a0fe4119.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/21afebd3-82a4-40b0-ac9d-20e17d5e0466.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/b650fd50-1f36-3020-fe6e-9e0e2785cc34.png)

***これでホーム画面は完成です！***

##感想
簡単でしたね！
かなりわかりやすかったのでは？ww
丁寧すぎたかも・・・それはそれでヨシ！
ツールボックスの位置とか
プロパティの使い方に慣れてきました！
にしても未だにタスクを振られていない・・
引き続きゲーム作っていくかあ（仕事中）

次はリザルト画面の作成です！↓
[Visual StudioとC#を初めて使ってブロック崩しゲームを作ってみた③](https://qiita.com/oh_yeah_sayryo/items/68fab28be412a49de315)