2

我正在创建一个游戏,其中有 2 名玩家,每个人控制他们上下移动的单独块,以及一个弹跳的球,目的是让球在玩家的单位后面并接触墙壁(这是一个游戏如果有帮助,请在 Wii Play 上使用 =D)

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

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

TL;DR:同时发生多个关键事件。我如何一次处理所有这些?

4

3 回答 3

2

假设您通过 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

有多种方法可以做到这一点。当同时按下多个键时,将多次触发事件,每个键一次,因此您可以在触发和事件时Form.KeyDown跟踪每个键的当前状态。或者,您可以通过使用该方法将 a 添加到应用程序的消息过滤器来执行类似的操作。如果您必须检查许多键并且经常这样做,那么像这样跟踪每个键的状态可能是有意义的,但是,更简单且可能同样有效的方法是简单地检查每个键的状态根据需要使用Joseph Lee 推荐的方法(.NET 框架 3.0 及更高版本),或使用user32.dll(3.0 之前的框架)中的 Win32 API 调用。KeyDownKeyUpKeyMessageFilterApplication.AddMessageFilterKeyboard.IsKeyDownGetKeyState

要在下面的评论中回答您的问题,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 或更高版本的框架开发应用程序,我建议您使用Keyboard该类,因为它是托管代码。除非其他选项不适合您,否则我只会使用 Win32 API。

于 2012-12-29T20:29:11.623 回答