投稿者 あにす  (社会人) 投稿日時 2008/11/19 23:58:44
試しにキーの状態の取得部分をDirectInputを使用したコードに差し替えて見ても状況が改善されなかったので、
同じアルゴリズムでデータ構造を変えたコードを書きなおしました。なぜか上手く動くようになりました。
せっかくなのでコピペして使える様にモジュールをうp
Imports System.Windows.Forms

Module KeysState

    Dim keysState As New Dictionary(Of Keys, List(Of Boolean))

    ''' <summary> 
    ''' 毎フレーム呼び出す 
    ''' </summary> 
    Public Sub UpDate()
        For Each key As Keys In keysState.Keys
            keysState(key).RemoveAt(1)
            keysState(key).Add(keysState(key)(0))
        Next
    End Sub

    ''' <summary> 
    ''' キーが押し始められたかを取得 
    ''' </summary> 
    ''' <param name="key">押し始められたかどうかを取得するキー</param> 
    ''' <returns>押し始められていたらTrue、押し始められていなければFalse</returns> 
    Public Function IsPush(ByVal key As Keys) As Boolean
        Return keysState.ContainsKey(key) AndAlso Not keysState(key)(1) AndAlso keysState(key)(2)
    End Function

    ''' <summary> 
    ''' キーが押されているか取得 
    ''' </summary> 
    ''' <param name="key">押されているかどうかを取得するキー</param> 
    ''' <returns>押されていたらTrue、押されていなければFalse</returns> 
    Public Function IsPress(ByVal key As Keys) As Boolean
        Return keysState(key)(0)
    End Function

    ''' <summary> 
    ''' キーが離されたかを取得 
    ''' </summary> 
    ''' <param name="key">離されたかどうかを取得するキー</param> 
    ''' <returns>離されたらTrue、離されていなければFalse</returns> 
    Public Function IsUp(ByVal key As Keys) As Boolean
        Return keysState.ContainsKey(key) AndAlso keysState(key)(1) AndAlso Not keysState(key)(2)
    End Function

    ''' <summary> 
    ''' 対象のコントロールのKeyDownイベントハンドラに追加する 
    ''' </summary> 
    Public Sub KeyDown(ByVal sender As ObjectByVal e As KeyEventArgs)
        If keysState.ContainsKey(e.KeyCode) Then
            keysState(e.KeyCode)(0) = True
        Else
            keysState.Add(e.KeyCode, New List(Of Boolean)(New Boolean() {True, False, False}))
        End If
    End Sub

    ''' <summary> 
    ''' 対象のコントロールのKeyUpイベントハンドラに追加する 
    ''' </summary> 
    Public Sub KeyUp(ByVal sender As ObjectByVal e As KeyEventArgs)
        If keysState.ContainsKey(e.KeyCode) Then
            keysState(e.KeyCode)(0) = False
        Else
            keysState.Add(e.KeyCode, New List(Of Boolean)(New Boolean() {False, False, False}))
        End If
    End Sub
End Module


>うたひこさん
各オブジェクトの似ている要素を取り出してクラスにまとめるのは分かるのですが、
オブジェクトごとの固有の振る舞いはどこにコーディングしたのでしょうか?
違うコレクションに入れていても、同じクラスのインスタンスなら同じ動きしかしませんよね?
インスタンスのデータ部分で振る舞いを決定するにしても限界があるように思います。

>同じ動きをするオブジェクトがあったとします。
>
>例えば、敵弾、味方弾、敵キャラが別のキャラにホーミングするという動作。
>
>これをポリモーフで実現しようとすると、
>似たクラスを三つ作るというバカを丸出す羽目になります。
これを多態で表現するなら、『別のキャラにホーミングするクラス』を継承した
敵弾クラス、味方弾クラス、敵キャラクラスが出来ると思います。
そうすると、この3つのクラスは別のキャラにホーミングする以外の振る舞いのみが記述された全く違うクラスになりませんか?
あれ、VB6って継承出来ないんですね…。え、じゃぁどうやって多態を表現するんでしょう。わけが分からなくなって来ました…。