【C#入門】第13回 タイマーについて【じゃんけんゲームを作ろう その13】

2023年2月7日

こんにちは、ノムノムです。

前回はクラスをやりました。クラスまで理解できてしまえば初心者から初級者になれると思います。

【C#入門】第12回 クラスについて【じゃんけんゲームを作ろう その12】
【C#入門】第12回 クラスについて【じゃんけんゲームを作ろう その12】
こんにちは!ノムノムです。 前回は文字列と型変換の説明をしました。 今回は、ついにクラスです。はやくクラスの説…
http://nomux2.net/class/

ここで終わりにしてしまってもよいかとは思いますが、もったいないので他の機能も紹介していこうと思います。

今回はタイマーです。

タイマー

タイマーとは読んで字のごとくタイマーです。

つまりタイマーコントロールとは指定した時間間隔でイベントを起こせるコントロールです。

コントロールの配置

タイマーコントロールは、ツールボックスの「コンポーネント」-「Timer」の中にあります。

これを選択すると以下のようになります。

プロパティ

それではプロパティを見てみましょう

Timerコントロールのプロパティは少ないですね。主要なものを解説します。

(Name)Timerコントロールの名称を指します。
Enabled真(True)の時にタイマーイベントが発生します。
偽(False)の時はタイマーイベントを停止します。
Intervalタイマーイベントが発生する時間間隔です。ms単位で入力します。

イベント関数

続きましてTimer1をダブルクリックしてみましょう。イベント関数が追加されます。

private void timer1_Tick(object sender, EventArgs e)
{

}

このイベント関数は、Intervalプロパティに設定した時間間隔(ms)ごとに呼び出されます。

さっそく使ってみましょう

じゃんけんゲームに使っていきます。
今回は、じゃんけんゲームっぽく、掛け声的に「Ready!!」→「Jan」→「Ken」→「Pon!」みたいに順番に表示してみたいと思います。

それでは以下の画像を保存して使ってください。

それでは追加してみましょう

以前の説明をしたようにimgageListとPictureBoxのコントロールを設置してみましょう。
わからなければ以下の記事を参照してください。

【C#入門】第4回 ここまでのおさらいと値の設定について【じゃんけんゲームを作ろう その4】
【C#入門】第4回 ここまでのおさらいと値の設定について【じゃんけんゲームを作ろう その4】
こんにちは。ノムノムです。 前回はイベントをやりました。イベント単位で処理を書くことができるのでソースコードが…
http://nomux2.net/substitution/

以下のようになればOKです。

imageListの追加
PictureBoxの追加

あとReadyボタンも追加してください。

イベント関数の記述

イベント関数の中は、1秒(1000ms)ごとに回るようにします。(Timer1のIntervalプロパティは1000に設定)

それではTimerイベントに追加してみます。

private void timer1_Tick(object sender, EventArgs e)
{
    if (status > 3)
    {
        //表示を消す
        this.picReady.Visible = false;

        //状態を0に
        status = 0;

        //タイマーを止める
        this.timer1.Enabled = false;

        //処理を抜ける
        return;
    }

    //Redy、Jan、ken、Ponの絵をセットする
    this.picReady.Image = this.imgReadyList.Images[status];

    status++;   //ステータスを移行

}

解説します。Timerイベント関数に入ってきたら変数statusをカウントアップします。この変数statusは状態を管理するための変数になります。

つまり、今はReadyなのかJanなのかKenなのかPonなのか勝負が終わったのかを管理するために使っています。

どの値がどういう状態なのかはこちらで決めます。私は0は「Ready」、1は「Jan」、2は「Ken」3は「Pon」、3以降は勝負完了という風にしました。

というわけで他にも必要なものがあります。まずは変数statusの宣言です。

namespace ProjectJanken
{
    public partial class Form1 : Form
    {

        System.Random r = new System.Random();
        int[] array_match_result = new int[0];
        private ClassRobo robo = new ClassRobo();
        int status = 0;     //状態管理

あとは画面をじゃんけんを始める準備状態にしてタイマーを起動するための関数を用意します。

//Readyボタンをクリックしたときに発生するイベント関数
private void btnReady_Click(object sender, EventArgs e)
{
    //じゃんけん開始
    MatchReady();
}

//じゃんけんの準備をするための関数
private void MatchReady()
{
    this.picCPU.Image = null;         //CPUの手を消去
    this.picYou.Image = null;         //あなたの手を消去
    status = 0;                       //初期状態にする
    this.timer1.Enabled = true;       //タイマー起動
    this.picReady.Visible = true;     //Ready画像の表示
}

動かしてみます。

なんかそれっぽくなりました。

まとめ

遊んでいるとわかるのですが、 このままではダメなことがあります。

一つ目は、じゃんけんポンと実際にグーチョキパーを出すところが処理が分かれてしまっているので、遅出しとか早すぎとかそういう判定がありません。変数statusが現在の状態をもっているので同期をとるのに役立ちそうです。

二つ目に、Ready、Jan、Ken、Ponを表示するPictureBoxが透過できていないことです。 PictureBox のBackColorプロパティを「Transparent(透過)」にすればいけるように思えますが、親コントロールにだけ透けるようです。この場合親コントロールはForm1になります。つまりpicRoboコントロールは親じゃないので透けないということです。ここらへんがポイントですね。

こういうのを直すのも自分で考えてどんなふうにすればいいか試行錯誤するのもプログラミングの楽しい部分です。
業務だと時間に追われて楽しんでる場合ではないのですが、僕は仕様を考える時や困った時などそれをどうやって実現させようかなって考えてる時がプログラミングで一番好きです。