Ruby Win32Api获得单字符无阻塞

时间:2010-04-22 00:42:38

标签: ruby winapi input nonblocking

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

2 个答案:

答案 0 :(得分: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调用将Windows消息定向到相应的窗口处理程序。您将需要在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消息,以便当您的窗口是主要前景窗口时,如果您只关心键状态,则应用程序会在其他窗口处于活动状态时忽略或推迟检查。 / p>

WM_ACTIVATE @ MSDN
WM_SETFOCUS @ MSDN
WM_KILLFOCUS @ MSDN

答案 1 :(得分:0)

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

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