カウンタ

  キーボードからの入力

Google
▲探し物はこちら

 画面を見るだけなら問題ないのですが、ゲームなどではキーボードなどを使ってユーザーが何らかの入力を行うはずです。今回はキーボードの入力を受けられるようにしたいと思います。
 本来ゲーム用途であれば「DirectInput」を使う方法もありますが、それは別項目なのでそちらのページを参照してください。

 押したキーの名前が画面に文字として表示されます。

キーボードからの入力

 下のリンクから今回のプロジェクトをダウンロードできます。

ファイル名 言語 サイズ バージョン
inputkeyboard_cs_1_1.zip C# 22KB 1.1
inputkeyboard_vb_1_1.zip VB.NET 28KB 1.1
inputkeyboard_cpp_1_1.zip C++/CLI 13KB 1.1

 今回のメインコードファイルを載せます。重要なコードを赤色で表示させています

MainSample.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace MDXSample
{
    /// <summary>
    /// メインサンプルクラス
    /// </summary>
    public partial class MainSample : IDisposable
    {
        /// <summary>
        /// キーのプレス判定
        /// </summary>
        private bool[] _keys = new bool[256];


        /// <summary>
        /// アプリケーションの初期化
        /// </summary>
        /// <param name="topLevelForm">トップレベルウインドウ</param>
        /// <returns>全ての初期化がOKなら true, ひとつでも失敗したら false を返すようにする</returns>
        /// <remarks>
        /// false を返した場合は、自動的にアプリケーションが終了するようになっている
        /// </remarks>
        public bool InitializeApplication(MainForm topLevelForm)
        {
            // フォームの参照を保持
            this._form = topLevelForm;

            // キーイベント作成
            topLevelForm.KeyDown += new KeyEventHandler(this.form_KeyDown);
            topLevelForm.KeyUp += new KeyEventHandler(this.form_KeyUp);

            try
            {
                // Direct3D デバイス作成
                this.CreateDevice(topLevelForm);

                // フォントの作成
                this.CreateFont();
            }
            catch (DirectXException ex)
            {
                // 例外発生
                MessageBox.Show(ex.ToString(), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return true;
        }

        /// <summary>
        /// キーボードのキーを押した瞬間
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void form_KeyDown(object sender, KeyEventArgs e)
        {
            // 押されたキーコードのフラグを立てる
            if ((int)e.KeyCode < this._keys.Length)
            {
                this._keys[(int)e.KeyCode] = true;
            }
        }
        /// <summary>
        /// キーボードのキーを放した瞬間
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void form_KeyUp(object sender, KeyEventArgs e)
        {
            // 放したキーコードのフラグを下ろす
            if ((int)e.KeyCode < this._keys.Length)
            {
                this._keys[(int)e.KeyCode] = false;
            }
        }

        /// <summary>
        /// メインループ処理
        /// </summary>
        public void MainLoop()
        {
            // 描画内容を単色でクリアし、Zバッファもクリア
            this._device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);

            // 「BeginScene」と「EndScene」の間に描画内容を記述する
            this._device.BeginScene();


            // 文字列の描画
            this._font.DrawText(null, "キープレス判定", 0, 0, Color.White);
            int height = 24;
            for (int i = 0; i < this._keys.Length; i++)
            {
                if (this._keys[i])
                {
                    this._font.DrawText(null, ((Keys)i).ToString(), 0, height, Color.White);
                    height += 24;
                }
            }


            // 描画はここまで
            this._device.EndScene();

            // 実際のディスプレイに描画
            this._device.Present();
        }

        /// <summary>
        /// リソースの破棄をするために呼ばれる
        /// </summary>
        public void Dispose()
        {
            // フォントのリソースを解放
            if (this._font != null)
            {
                this._font.Dispose();
            }

            // Direct3D デバイスのリソース解放
            if (this._device != null)
            {
                this._device.Dispose();
            }
        }
    }
}

 では、赤文字の部分を説明していきます。MainSamplePartial.cs ファイルのコードはこちらです。


/// <summary>
/// キーのプレス判定
/// </summary>
private bool[] _keys = new bool[256];

 どのキーが押されているかのフラグを保持するために256個の bool 配列を作成しておきます。256 というのは「System.Windows.Forms.Keys」列挙型で定義されているキーのなかで一般的に使用されるキーの数です。


// キーイベント作成
topLevelForm.KeyDown += new KeyEventHandler(this.form_KeyDown);
topLevelForm.KeyUp += new KeyEventHandler(this.form_KeyUp);

 ここでキーを押したときのイベントを受けられるようにイベントハンドラを作成しています。すこし特殊な形をしていますが、このあたりは C# の仕様なので書籍などで確認してください。

 キーのイベントを受けるのはメインフォームなので、フォームのイベントに追加するようにしています。ここで追加するのは「キーを押した瞬間」と「キーを放した瞬間」です。
 そしてその処理を行うメソッドを作成しておき、「KeyEventHandler」コンストラクタに渡しています。


/// <summary>
/// キーボードのキーを押した瞬間
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void form_KeyDown(object sender, KeyEventArgs e)
{
    // 押されたキーコードのフラグを立てる
    if ((int)e.KeyCode < this._keys.Length)
    {
        this._keys[(int)e.KeyCode] = true;
    }
}
/// <summary>
/// キーボードのキーを放した瞬間
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void form_KeyUp(object sender, KeyEventArgs e)
{
    // 放したキーコードのフラグを下ろす
    if ((int)e.KeyCode < this._keys.Length)
    {
        this._keys[(int)e.KeyCode] = false;
    }
}

 これがキーを押したとき、放したときに呼ばれるメソッドです。

 ここでは単純に、キーを押したときは押されたキーのフラグを立て、放したときはフラグを下ろしています。どのキーが押されたかは「KeyEventArgs.KeyCode」に格納されているので、これを int でキャストしてそのインデックスのフラグを操作するようにしています。


this._font.DrawText(null, "キープレス判定", 0, 0, Color.White);
int height = 24;
for (int i = 0; i < this._keys.Length; i++)
{
    if (this._keys[i])
    {
        this._font.DrawText(null, ((Keys)i).ToString(), 0, height, Color.White);
        height += 24;
    }
}

 全てのキーのフラグを調べ、キーが押されている場合はそのキーを文字として出力しています。文字が重ならないように、文字を出力するごとに高さを調節しています。
 キーの文字列は、数値を「System.Windows.Forms.Keys」でキャストし、「ToString」メソッドで受け取ることが出来ます。

その他の関連情報です▼