多人在VB.NET中使用事件玩游戏

时间:2012-12-29 20:08:14

标签: vb.net events event-handling

我正在创造其中一个游戏,其中有2个玩家,每个玩家控制他们上下移动的单独区块,以及一个球弹跳,目标是让球落在玩家的单位后面并触摸墙壁(如果这有助于= D),那就是Wii Play游戏。

我面临的问题是我使用的事件,例如Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown。简单的东西。

之前,我只制作了单人游戏,所以这不是一个问题(但是它禁止我对角移动等等,因为两个单独的事件没有一起处理,它们是分开处理的)。那么问题是什么?好吧,有两个玩家,同时按下多个键,这将如何处理?

TL; DR:同时发生多个关键事件。我如何一次处理它们?

3 个答案:

答案 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的原因有多种:

  • 理想情况下,.NET应用程序应该与操作系统无关。如果您调用Win32 API调用,则会使您的应用程序仅在Windows下运行,更具体地说,仅在专门支持该API调用的Windows版本下运行。
  • 调用非托管代码需要一些幕后数据封送,因此它不如调用托管代码快。 .NET框架中的许多方法都完全在托管代码中实现,因此实际上不需要对非托管代码进行幕后调用。
  • 托管库更容易使用。它们是面向对象的,并使用标准数据类型。许多Win32 API调用都使用指针和自定义结构,这使得调用它们变得困难,尽管并非不可能。

因此,如果您针对3.0版本的框架或更高版本开发应用程序,我建议使用GetKeyState类,因为它是托管代码。我只会使用Win32 API,除非其他选项不适合你。