2

私は、2 人のプレイヤーがいて、それぞれが上下に動く別々のブロックを制御し、ボールが跳ね返るゲームの 1 つを作成しています。目的は、ボールをプレイヤーのユニットの後ろに置き、壁に触れることです (そのゲームです)。それが役立つ場合はWii Playで= D)

私が直面している問題は、 などのイベントを使用することPrivate Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDownです。シンプルなもの。

以前は、シングル プレイヤー ゲームしか作成していなかったので、これはあまり問題ではありませんでした (ただし、2 つの別々のイベントが一緒に処理されず、別々に処理されたため、斜めに移動することが妨げられました)。それで、質問は何ですか?では、2 人のプレイヤーが同時に複数のキーを押した場合、これはどのように処理されるのでしょうか?

TL;DR: 複数の重要なイベントが同時に発生しています。それらを一度に処理するにはどうすればよいですか?

4

3 に答える 3

2

(Web サイトではなく) Windows アプリケーションを介してこれを行っていると仮定します。

複数のキー押下を同時に処理するには、Key イベントを介してこれを行うことはできません。代わりに、関数を (非常に迅速に) 起動/実行する Timer オブジェクトを作成します。その関数では、System.Windows.Input 名前空間の Keyboard クラス、具体的には isKeyDown() メソッドを使用します。

If Keyboard.IsKeyDown(Key.Up) And Keyboard.IsKeyDown(Key.Right) Then
    'Do something to move Up-right
End If

乾杯。

于 2012-12-29T20:21:20.340 に答える
1

ゲームでキーを処理するために GetAsyncKeyState を使用している人がいると聞きました。これが私の小さな例です:

Imports System.Runtime.InteropServices

Public Class Form1
    <DllImport("user32.dll")> _
    Public Shared Function GetAsyncKeyState(ByVal vKey As System.Windows.Forms.Keys) As Short
    End Function
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim keyhandler As New Threading.Thread(AddressOf handlekeys)
        keyhandler.Start()
    End Sub

    Sub handlekeys()
        While True
            If GetAsyncKeyState(Keys.Up) Then
                'do something if up arrow key is being pressed
            ElseIf GetAsyncKeyState(Keys.Down) Then
                'do something if down arrow key is being pressed
            End If
            Threading.Thread.Sleep(1)
        End While

    End Sub
End Class

これにより、一度に複数のキーを処理できます。また、スリープ状態のスレッドの代わりにタイマーを使用することもできます。

于 2012-12-29T20:21:47.583 に答える
1

これを行うには複数の方法があります。複数のキーが同時に押されると、キーごとに 1 回、イベントが複数回発生するため、およびイベントが発生Form.KeyDownしたときに各キーの現在の状態を追跡できます。または、メソッドを使用してアプリケーションのメッセージ フィルターに を追加することで、同様のことを行うことができます。このように各キーの状態を自分で追跡することは、多くのキーを頻繁に検査する必要がある場合に意味があるかもしれませんが、はるかに単純なアプローチで、おそらく同じくらい効率的な方法は、各キーの状態を単純にチェックすることです。必要に応じて、Joseph Lee が推奨する方法 (.NET Framework 3.0 以降) を使用するか、user32.dll (3.0 以前のフレームワーク) で Win32 API 呼び出しを使用します。KeyDownKeyUpKeyMessageFilterApplication.AddMessageFilterKeyboard.IsKeyDownGetKeyState

以下のコメントであなたの質問に答えるために、user32.dll は標準の Windows ライブラリです。これは、まとめて Win32 API と呼ばれる標準ライブラリのリストの 1 つです。Windows と同じくらい長い間、95 より前から存在しています。これはアンマネージ ライブラリです。つまり、簡単に言えば、.NET で記述されておらず、.NET フレームワークを使用していません。これらは基本的に、Windows OS と直接通信するための手段です。

.NET フレームワークで提供されるメソッドの多くは、古い Win32 API 呼び出しの単なるラッパーです。.NET フレームワークのマネージ クラスが同じ機能を提供する場合、ほとんどの場合、Win32 API 呼び出しの代わりにそれを使用する必要があります。管理ライブラリが Win32 API よりも好まれる理由は複数あります。

  • 理想的には、.NET アプリは OS に依存しないはずです。Win32 API 呼び出しを呼び出すと、アプリケーションは Windows でのみ実行され、より具体的には、その API 呼び出しを明確にサポートする Windows のバージョンでのみ実行されます。
  • アンマネージ コードの呼び出しには、バックグラウンドでのデータ マーシャリングが必要なため、マネージ コードの呼び出しほど高速ではありません。.NET フレームワークのメソッドの多くは完全にマネージ コードで実装されているため、アンマネージ コードの舞台裏での呼び出しは実際には必要ありません。
  • 管理されたライブラリは、単純に使いやすいです。それらはオブジェクト指向であり、標準のデータ型を使用します。Win32 API 呼び出しの多くは、ポインターとカスタム構造体を使用しているため、呼び出しが困難ではありますが、不可能ではありません。

したがって、フレームワークのバージョン 3.0 以降でアプリを開発している場合は、Keyboardマネージ コードであるため、このクラスを使用することをお勧めします。他のオプションが機能しない場合を除き、Win32 API のみを使用します。

于 2012-12-29T20:29:11.623 に答える