§8 シューティング・ゲーム(1)2 プログラミング実習
 back next 

【4】 UFOの移動

 UFOをウィンドウの左端から右方向へ移動させる。右ウィンドウの端に到達したら、再び左端から現れる。このとき、画像の高さ分だけ下方向に移動する。

操作 7 タイマー(Timer1)を配置する。
 ツールボックスのコンポーネントから[Timer]をダブルクリックする。

Enabled True Interval 300 (300ミリ秒=0.3秒)

操作 8 タイマー(Timer1)のイベントに対応するメソッドを次のように作成する。
 デザインウィンドウで、[Timer]をダブルクリックすると、Timer1_Tickメソッドの定義部が表示される。

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        picUFO.Left = picUFO.Left + picUFO.Width / 3    'UFOの移動
        '右端に到達したときの処理
        If picUFO.Left > Me.ClientSize.Width Then
            picUFO.Left = 0        '左端へ移動
            picUFO.Top = picUFO.Height + picUFO.Height    '下方向へ移動
        End If
End Sub

※ UFOの水平方向の移動量は、画像の幅(Width)の1/3としている。

 UFOが下方向にも移動するので、UFOがウィンドウの一番下まできたときの処理が必要である。ここでは、それまでに爆破できるものとして処理を省略している。

 

【5】 SHIPの移動

 プレーヤが操作するSHIPを左右に移動できるようにする。移動にはキーボードの[←]と[→]を使うものとする。
 キーを押すと、KeyDownイベント、KeyPressイベント、KeyUpイベントの順でイベントが発生する。以前に使ったKeyPressイベントでは、カーソルキーなど特殊なキーでイベントが発生しないので、ここではKeyDownイベントを使う。

操作 9 フォーム(Form1)のプロパティを次のように設定する。

KeyPreview True
※ ほかのオブジェクトがキーイベントを取得する前にフォームがキーイベントを取得するように設定する。今回は、キーイベントを取得するほかのオブジェクトがないのでFalseのままでも良い。

操作 10 フォーム(Form1)のKeyDownイベントに対応するメソッドを次のように作成する。
 コードウィンドウの上部にあるクラス名を「(Form1 イベント)」に、メソッド名を「KeyDown」に変更する。(下図)

コードウィンドウ、クラス・メソッド入力ボックス

    Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode = Keys.Right Then    '[→]キー
            picSHIP.Left = picSHIP.Left + picSHIP.Width / 2    '右移動
            If picSHIP.Left > Me.ClientSize.Width - picSHIP.Width Then
                picSHIP.Left = Me.ClientSize.Width - picSHIP.Width  '↑右枠到達
            End If                                                     '↑戻す
        ElseIf e.KeyCode = Keys.Left Then    '[←]キー
            picSHIP.Left = picSHIP.Left - picSHIP.Width / 2    '左移動
            If picSHIP.Left < 0 Then    '左枠到達
                picSHIP.Left = 0       '戻す
            End If
        End If
    End Sub

※ 押されたキーデータは引数eのKeyCodeプロパティで参照することができる。また、キーデータはKeys列挙体で定義されているのでそれを利用している(下線部)。[→]キーはKeys.Right、[←]キーはKeys.Leftである。
※ SHIPの水平方向の移動量は、画像の幅(Width)の1/2として、UFOより早く移動できるようにしている(下線部)。
※ SHIPがウィンドウの右枠または左枠に到達したとき、それ以上移動しないようにしている。
結果 実行して、[←][→]キーを押すとSHIPが左右に移動する。
問題点→ SHIPが左右の枠に到達した後も[←][→]キーを押すとSHIPの表示がちらつく。原因は、移動させた後に枠到達の判定をしているからである。
 Keys列挙体については、Keysにカーソルをあわせて[F1]キーを押すとヘルプが表示される。

 

操作 11 SHIPのちらつきを解消する。フォーム(Form1)のKeyDownイベントに対応するメソッドを次のように変更する。

    Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode = Keys.Right Then    '[→]キー
            picSHIP.Left = picSHIP.Left + picSHIP.Width / 2    '右移動
            If picSHIP.Left + picSHIP.Width / 2 > Me.ClientSize.Width - picSHIP.Width Then    '右枠到達
                picSHIP.Left = Me.ClientSize.Width - picSHIP.Width    '戻す
            Else
                picSHIP.Left = picSHIP.Left + picSHIP.Width / 2    '右移動
            End If
        ElseIf e.KeyCode = Keys.Left Then    '[←]キー
            picSHIP.Left = picSHIP.Left - picSHIP.Width / 2    '左移動
            If picSHIP.Left - picSHIP.Width / 2 < 0 Then    '左枠到達
                picSHIP.Left = 0    '戻す
            Else
                picSHIP.Left = picSHIP.Left - picSHIP.Width / 2    '左移動
            End If
        End If
    End Sub

 最初に、移動先の座標(下線部)が枠を超えるか判定する。超える(真)ときは戻す。超えない(偽)ときは移動する。
結果 SHIPが左右の枠に到達した後のSHIPの表示のちらつきが解消された。
【ボタンコントロールがあると・・・】
 フォームにボタンがあると、カーソルキーがフォームのKeyDownイベントで取得できなくなる。カーソルキーとTabキーは、ボタンがイベントを取ってしまうためである(正確な表現ではないが)。対処方法として、フォームクラスのProcessDialogKeyメソッドをオーバーライドする。具体的には、フォームのKeyDownイベントに対応するメソッドの代わりに、次のプログラムを記述する。
    Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean
        If keyData = Keys.Right Then
            If picSHIP.Left + picSHIP.Width / 2 > Me.ClientSize.Width - picSHIP.Width Then    '右枠到達
                picSHIP.Left = Me.ClientSize.Width - picSHIP.Width    '戻す
            Else
                picSHIP.Left = picSHIP.Left + picSHIP.Width / 2    '右移動
            End If
            Return True
        ElseIf keyData = Keys.Left Then
            If picSHIP.Left - picSHIP.Width / 2 < 0 Then    '左枠到達
                picSHIP.Left = 0    '戻す
            Else
                picSHIP.Left = picSHIP.Left - picSHIP.Width / 2    '左移動
            End If
            Return True
        End If
        Return MyBase.ProcessDialogKey(keyData)
    End Function


 back next 
 §8 シューティング・ゲーム(1)2 Copyright©2008 Hiroshi Masuda 

 

 

inserted by FC2 system