タイマー作成②

# 初めに
投稿をサボってはいけない（戒め）
## キー入力
「Mキーが押されたら～、Xキーが押されたら～」と仕様書にある通り、今回のタイマー作成に必須なのがこのキー入力。
フォームアプリケーションなら__KeyDownメソッド__があるから楽なのですが、今回は自分で作らないといけません。
## ReadKey()
調べてみると、この__Consoleクラス__の__ReadKeyメソッド__でキー入力に関する処理を行えそうです。以下、[公式サイト](https://docs.microsoft.com/ja-jp/dotnet/api/system.console.readkey?view=netframework-4.8#System_Console_ReadKey_System_Boolean_)から。
> __オーバーロード__
> ReadKey()	
> ユーザーによって押された次の文字キーまたはファンクション キーを取得します。 押されたキーは、コンソール ウィンドウに表示されます。<br>
> ReadKey(Boolean)
> ユーザーによって押された次の文字キーまたはファンクション キーを取得します。 押されたキーは、オプションでコンソール ウィンドウに表示されます。

・・・要するに
「ReadKeyメソッドは__引数なし__だと入力したキーを標準出力して、__引数あり__だと出力するかしないか選べるよ～」
ってことですね。今回はコンソール上に出力する必要はないので~~__Console.ReadKey(false)__を使うことになりそうですね。~~
逆でした。__Console.ReadKey(true)__で標準出力なしだそうです。普通逆だろぉ。

> __戻り値__
> 押されたコンソール キーに対応する ConsoleKey 定数と Unicode 文字 (存在する場合) を記述するオブジェクト。 また、ConsoleKeyInfo オブジェクトは、1 つ以上の Shift、Alt、Ctrl の各修飾子キーがコンソール キーと同時に押されたかどうかを ConsoleModifiers 値のビットごとの組み合わせで記述します。

何を言ってるのかさっぱりですね。公式は日本語を喋ってほしい。

## ConsoleKeyInfo
調べてみると、キー情報が格納された__ConsoleKeyInfo構造体__が戻り値として渡されるそうです。
・・・そろそろややこしくなってきました。構造体とクラスの違いについては、また後日。
> __プロパティ__
> Key
現在の ConsoleKeyInfo オブジェクトが表すコンソール キーを取得します。<br>
> KeyChar
現在の ConsoleKeyInfo オブジェクトが表す Unicode 文字を取得します。<br>
> Modifiers
コンソール キーと同時に押される 1 つ以上の修飾子キーを指定する、ConsoleModifiers 値のビットごとの組み合わせを取得します。

やっとそれらしきものにたどり着きました。
この__KeyCharプロパティ__を使えば、キー入力時の処理を実現できそうですね！

## デモ
今回のキー入力はタイマーというより、むしろユーザー側の操作に関係するので、新たに__Userクラス__を作成。
### Userクラス

```cs

using System;

namespace Timer
{
    class User
    {
        public char PressedKey()
        {
            ConsoleKeyInfo keyInfo;
            if (Console.KeyAvailable)
            {
                keyInfo = Console.ReadKey(true);
                return keyInfo.KeyChar;
            }
            else
                return '\0';
        }
    }
}

```

### Timerクラス
```cs
using System;

namespace Timer
{
    /// <summary>
    /// タイマー
    /// </summary>
    class Timer
    {
        //private int min = 0;
        //private int sec = 0;
        private User user;

        public Timer()
        {
            user = new User();
        }

        private int Min { get; set; }

        private int Sec { get; set; }
        /// <summary>
        /// 時間設定中の様子を表示
        /// </summary>
        public void printTimerSetting()
        {
            Console.CursorLeft = 0;
            Console.Write("時間を設定してください");
            Console.Write("Sキー:+10秒");
            Console.Write("Mキー:+1分");
            Console.Write("Cキー:リセット");
            Console.Write("Xキー:スタート/ストップ");            
            Console.Write("{0}分：{1}秒", Min, Sec);
        }

        /// <summary>
        /// タイマーの設定を行う
        /// </summary>
        public void settingTime()
        {
            char pressedKey;
            do
            {
                pressedKey = user.PressedKey();
                switch(pressedKey)
                {
                    case 's':
                        Sec += 10;
                        break;

                    case 'm':
                        Min++;
                        break;

                    case 'c':
                        Sec = 0;
                        Min = 0;
                        break;

                    case 'x':
                        Console.WriteLine("Xキーが押されました");
                        break;
                }
                printTimerSetting();
            } while (pressedKey != 'x');
        }
    }
}

```

### Main
```cs
namespace Timer
{
    class main
    {
        public static void Main()
        {
            Timer timer = new Timer();
       
            timer.settingTime();
        }
    }
}

```

### 実行画面
![実行画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781063/dca25911-0b73-edbd-f024-2a59c281ff56.png)

画像なので分かりづらいですが、Sキーを押すと10秒、Mキーを押すと1分追加され、Cキーを押すと値がリセット、そしてXキーを押すと「Xキーが押されました」と表示されて終了します。これでタイマーをセットするのは、概ね完成しましたね。

ただ、コンソールに上書き出力する時に文字がちらつくのが気になります・・・。どうにか改善しないと。

長くなりましたが、今回はここまで。
読んでいただき、ありがとうございます。