こ こ で は 、 オ ブ ジ ェ ク ト の 移 動 、 キ ー ボ ー ド か ら の 入 力 判 定 に つ い て 学 ん だ 後 、 動 き の あ る 本 格 的 な ゲ ー ム を 作 成 し ま し ょ う 。
10.1 オブジェクトの位 置
オ ブ ジ ェ ク ト の 位 置 も プ ロ パ テ ィ で す 。Location プ ロ パ テ ィ を 見 る こ と で オ ブ ジ ェ ク ト の 座 標 が わ か り ま す 。 ま た 、Location プ ロ パ テ ィ を 変 更 す る こ と で オ ブ ジ ェ ク ト の 位 置 を 変 更 で き ま す 。Location プ ロ パ テ ィ は X 座 標 と Y 座 標 が く っ つ い た Point と い う 名 前 の 構 造 体 で す 。Location.X が X 座 標 の 値 、Location.Y が Y 座 標 の 値 で す 。 な お 、Location プ ロ パ テ ィ が 表 し て い る 座 標 は 、 そ の オ ブ ジ ェ ク ト の 左 上 の 点 の 座 標 で す 。【 例 1 】PictureBox1 の X 座標と Y 座 標 の 値 を そ れ ぞ れ TextBox1 と TextBox2 に 表 示 す る 場 合 、 次 の よ う に 書 き ま す 。 TextBox1.Text = PictureBox1.Location.X TextBox2.Text = PictureBox1.Location.Y 【 例 2 】PictureBox1 の 座 標 を (100, 200)に 設 定 す る 場 合 、 次 の よ う に 書 き ま す 。 Dim P As Point P.X = 100 P.Y = 200 PictureBox1.Location = P 【 例 3 】PictureBox1 の 座 標 を (100, 200)に 設 定 す る 場 合 、次 の よ う に 書 く こ と も で き ま す 。
PictureBox1.Location = New Point(100, 200)
Location プ ロ パ テ ィ を 用 い ず に 、 Left プ ロ パ テ ィ と Top プ ロ パ テ ィ に よ り オ ブ ジ ェ ク ト の X 座 標 と Y 座 標 を 別 々 に 参 照 ま た は 設 定 す る こ と も で き ま す 。 な お 、 Left と Top は プ ロ パ テ ィ ウ ィ ン ド ウ に 表 示 さ れ て い ま せ ん が 、 Left に 値 を 設 定 す る と Location.X の 値 が 、 Top に 値 を 設 定 す る と Location.Y の 値 が か わ り ま す 。
第 10 章
【 例 5 】PictureBox1 の座標を(100, 200)に設定する場合、次のように書くこともできます。 PictureBox1.Left = 100 PictureBox1.Top = 200 【 例 6 】PictureBox1 を下に 1 ピクセル移動したい場合、次のように書きます。 PictureBox1.Top = PictureBox1.Top + 1 【 例 7 】PictureBox1 を上に 1 ピクセル移動したい場合、次のように書きます。 PictureBox1.Top = PictureBox1.Top – 1 【 例 8 】PictureBox1 を右に 1 ピクセル移動したい場合、次のように書きます。 PictureBox1.left = PictureBox1.left + 1 【 例 9 】PictureBox1 を左に 1 ピクセル移動したい場合、次のように書きます。 PictureBox1.left = PictureBox1.left - 1 Timer を 使 用 し て 、 指 定 し た 時 間 間 隔 で オ ブ ジ ェ ク ト の 位 置 を 更 新 す る こ と で オ ブ ジ ェ ク ト に 動 き を 持 た せ る こ と が で き ま す 。 例 題 1 0 . 1 ハ ー ト の 絵 を 描 い て ピ ク チ ャ ー ボ ッ ク ス に 絵 を 貼 り 付 け ハ ー ト が 上 か ら 下 に 向 か っ て 動 く よ う に 見 え る プ ロ グ ラ ム を 作 り な さ い 。
Private Sub Timer1_Tick(…省略…) Handles Timer1.Tick
PictureBox1.Top = PictureBox1.Top + 5 ’PictureBox1を下に5ピクセル移動 End Sub PictureBox1 Enabled を True Interval を 50 に変更 Image にハートの絵 を設定 SizeMode を AutoSize に変更 BackColor を White に変更 Form1
例 題 1 0 . 2 ハ ー ト の 絵 が 下 に 移 動 し て 見 え な く な っ た ら も う 一 度 上 か ら 現 れ る よ う に 例 題 1 0 . 1 の プ ロ グ ラ ム を 改 良 し な さ い 。
Private Sub Timer1_Tick(…省略…) Handles Timer1.Tick
If PictureBox1.Top < Me.Height Then ’PictureBox1のTopの値がForm1の高さ未満の場合 PictureBox1.Top = PictureBox1.Top + 5 ’PictureBox1を下に5ピクセル移動
Else ’条件が成立しなかった場合
PictureBox1.Top = -PictureBox1.Height ’PictureBox1を上に移動 End If End Sub PictureBox1.Height は 、 PictureBox1 の 高 さ ( Y 方 向 の 長 さ ) を 表 し ま す 。 こ の プ ロ グ ラ ム で は 、PictureBox1 を 上 に 移 動 さ せ る 時 に 、オ ブ ジ ェ ク ト が 完 全 に 見 え な い 位 置 か ら 表 示 さ せ る た め に Top プ ロ パ テ ィ に –PictureBox1.Height を 代 入 し て い ま す 。 原 点 座 標 (0,0) PictureBox1.top が 0 原 点 座 標 (0,0) PictureBox1.top が –PictureBox1.Height PictureBox1.top の基準となる点 PictureBox1.top の基準となる点
例 題 1 0 . 3 ハ ー ト を ク リ ッ ク す る ゲ ー ム を 作 り ま し ょ う 。
Dim a As Integer ' 横方向の移動量を記憶する変数 Private Sub Timer1_Tick(…省略…) Handles Timer1.Tick
If PictureBox1.Top < Me.Height Then ' PictureBox1のTopの値がForm1の高さ未満の場合 PictureBox1.Top = PictureBox1.Top + 5 'PictureBox1を下に5ピクセル移動 PictureBox1.Left = PictureBox1.Left + a 'PictureBox1を横方向に移動 Else ' 条件が成立しなかった場合
PictureBox1.Top = -PictureBox1.Height 'PictureBox1を上に移動 PictureBox1.Left = Rnd() * (Me.Width - PictureBox1.Width) 'PictureBox1の横の位置を決定 a = 5 * Rnd() - 2 '横方向の移動量を乱数により決定 End If
End Sub
Private Sub PictureBox1_Click(…省略…) Handles PictureBox1.Click ' PictureBox1をクリックした Label1.Text = Label1.Text + 1 '点数を1点増やす PictureBox1.Top = Me.Height 'PictureBox1を下に移動 End Sub
Private Sub Form1_Load(…省略…) Handles MyBase.Load
Randomize() '乱数系列の初期化 a = 5 * Rnd() - 2 '横方向の移動量を乱数により決定 End Sub PictureBox1 Enabled を True Interval を 50 に変更 Image に ハートの絵 を設定 SizeMode を AutoSize に変更 BackColor を White に変更 Form1 Label1
9.2 キーボード入 力 の判 定
キ ー ボ ー ド が 押 さ れ た と き に 処 理 を 行 い た い 場 合 に は 、KeyPressイ ベ ン ト ま た は KeyDownイ ベ ン ト を 用 い ま す 。 KeyPressイ ベ ン ト は 、 文 字 キ ー を 押 し た と き に 発 生 し 、KeyDownイ ベ ン ト は 文 字 キ ー だ け で な く 矢 印 キ ー や フ ァ ン ク シ ョ ン キ ー を 押 し た と き に も 発 生 し ま す 。 KeyPressイ ベ ン ト プ ロ シ ー ジ ャ を 作 成 す る 場 合 、 ま ず 、 コ ー ド ウ ィ ン ド ウ の 上 部 に あ る 左 の プ ル ダ ウ ン メ ニ ュ ー でForm1イ ベ ン ト を 選 択 し ま す 。 次 に 、 右 の プ ル ダ ウ ン メ ニ ュ ー か らKeyPressを 選 択 し ま す 。 ② ク リ ッ ク ① ク リ ッ ク ④ ク リ ッ ク ③ ク リ ッ ク次のようなコードが自動的に生成されますので、Private Sub Form1_KeyPressとEnd Sub の間に文字 キーが押されたときに実行させたいイベントプロシージャを記述します。
Private Sub Form1_KeyPress(…省略…) Handles Me.KeyPress
End Sub
KeyPressイ ベ ン ト に お い て ど の 文 字 キ ー が 押 さ れ た か は 、e.KeyCharに よ り 知 る こ と が で き ま す 。 押 し た 文 字 キ ー が そ の ま まe.KeyCharの 値 と し て 入 っ て い ま す 。
【 例 1 】 文 字 キ ー が 押 さ れ た と き 、Label1に そ の 文 字 を 表 示 さ せ る に は 、 KeyPress の イ ベ ン ト プ ロ シ ー ジ ャ に 次 の プ ロ グ ラ ム コ ー ド を 書 き ま す 。
Private Sub Form1_KeyPress(…省 略 …) Handles Me.KeyPress Label1.Text = e.KeyChar End Sub 【 例 2 】 例 1 のKeyPressの イ ベ ン ト プ ロ シ ー ジ ャ が 書 か れ て い る と き に 、 キ ー ボ ー ド か ら a の キ ー を 押 す と Label1に a と 表 示 さ れ ま す 。 【 例 3 】 例 1 のKeyPressの イ ベ ン ト プ ロ シ ー ジ ャ が 書 か れ て い る と き に 、 シ フ ト キ ー を 押 し た 状 態 で キ ー ボ ー ド か ら a の キ ー を 押 す と Label1に A と 表 示 さ れ ま す 。 文 字 キ ー 以 外 の キ ー が 押 さ れ た と き に 処 理 を 行 い た い 場 合 は 、KeyDownイ ベ ン ト を 用 い ま す 。KeyDownイ ベ ン ト に お い て ど の キ ー が 押 さ れ た か は 、e.KeyCodeに よ り 知 る こ と が で き ま す 。 代 表 的 な キ ー コ ー ド を 表10.1に 示 し ま す 。 表10.1 代 表 的 な キ ー コ ー ド ア ル フ ァ ベ ッ ト 数 字 テ ン キ ー 数 字 テ ン キ ー 記 号 記 号 制 御 キ ー A 65 O 79 0 48 0 96 * 106 :* 186 BackSpace 8 B 66 P 80 1 49 1 97 + 107 ;+ 187 Enter 13 C 67 Q 81 2 50 2 98 ,< 188 Shift 16 D 68 R 82 3 51 3 99 - 109 -= 189 Ctrl 17 E 69 S 83 4 52 4 100 . 110 .> 190 Alt 18 F 70 T 84 5 53 5 101 / 111 /? 191 ス ペ ー ス 32 G 71 U 85 6 54 6 102 @` 192 PageUp 33 H 72 V 86 7 55 7 103 [{ 219 PageDown 34 I 73 W 87 8 56 8 104 ¥| 220 ← 37 J 74 X 88 9 57 9 105 ]} 221 ↑ 38 K 75 Y 89 ^~ 222 → 39 L 76 Z 90 ¥_ 226 ↓ 40
【 例 4 】 キ ー が 押 さ れ た と き 、Label1に 押 さ れ た 文 字 を 表 示 さ せ る に は 、 KeyDownの イベントプロシージャに次のプログラムコードを書きます。
Private Sub Form1_KeyDown(…省略…) Handles Me.KeyPress Label1.Text = e. KeyCode End Sub 【 例 5 】 例 4 のKeyDownのイベントプロシージャが書かれているときに、キーボードの a のキー を押すとLabel1に 65 と表示されます。 【 例 6 】例 4 のKeyDownのイベントプロシージャが書かれているときに、キーボードのシフトキー を押すとLabel1に 16 と表示されます。 【 例 7 】例 4 のKeyDownのイベントプロシージャが書かれているときに、キーボードの左矢印キー を押すとLabel1に 37 と表示されます。 【 例 8 】例 4 のKeyDownのイベントプロシージャが書かれているときに、キーボードの右矢印キー を押すとLabel1に 39 と表示されます。 【 例 9 】 上 下 左 右 の 矢 印 キ ー を 押 す と 、PictureBox1が 押 し た 矢 印 の 方 向 に 1 ピ ク セ ル 移動するプログラムは次のようになります。
Private Sub Form1_KeyDown(…省略…) Handles Me.KeyPress
If e. KeyCode = 37 Then PictureBox1.Left =PictureBox1.left – 1 ’左矢印キーに対する処理 If e. KeyCode = 39 Then PictureBox1.Left =PictureBox1.left + 1 ’右矢印キーに対する処理 If e. KeyCode = 38 Then PictureBox1.top =PictureBox1.top – 1 ’上矢印キーに対する処理 If e. KeyCode = 40 Then PictureBox1.top =PictureBox1.top + 1 ’下矢印キーに対する処理 End Sub
プログラムを書く場合に、キーコードは数字なので直感的にわかりにくいため、キーコードを示す定 数が用意されています。代表的なキーコード定数を表10.2に示します。
表10.2 代 表 的 な 制 御 キ ー を 表 す コ ー ド 定 数
BackSpace Keys.Back Alt Keys.Menu ← Keys.Left Enter Keys.Enter ス ペ ー ス Keys.Space ↑ Keys.Up
【例10】上下左右の矢印キーが押されるとPictureBox1が押した矢印の方向に1ピクセル移動するプ ログラムを、キーコード定数を用いて書くと次のようになります。
Private Sub Form1_KeyDown(…省略…) Handles Me.KeyPress
If e.KeyCode = Keys.Left Then PictureBox1.Left = PictureBox1.Left – 1 ’左矢印キーに対する処理 If e.KeyCode = Keys.Right Then PictureBox1.Left = PictureBox1.Left + 1 ’右矢印キーに対する処理 If e.KeyCode = Keys.Up Then PictureBox1.Top = PictureBox1.Top - 1 ’上矢印キーに対する処理 If e.KeyCode = Keys.Down Then PictureBox1.Top = PictureBox1.Top + 1 ’下矢印キーに対する処理 End Sub
<Point> KeyPressイ ベ ン ト プ ロ シ ー ジ ャ 内 で 押 さ れ た キ ー を 知 る の に 、 e.KeyChar を 使 い ま す 。 ま た 、KeyDownイ ベ ン ト プ ロ シ ー ジ ャ 内 で は e.KeyCodeを 使 い ま す 。
例 題 1 0 . 4 天 使 の 絵 を 描 い て ピ ク チ ャ ー ボ ッ ク ス に 絵 を 貼 り 付 け 、矢 印 キ ー に よ り 動 か し て み ま し ょ う 。
Private Sub Form1_KeyDown(…省略…) Handles Me.KeyDown
If e.KeyCode = Keys.Left Then PictureBox1.Left = PictureBox1.Left - 5 ’左矢印キーに対する処理 If e.KeyCode = Keys.Right Then PictureBox1.Left = PictureBox1.Left + 5 ’右矢印キーに対する処理 If e.KeyCode = Keys.Up Then PictureBox1.Top = PictureBox1.Top - 5 ’上矢印キーに対する処理 If e.KeyCode = Keys.Down Then PictureBox1.Top = PictureBox1.Top + 5 ’下矢印キーに対する処理 End Sub PictureBox1 Image に 天使の絵 を設定 SizeMode を AutoSize に変更 BackColor を White に変更 Form1
例 題 1 0 . 5 飛 ん で く る ハ ー ト を 、 天 使 の 矢 に よ り 射 抜 く ゲ ー ム を 作 り な さ い 。 こ の ゲ ー ム は 、 ハ ー ト を 射 抜 く と 得 点 が 増 え て い き ま す 。 な お 、 天 使 は 矢 印 き ー に よ り 操 作 し 、 矢 は ス ペ ー ス キ ー で 発 射 す る も の と し ま す 。 プ ロ グ ラ ム に お い て 、 ハ ー ト と 天 使 の 衝 突 と 矢 命 中 の 判 定 部 分 の i f 文 内 で 用 い た 数 値 は 、 使 用 し た 絵 の 大 き さ と ど の 部 分 を 命 中 と 判 断 す る か を 考 慮 に 入 れ て 決 め て い ま す 。 な お 、 今 回 使 用 し た ピ ク チ ャ ー の 大 き さ は 以 下 の と お り で す 。 表10.2 使 用 し た 絵 の 大 き さ 横 縦 ハ ー ト 8 4 ピ ク セ ル 70ピ ク セ ル 天 使 1 1 4 ピ ク セ ル 133ピ ク セ ル 矢 10ピ ク セ ル 70ピ ク セ ル PictureBox3 Image に矢の絵 を設定 SizeMode を AutoSize に変更 Text を 0 に 変 更 PictureBox2 Image に 天使の絵 を設定 SizeMode を AutoSize に変更 PictureBox1 Enabled を True Interval を 50 に変更 Image に ハートの絵 を設定 SizeMode を AutoSize に変更 BackColor を White に変更 Form1 Label1
Dim a As Integer 'ハートの横方向の移動量を記憶する変数 Dim m As Integer '矢の状態を記憶する変数
Private Sub Timer1_Tick(…省略…) Handles Timer1.Tick
If PictureBox1.Top < Me.Height Then 'フォーム内にハートがある PictureBox1.Top = PictureBox1.Top + 2 'ハートをを下に移動 PictureBox1.Left = PictureBox1.Left + a 'ハートをを横に移動 Else 'フォームから外に出たとき
PictureBox1.Top = -PictureBox1.Height 'ハートを上に移動
PictureBox1.Left = Rnd() * (Me.Width - PictureBox1.Width) 'ハートの横の位置を決定 a = 5 * Rnd() - 2
End If
If m = 1 Then 'もし、矢が発射状態ならば
PictureBox3.Top = PictureBox3.Top - 3 '矢を上へ移動 If PictureBox1.Top + 30 > PictureBox3.Top And PictureBox1.Top < PictureBox3.Top Then
If PictureBox1.Left - 10 < PictureBox3.Left And PictureBox1.Left + 70 > PictureBox3.Left Then PictureBox1.Top = -100 'ハートを上に移動
PictureBox1.Left = Rnd() * (Me.Width - PictureBox1.Width) 'ハートの横の位置を決定 a = 5 * Rnd() - 2 Label1.Text = Label1.Text + 1 '点数を増やす PictureBox3.Top = -100 '矢を飛び去った状態にする End If End If End If If PictureBox3.Top < -70 Then 'もし、矢が飛び去ってしまったら m = 0 '矢を非発射状態にする End If End Sub
Private Sub Form1_KeyDown(…省略…) Handles Me.KeyDown
If e.KeyCode = Keys.Left Then PictureBox2.Left = PictureBox2.Left - 3 If e.KeyCode = Keys.Right Then PictureBox2.Left = PictureBox2.Left + 3 If e.KeyCode = Keys.Up Then PictureBox2.Top = PictureBox2.Top - 3 If e.KeyCode = Keys.Down Then PictureBox2.Top = PictureBox2.Top + 3
If e.KeyCode = Keys.Space Then 'もし、スペースキーをが押されたら If m = 0 Then 'もし、矢が非発射状態なら m = 1 '矢を発射状態にする PictureBox3.Top = PictureBox2.Top PictureBox3.Left = PictureBox2.Left + 52 ハ ー ト に 矢 が 命 中 し た か の 判 定 ハ ー ト に 矢 が 当 た っ た と き の 処 理 ハ ー ト の 動 き 矢 印 キ ー に よ る 天 使 の 移 動 天 使 の 位 置 か ら 矢 の 初 期 位 置 を 決 定 す る
End If End If End Sub
Private Sub Form1_Load(…省略…) Handles MyBase.Load Randomize() '乱数系列の初期化 PictureBox3.Top = -100 '矢を見えない位置に移動 a = 5 * Rnd() - 2