我正在使用图形模块在 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反而。 Sdlkey和 Sdlevent模块为键盘提供了更细粒度的接口(interface)(除其他外)。特别是,您可以检测 KEYDOWN
和 KEYUP
事件。
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/