第 10 章

第 10 章
動きのあるゲーム
ここでは、オブジェクトの移動、キーボードからの入力判定について学んだ後、
動きのある本格的なゲームを作成しましょう。
10.1 オブジェクトの位 置
オ ブ ジ ェ ク ト の 位 置 も プ ロ パ テ ィ で す 。 L o c a t i on プ ロ パ テ ィ を 見 る こ と で オ ブ ジ
ェ ク ト の 座 標 が わ か り ま す 。 ま た 、 L o ca t i on プ ロ パ テ ィ を 変 更 す る こ と で オ ブ ジ ェ
ク ト の 位 置 を 変 更 で き ま す 。 L o c a t i on プ ロ パ テ ィ は X 座 標 と Y 座 標 が く っ つ い た
Po in t と い う 名 前 の 構 造 体 で す 。L o c a t i o n . X が X 座 標 の 値 、L o ca t i o n . Y が Y 座 標 の 値
で す 。 な お 、 L o ca t i on プ ロ パ テ ィ が 表 し て い る 座 標 は 、 そ の オ ブ ジ ェ ク ト の 左 上 の
点の座標です。
【 例 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)
L o c a t i o n プ ロ パ テ ィ を 用 い ず に 、 L e f t プ ロ パ テ ィ と To p プ ロ パ テ ィ に よ り オ ブ ジ ェ
ク ト の X 座 標 と Y 座 標 を 別 々 に 参 照 ま た は 設 定 す る こ と も で き ま す 。 な お 、 Left と
To p は プ ロ パ テ ィ ウ ィ ン ド ウ に 表 示 さ れ て い ま せ ん が 、 L e f t に 値 を 設 定 す る と
L o c a t i o n . X の 値 が 、 To p に 値 を 設 定 す る と L o ca t i on . Y の 値 が か わ り ま す 。
【 例 4 】 PictureBox1 の X 座 標 と Y 座 標 の 値 を 、 Left と Top プ ロ パ テ ィ に よ り 、 そ れ ぞ
れ TextBox1 と TextBox2 に 表 示 す る 。
TextBox1.Text = PictureBox1.Left
TextBox2.Text = PictureBox1.Top
1
【 例 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 を 使 用 し て 、 指 定 し た 時 間 間 隔 で オ ブ ジ ェ ク ト の 位 置 を 更 新 す る こ と で オ ブ
ジェクトに動きを持たせることができます。
例 題 10.1 ハ ー ト の 絵 を 描 い て ピ ク チ ャ ー ボ ッ ク ス に 絵 を 貼 り 付 け ハ ー ト が 上 か
ら下に向かって動くように見えるプログラムを作りなさい。
P i c t u re B ox 1
Image
にハートの絵 を設定
SizeMode を AutoSize に変更
For m 1
BackColor を White に変更
Enabled を True
Interval を 50 に変更
Private Sub Timer1_Tick(…省略…) Handles Timer1.Tick
PictureBox1.Top = PictureBox1.Top + 5
’PictureBox1を下に5ピクセル移動
End Sub
2
例 題 10.2 ハ ー ト の 絵 が 下 に 移 動 し て 見 え な く な っ た ら も う 一 度 上 か ら 現 れ る よ
う に 例 題 10.1の プ ロ グ ラ ム を 改 良 し な さ い 。
Private Sub Timer1_Tick(…省略…) Handles Timer1.Tick
If PictureBox1.Top < Me.Height Then
’PictureBox1のTopの値がForm1の高さ未満の場合
PictureBox1.Top = PictureBox1.Top + 5
Else
’PictureBox1を下に5ピクセル移動
’条件が成立しなかった場合
PictureBox1.Top = -PictureBox1.Height
’PictureBox1を上に移動
End If
End Sub
P i c tu re B ox 1 . H e ig h t は 、 P i c t u re B ox 1 の 高 さ ( Y 方 向 の 長 さ ) を 表 し ま す 。 こ の プ ロ
グ ラ ム で は 、P i c tu re B ox 1 を 上 に 移 動 さ せ る 時 に 、オ ブ ジ ェ ク ト が 完 全 に 見 え な い 位
置 か ら 表 示 さ せ る た め に To p プ ロ パ テ ィ に – P i c t u r e B o x 1 . H e i g h t を 代 入 し て い ま す 。
PictureBox1.top の基準となる点
PictureBox1.top の基準となる点
原点座標
原点座標
( 0, 0 )
( 0, 0 )
PictureBox1.top が 0
PictureBox1.top が – P i c t u r e B ox 1 . H e ig h t
3
例 題 10.3 ハートをク リ ッ ク す る ゲ ー ム を 作 り ま し ょ う 。
Label1
P i c t u re B ox 1
Image
に ハートの絵
SizeMode を AutoSize
を設定
に変更
For m 1
BackColor を White に変更
Enabled を True
Interval を 50 に変更
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
4
9.2 キーボード入 力 の判 定
キ ー ボ ー ド が 押 さ れ た と き に 処 理 を 行 い た い 場 合 に は 、 Ke y P re s s イ ベ ン ト ま た は
Ke y D o wn イ ベ ン ト を 用 い ま す 。 Ke y P re s s イ ベ ン ト は 、 文 字 キ ー を 押 し た と き に 発 生
し 、 Ke y D o w n イ ベ ン ト は 文 字 キ ー だ け で な く 矢 印 キ ー や フ ァ ン ク シ ョ ン キ ー を 押 し
たときにも発生します。
Ke y P re s s イ ベ ン ト プ ロ シ ー ジ ャ を 作 成 す る 場 合 、 ま ず 、 コ ー ド ウ ィ ン ド ウ の 上 部
に あ る 左 の プ ル ダ ウ ン メ ニ ュ ー で Fo rm 1 イ ベ ン ト を 選 択 し ま す 。
①クリック
②クリック
次 に 、 右 の プ ル ダ ウ ン メ ニ ュ ー か ら Ke y P re s s を 選 択 し ま す 。
③クリック
④クリック
5
次のようなコードが自動的に生成されますので、Private Sub Form1_KeyPressとEnd Sub の間に文字
キーが押されたときに実行させたいイベントプロシージャを記述します。
Private Sub Form1_KeyPress(…省略…) Handles Me.KeyPress
End Sub
Ke y P re s s イ ベ ン ト に お い て ど の 文 字 キ ー が 押 さ れ た か は 、e . Ke y C h a r に よ り 知 る こ
と が で き ま す 。 押 し た 文 字 キ ー が そ の ま ま e . Ke y Ch a r の 値 と し て 入 っ て い ま す 。
【 例 1 】 文 字 キ ー が 押 さ れ た と き 、 L a b e l 1 に そ の 文 字 を 表 示 さ せ る に は 、 Ke y P re s s
のイベントプロシージャに次のプログラムコードを書きます。
P r iva t e S u b Fo r m 1 _ Ke y P re s s (… 省 略 … ) H a n d l e s M e . Ke y P r e s s
L a b e l1 .Te xt = e . Ke y C h a r
End Sub
【 例 2 】 例 1 の Ke y P re s s の イ ベ ン ト プ ロ シ ー ジ ャ が 書 か れ て い る と き に 、 キ ー ボ ー
ド か ら a の キ ー を 押 す と Label1に a と 表 示 さ れ ま す 。
【 例 3 】 例 1 の Ke y P re s s の イ ベ ン ト プ ロ シ ー ジ ャ が 書 か れ て い る と き に 、 シ フ ト キ
ー を 押 し た 状 態 で キ ー ボ ー ド か ら a の キ ー を 押 す と Label1に A と 表 示 さ れ ま す 。
文 字 キ ー 以 外 の キ ー が 押 さ れ た と き に 処 理 を 行 い た い 場 合 は 、 Ke y D o w n イ ベ ン ト
を 用 い ま す 。Ke y D o wn イ ベ ン ト に お い て ど の キ ー が 押 さ れ た か は 、e . Ke y C o d e に よ り
知 る こ と が で き ま す 。 代 表 的 な キ ー コ ー ド を 表 10.1に 示 し ま す 。
表 10.1
代表的なキーコード
テンキー
テンキー
数字
記号
アルファベット
数字
A
65
O
79
0
48
0
96
*
106
:*
186
B a ck S p a c e
8
B
66
P
80
1
49
1
97
+
107
;+
187
En t e r
13
C
67
Q
81
2
50
2
98
,<
188
S h if t
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
Pa g e U p
33
H
72
V
86
7
55
7
103
[{
219
Pa g e D o w n
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
6
記号
制御キー
【 例 4 】 キ ー が 押 さ れ た と き 、 L a b e l1 に 押 さ れ た 文 字 を 表 示 さ せ る に は 、 KeyDownの
イベントプロシージャに次のプログラムコードを書きます。
Private Sub Form1_KeyDown(…省略…) Handles Me.KeyPress
Label1.Text = e. KeyCode
End Sub
【 例 5 】 例 4 の KeyDownのイベントプロシージャが書かれているときに、キーボードの a のキー
を押すとL a b e l 1 に 65 と表示されます。
【 例 6 】例 4 の KeyDownのイベントプロシージャが書かれているときに、キーボードのシフトキー
を押すとL a b e l 1 に 16 と表示されます。
【 例 7 】例 4 の KeyDownのイベントプロシージャが書かれているときに、キーボードの左矢印キー
を押すとL a b e l 1 に 37 と表示されます。
【 例 8 】例 4 の KeyDownのイベントプロシージャが書かれているときに、キーボードの右矢印キー
を押すとL a b e l 1 に 39 と表示されます。
【 例 9 】 上 下 左 右 の 矢 印 キ ー を 押 す と 、 P i ct u re B ox 1 が 押 し た 矢 印 の 方 向 に 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
Ke y s . B a c k
Alt
Ke y s . M e n u
←
Ke y s . L e f t
Enter
Ke y s . E n t e r
スペース
Ke y s . S p a c e
↑
Ke y s . U p
Shift
Ke y s . S h i f t Ke y
Pa g e U p
Ke y s .Pa g e Up
→
Ke y s . R i g h t
C tr l
Ke y s . C on t ro l Ke y
Pa g e D o wn
Ke y s .Pa g e D o wn
↓
Ke y s . D o wn
7
【例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
< Po i n t > Ke y P re s s イ ベ ン ト プ ロ シ ー ジ ャ 内 で 押 さ れ た キ ー を 知 る の に 、 e . Ke y Ch a r
を 使 い ま す 。 ま た 、 Ke y D o w n イ ベ ン ト プ ロ シ ー ジ ャ 内 で は e . Ke y C o d e を 使 い ま す 。
例 題 1 0 . 4 天 使 の 絵 を 描 い て ピ ク チ ャ ー ボ ッ ク ス に 絵 を 貼 り 付 け 、矢 印 キ ー に よ り
動かしてみましょう。
For m 1
BackColor を White に変更
P i c t u re B ox 1
Image
に
天使の絵
を設定
SizeMode を AutoSize
に変更
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
8
例 題 10.5 飛 ん で く る ハ ー ト を 、 天 使 の 矢 に よ り 射 抜 く ゲ ー ム を 作 り な さ い 。 こ の
ゲームは、ハートを射抜くと得点が増えていきます。なお、天使は矢印きーにより
操作し、矢はスペースキーで発射するものとします。
Label1
Te x t を 0 に 変 更
P i c t u re B ox 1
Image
に ハートの絵
SizeMode を AutoSize
を設定
に変更
For m 1
BackColor を White に変更
P i c t u re B ox 2
Image
に
天使の絵
を設定
SizeMode を AutoSize
に変更
P i c t u re B ox 3
Image
Enabled を True
に矢の絵
を設定
SizeMode を AutoSize
Interval を 50 に変更
に変更
プ ロ グ ラ ム に お い て 、 ハ ー ト と 天 使 の 衝 突 と 矢 命 中 の 判 定 部 分 の if文 内 で 用 い た
数値は、使用した絵の大きさとどの部分を命中と判断するかを考慮に入れて決めて
います。なお、今回使用したピクチャーの大きさは以下のとおりです。
表 10.2
使用した絵の大きさ
横
縦
ハート
84ピ ク セ ル
70ピ ク セ ル
天使
114ピ ク セ ル
133ピ ク セ ル
矢
10ピ ク セ ル
70ピ ク セ ル
9
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
置を決定する
10
End If
End If
End Sub
Private Sub Form1_Load(…省略…) Handles MyBase.Load
Randomize()
PictureBox3.Top = -100
'乱数系列の初期化
'矢を見えない位置に移動
a = 5 * Rnd() - 2
End Sub
11
練 習 問 題 10
【1】 例 題 1 0 . 3 の ハ ー ト の 数 を 増 や し な さ い 。 ま た 、 制 限 時 間 も 付 け な さ い 。
【2】ハ ー ト が 右 か ら 左 へ 飛 ん で く る よ う に 例 題 1 0 . 5 の プ ロ グ ラ ム を 改 良 し な さ
い。また、ハートの数も増やし制限時間も付けなさい。
【 3 】 せ ま っ て く る ワ ニ を ク リ ッ ク し て 撃 退 す る ゲ ー ム を 作 り な さ い 。ワ ニ を ク リ ッ ク す
ると得点が増えていきクリックされたワニはもと位置にもどります。フォームの下
のラインまでワニが進むと噛まれたことになり減点されるようにしなさい。また、
制限時間も付けなさい。
12
附録
13
14