投稿者 あにす  (社会人) 投稿日時 2008/11/19 00:01:53
挑戦しました。
シューティングゲームを作ろうと思い、カーソルキーでゲームのスタートや終了を選択できるタイトル画面から作り始めました。
カーソルキーの状態を取得しないといけませんが、VBにはキーボードの状態を取得する機能はないようです。
そこで、KeyUpイベントとKeyDownイベントでフラグを操作して、それを毎フレームごとに監視するようにしました。
常に一つ前のフレームの状態まで保持していれば、今押されているかどうかだけではなく、押し始めた瞬間も取得出来ると考えました。
しかし、↑、→、←、キーは取得できるのに↓キーだけ取りこぼしてしまいます。何故でしょう。
ミニマムコードを書いて実行してみると成功してしまいます。
もう少し悩んでみようと思います。
Imports System.Windows.Forms
Imports System.Drawing

Module Module1
    Sub Main()
        Dim frm As New Form()
        AddHandler frm.KeyDown, New KeyEventHandler(AddressOf frm_KeyDown)
        AddHandler frm.KeyUp, New KeyEventHandler(AddressOf frm_KeyUp)
        frm.Show()

        Dim g As Graphics = frm.CreateGraphics()

        Dim AKeyPushCount As Integer = 0
        Dim AKeyPressCount As Integer = 0

        Dim nextFlame As Double = Environment.TickCount
        Dim wait As Single = 1000 / 60

        While frm.Created
            If Environment.TickCount >= nextFlame Then
                upDate()
                If Push Then
                    AKeyPushCount += 1
                End If
                If Press Then
                    AKeyPressCount += 1
                End If
                If Environment.TickCount < nextFlame + wait Then
                    g.FillRectangle(Brushes.White, 0, 0, frm.ClientSize.Width, frm.ClientSize.Height)
                    g.DrawString("Push:" + AKeyPushCount.ToString() + " Press:" + AKeyPressCount.ToString(), frm.Font, Drawing.Brushes.Black, 0, 0)
                End If
                nextFlame += wait
            End If
            Application.DoEvents()
        End While
    End Sub

    Dim AKeyState() As Boolean = {False, False}
    Dim tmpAKeyState As Boolean = False

    ReadOnly Property Press() As Boolean
        Get
            Return AKeyState(1)
        End Get
    End Property

    ReadOnly Property Push() As Boolean
        Get
            Return AKeyState(1) AndAlso Not AKeyState(0)
        End Get
    End Property

    Sub frm_KeyDown(ByVal sender As ObjectByVal e As KeyEventArgs)
        If e.KeyData = Keys.Down Then
            tmpAKeyState = True
        End If
    End Sub

    Sub frm_KeyUp(ByVal sender As ObjectByVal e As KeyEventArgs)
        If e.KeyData = Keys.Down Then
            tmpAKeyState = False
        End If
    End Sub

    Sub upDate()
        AKeyState(0) = AKeyState(1)
        AKeyState(1) = tmpAKeyState
    End Sub
End Module