我正在创造其中一个游戏,其中有2个玩家,每个玩家控制他们上下移动的单独区块,以及一个球弹跳,目标是让球落在玩家的单位后面并触摸墙壁(如果这有助于= D),那就是Wii Play游戏。
我面临的问题是我使用的事件,例如Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
。简单的东西。
之前,我只制作了单人游戏,所以这不是一个问题(但是它禁止我对角移动等等,因为两个单独的事件没有一起处理,它们是分开处理的)。那么问题是什么?好吧,有两个玩家,同时按下多个键,这将如何处理?
TL; DR:同时发生多个关键事件。我如何一次处理它们?
答案 0 :(得分:2)
假设您是通过Windows应用程序(而非网站)执行此操作。
要同时处理多个按键,您无法通过按键事件执行此操作。 相反,创建一个触发/执行函数的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
欢呼声。
答案 1 :(得分: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
这允许您一次处理多个键。此外,您可以使用计时器而不是休眠线程。
答案 2 :(得分:1)
有多种方法可以做到这一点。当同时按下多个键时,Form.KeyDown
事件将被多次提升,每个键一次,因此您可以跟踪每个键的当前状态KeyDown
和{{1引发事件。或者,您可以通过使用KeyUp
方法向应用程序的邮件过滤器添加KeyMessageFilter
来执行类似操作。如果您必须经常检查许多密钥并且经常这样做,那么保持跟踪自己每个密钥的状态可能是有意义的,但是,更简单的方法,可能同样有效,只需检查每个密钥的状态必要时使用Joseph Lee推荐的Application.AddMessageFilter
方法(.NET framework 3.0及更高版本),或者使用user32.dll(3.0版之前的框架)中的Win32 API调用Keyboard.IsKeyDown
。
要在下面的评论中回答您的问题,user32.dll是一个标准的Windows库。它是标准库列表中的一个,统称为Win32 API。它就像Windows一样长,甚至在95之前。它是一个非托管库,简单来说,它不是用.NET编写的,也不是使用.NET框架。它们本质上是您与Windows操作系统直接通信的手段。
.NET框架中提供的许多方法都只是旧Win32 API调用的包装器。如果.NET框架中的托管类提供相同的功能,您几乎总是希望使用它而不是Win32 API调用。托管库优先于Win32 API的原因有多种:
因此,如果您针对3.0版本的框架或更高版本开发应用程序,我建议使用GetKeyState
类,因为它是托管代码。我只会使用Win32 API,除非其他选项不适合你。