【问题标题】:Ruby Win32Api get single character non-blockingRuby Win32Api 获得单字符非阻塞
【发布时间】:2011-02-10 20:45:34
【问题描述】:

我正在尝试编写一个使用两个线程的简单游戏,一个线程用于获取用户的输入,另一个线程用于为某些场景设置动画。我可以在不按 ENTER 的情况下获得字符,但它会在动画线程中阻塞,直到用户按下一个键。有谁知道从键盘非阻塞获取字符的方法?

【问题讨论】:

  • 所以你说的是ruby 1.8,在windows中,如果一个线程执行“getc”,那么另一个线程也会被阻塞,你想要修复它吗?还是我误会了?

标签: ruby winapi input nonblocking


【解决方案1】:

如果您要检查几个特定键,GetAsyncKeyState() 可用于轮询状态。否则,您应该实现一个消息循环并在您的应用程序中处理WM_CHAR 消息。

如果您的环境尚不支持您需要的 win32 函数,您可以使用类似于以下内容的库访问原始 win32 函数。

RAA - win32-api @ raa.ruby-lang.org

这里是GetAsyncKeyState()的相关链接。

GetAsyncKeyState() @ MSDN
Virtual-Key Codes @ MSDN (used as values for GetAsyncKeyState and other functions)

如果您决定使用消息循环,则需要在托管应用程序窗口的同一线程上实现它。这里有一个简短的解释:

Message Loop in Microsoft Windows @ Wikipedia

如该链接所示,消息循环并不多。您的框架可能已经在后台运行了一个来托管包含您的图形的窗口。如果是这种情况,您不需要第二个线程进行输入;但您需要拦截和处理该主机窗口的 Windows 消息。

如果您必须自己实现消息循环,您可以使用维基百科链接中的骨架。 DispatchMessage 调用会将窗口消息定向到适当的窗口处理程序。您需要在 ruby​​ 框架中为 Windows 消息寻找匹配的存根或处理程序,并从那里处理 WM_CHAR

DispatchMessage @ MSDN
WM_CHAR @ MSDN

如果您想知道按键何时被按下/按下,那么您将需要处理 WM_KEYUP 和 WM_KEYDOWN 消息。

WM_KEYUP @ MSDN
WM_KEYDOWN @ MSDN

另外注意,GetAsyncKeyState() 可以被调用并返回关键状态,即使另一个应用程序在前台。处理 WM_ACTIVATEWM_SETFOCUS/WM_KILLFOCUS 消息,以便您的应用程序在其他窗口处于活动状态时忽略或推迟检查,如果您只关心键状态而您的窗口是主要前景窗口。

WM_ACTIVATE @ MSDN
WM_SETFOCUS @ MSDN
WM_KILLFOCUS @ MSDN

【讨论】:

    【解决方案2】:

    我为此使用了rubygame。它使您能够以最少的代码将函数附加到键盘事件。 RubySDLGoSu 将为您提供类似的功能。

    如果您不想使用与游戏相关的 gem 走这条路,请查看this,了解如何检查 IO 对象中是否有可用数据。这可以用来轮询键盘。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多