【问题标题】:Listening for key input in wxErlang在 wxErlang 中监听键输入
【发布时间】:2016-10-19 21:52:55
【问题描述】:

我正在尝试使用 wxErlang 在 Erlang 中制作一个小游戏。我的主要功能是一个循环,我需要检查在循环开始时是否按下了特定键(上、下、左、右......)。我在网上找到的大多数解决方案都使用全局处理函数来处理事件,这不是我在这种情况下要寻找的。有没有办法做到这一点?

【问题讨论】:

  • 如果您显示当前版本(使用全局处理程序)或描述预期结果或示例,因为它在 wxwidets 或其他库中实现,可能会更好。
  • 你的意思是检查一个键是否被按下现在或检查该键是否刚刚被按下?
  • 我认为这对我来说并不重要,但是检查自上次循环运行以来是否按下了某个键可能会更容易使用。现在检查它是否被按下会很好,它只是一个连续循环,它运行得足够快,我认为这无关紧要。

标签: erlang wxwidgets wxerlang


【解决方案1】:

我对@9​​87654321@ 了解不多,但是有办法收集在特定时间间隔内到达的消息。它使用receive 表达式的after 子句。

collect() ->
    collect([]).

collect(Acc) ->
    receive
        {my_msg, _} = Msg ->
            collect([Msg|Acc])
    after 0 ->
        lists:reverse(Acc)
    end.

main() ->
    ...,
    _ = collect(),    % clean message box or previous loop
    ...,
    Msgs = collect(), % messages arrived after last collect/0
    ...

【讨论】:

    【解决方案2】:

    事件以记录形式作为消息进入主接收循环:

    -record(wx, {    id   :: integer(),         %% Integer Identity of object.
                     obj  :: wx:wx_object(),    %% Object reference that was used in the connect call.
                 userData :: term(),            %% User data specified in the connect call.
                    event :: event()            %% The event record
            }).
    

    这是您应该放入代码的主接收循环中的事件:

    %%%
    %% Event for Keyboard button press
    %
    
         #wx{ id = _ , event = #wxKey{ type = key_down , 
                                    keyCode = integer()}
                                                                    }) ->
    
    % Your code where something happens
    
    loop(State);
    

    至于 integer() 应该是什么?

    %from wx.hrl
    -define(WXK_LEFT, 314).
    -define(WXK_UP, 315).
    -define(WXK_RIGHT, 316).
    -define(WXK_DOWN, 317).
    

    keyCode 整数将是这 4 个整数之一,或其宏等效项。

    一些背景

    您感兴趣的具体事件是 wxKey 事件:

    -record(wxKey,   {type :: wxKeyEventType(), %% Callback event: {@link wxKeyEvent}
                         x :: integer(),
                         y :: integer(),
                   keyCode :: integer(),
               controlDown :: boolean(),
                 shiftDown :: boolean(),
                   altDown :: boolean(),
                  metaDown :: boolean(),
                  scanCode :: boolean(),
                   uniChar :: integer(),
                   rawCode :: integer(),
                  rawFlags :: integer()}).
    

    当关键事件出现时,您还可以将这些值添加到该元组和模式匹配中。这使您能够真正专注于您感兴趣的确切事件。生成的记录将具有与其类型等效的值。也就是说,并非所有 Key 事件都具有上述所有值。您可以将初始的 'type=' 更改为以下 4 个之一。

    -type wxKeyEventType() :: char                 %% #wx{ event = #wxKey{ type = char } }
                            | char_hook            %% #wx{ event = #wxKey{ type = char_hook } }
                            | key_down             %% #wx{ event = #wxKey{ type = key_down } }
                            | key_up.              %% #wx{ event = #wxKey{ type = key_up } }
    

    意识到你对可能发生的事情有相当多的控制权。

    【讨论】:

      猜你喜欢
      • 2012-10-07
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      相关资源
      最近更新 更多