ocaml - 如何在 Ocaml Graphics 中读取同时按下的两个按钮?

标签 ocaml

我正在使用图形模块在 Ocaml 中制作一个简单的太空入侵者。你可以用“a”和“d”移动飞船,并用空间射击。我的问题是我无法让你同时移动和射击。当我按“d”键移动,然后按空格键射击时,船会射击,但停止移动,即使我从未停止按“d”键。

let rec handler state old_time =  
   ...
   ...
    let event = Graphics.wait_next_event [ Graphics.Poll ] in
      if event.Graphics.keypressed then
          match (read_key ()) with
          |'a' -> handler { new_state with player = ((fst new_state.player) - 20, snd new_state.player) } new_time
          |'d' -> handler { new_state with player = ((fst new_state.player) + 20, snd new_state.player) } new_time
          |' ' -> handler (fire_bullet new_state) new_time
          | _ -> handler new_state new_time
  else
          handler new_state new_time
;;

我知道 read_key 从队列中读取以及所有这些,但问题是当我按下另一个键时,他不再看到我按住了一个键。

有谁知道如何解决这个问题吗?
谢谢。

最佳答案

图形模块暴露的键盘接口(interface)有点有限。

您可以考虑使用OCamlSDL反而。 SdlkeySdlevent模块为键盘提供了更细粒度的接口(interface)(除其他外)。特别是,您可以检测 KEYDOWNKEYUP 事件。

let printf = Format.printf

let rec poll_keys () =
  let open Sdlevent in
  if has_event () then begin
    match wait_event () with
    | KEYDOWN {keysym=key} -> printf "keydown '%c'@." (Sdlkey.char_of_key key)
    | KEYUP {keysym=key} -> printf "keyup '%c'@." (Sdlkey.char_of_key key)
    | _ -> Sdltimer.delay 5
  end;
  poll_keys ()

let () =
  Sdl.init [`VIDEO];
  (* Sdlkey.enable_key_repeat (); *)
  poll_keys ()

关于ocaml - 如何在 Ocaml Graphics 中读取同时按下的两个按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52845741/

相关文章:

OCaml 自定义编译器警告

functional-programming - 具有多个文件的记录的可变字段

html - 在 OCaml 中读取 URL 的 HTML 内容

ocaml - 如何通过类型构造函数比较相等值?

javascript - 如何将简单的命令行 OCaml 脚本编译成 Javascript

types - 约束多态类型

ocaml - 如何在 OCaml 中实现 lambda 演算?

list - 将哈希表转换为 OCaml 中的对(键,值)列表

haskell - 运行时是否通常使用类似命令式的函数式语言代码解释