14. Event-Handling イベント処理 (Event Handling) 今回は Windows の Form アプリケーションで 様々なイベント を表示する時のプログラムです 題材として 以下のプログラムを使います 何のプログラムか? 見ての通りです 全く同じプログラムで 先頭 の数行を変更するだけでサイズや通路の広さを変えることができます 試してみてください なお 縦 と 横 のサイズは一致させています 今回のプログラムでは プログラムの主要なパーツは ファイルで提供します 関数群は提供されたファイルからコピーし Form1_parts.h のファイル名で manaba にアップしますので 必要に応じてダウンロードしてください 但し Event 処理などのプログラムの骨格となる部分は 各自が生成してください 1
13.Sorting-Algorithm まず 教材の先頭部分です 定義を行います #define MAZE_SIZE 31 #define BLOCK_SIZE 10 #define SPACE 0 #define WALL 1 #define ENTRANCE 2 #define EXIT 3 #define I_AM_HERE 4 MAZE_SIZE は 迷路のサイズで 必ず奇数で設定してください 理由は 壁 通路 壁 通路と組み合わせていって 最後は壁になるため 迷路を表す行列 のサイズが必ず奇数になるためです ブロックサイズは 通路の幅 で ピクセル数で指定します 従って この迷路を実現する には 迷路のゾーンは 31 10 = 310 で 310 ピ クセル以上の大きさに設 定します 各自 適当な数値 に変えて試してみてください 次に Form に部品を配置してください 今回は 全部で部品数は 5 つです Button makemaze 迷路の作成 ボタン Label elapsed 経過時間表示用 Label label1 メッセージ表示 PictureBox zone 描画領域 Timer timer1 時間カウント用 2
14. Event-Handling また 変数は以下のものを使います array<int,2> ^maze; Bitmap^ bmppicbox; int current_x, current_y; int span_sec, span_min; SolidBrush ^brushblue; SolidBrush ^brushyellow; SolidBrush ^brushgreen; SolidBrush ^brushwhite; SolidBrush は ペンキ塗りのハケ です 予め 青 黄色 緑 白 を用意しておいて描画に使用します span_sec, span_min には 経過秒 経過分を記録します current_x, current_y は 今現在の X 座標と Y 座標を保存します bmppicbox は Bitmap で zone のグラフィクス領域を予め取得しておきます これらの実体定義を #pragma endregion の後に置きます これらの変数の コンストラクタ デストラクタも忘れず実行してください 3
13.Sorting-Algorithm ここで まず Form1 の属性 KeyPreview を true に設定します これは 迷路を抜ける操作のためにキーボ ードから読み込んだ char データ をプログラムで読み込めるようにします makemaze ボタンは このボタンが押されると 迷路の作成処理 を実行します make_maze(); という関数を用意してあるので ボタンが押されたら make_maze() をコールするようにプログラムして下さい ボタンが押された時の処理は 画面上のボタンをダブルクリックすることで 関数 の入れ物が自動的に生成されます 4
14. Event-Handling ここから 今日の新しい内容です 画面に配置した様々な部品には Event が定義されています Form1 に対してイベント属性の定義を表示させてください Click は クリックされた 時に呼び出される関数を定義します DoubleClick は ダブルクリックされた 時の関数 他にも マウスが範囲内に入った時の処理関数など 様々な イベン ト を定義することができます Form のデザイン画面上でダブルクリックした時に自動生成される イベントは 1 種類ですが 実際には様々なイベントがあります ここでは KeyPress イベントに対するイベントハンドラを登録し て キー入力を表示させずに制御用に取り込んでみます Form1 のイベントの KeyPress の関数入力部でダブルクリックします そうすると Form1.h には Form1_KeyPress というイベン トハンドラ関数が自動生成されます これはちょうど makemaze ボタンをクリックした時に makemaze ボタンのクリック用イベントハンドラが自動生成され たのとおなじことです この自動生成されたイベントハンドラから key_proc( ); という関数 をコールしてみましょう 但し ここではキーコードを処理するので e -> KeyChar というパラメータを手渡します key_proc( (int)e->keychar ); 5
13.Sorting-Algorithm さらに 今回は新しく Timer のイベントを定義しました ここでは 時計 を動かすだけのためにタイマーを使っていますが 実際のゲームでは 0.2 秒ごと (1 秒間に 5 コマ ) などの早さで キャラクターの絵を変化させるのに使ったりします ここで タイマー のデザインアイコンをクリックして プロパティを表示させてみてください Interval という値があります ミリ秒単位でタイマーを起動することができます Enabled のプロパティ値が True になると このタイマーは起動します ここでは 1000 ミリ秒に設定しましょう タイマーの値が設定値になった時 (1000 になった時 ) に 呼び出される関数を イベント定義のペインで設定します Tick の部分をダブルクリックすると Tick のイベントハンドラが自 動的に生成されます タイマーが時間になった時の処理 は 付属のファイルに含まれていますので それを使ってください 今回は 自動生成された Tick のイ ベントハンドラでは timer_tick( ); という関数をコールするだけで実装ができます 6
14. Event-Handling ここまでの イベントハンドラと パラメータの宣言部の画面を見ると 次のようになっています 報告課題(1) 上記の説明に従い manaba からダウンロードした関数も活用して 迷路プログラムを完成させてください 実行時のスクリーンショットを添付してください ここまでで C 評価 (6 点相当 ) とします 報告課題(2) 迷路のサイズを変えて 動作させ 変更点について説明し サイズを変えた迷路のスクリーンショットを添えて報告してください ( ここまでで評価を1 段階上げ 漏れがなければ B 評価とします ) 報告課題(3) 迷路作成から 30 秒が経過すると Time Out で Game Over となるようにプログラムしてください ここまでの報告で A 評価とします (10 点満点中 8 点 ) 報告課題 (4) 迷路作成アルゴリズムの問題です 現在のアルゴリズムは 何も接続されてい ない柱 を 必ず 壁 に接続するようにプログラムされています 7
13.Sorting-Algorithm 壁 mark 配列には 2 が格納されています これによって 出方が1 通りの迷路 ができるようになります 柱を柱に接続し 外側の壁につながっていない 壁 も生成可能とするには まだ壁に接続されていない柱(mark が 1) を まだ壁に接続されていない柱 と接続させても構わない というアルゴリズムに修正すると 出方 が複数とおりある迷路となります 接続先の mark 配列が 1 であっても 壁を作る ようにアルゴリズムを修正して 出来上がった迷路を比較してください ここまでの報告で S 評価とします (10 点満点中 9 点 ) 報告課題(5) 出方が複数ある迷路で 乱数 によって 障害物 を生成させると どんな画面になるか プログラムに挑戦してみて下さい 障害物は 赤い とします この課題に成績の上限は設けません 8