这是 OCaml 中的一个简单的游戏循环。状态被显示,输入被接收,状态被推进。通过在每个循环中将线程延迟 0.025 秒,将每秒帧数限制为 40。
主要.ml:
let rec main (* state *) frame_time =
(* Display state here. *)
Input.get_input ();
(* Advance state by one frame here. *)
(* If less than 25ms have passed, delay until they have. *)
if((Sys.time ()) < (frame_time +. 0.025)) then
Thread.delay ((frame_time +. 0.025) -. (Sys.time ()));
main (* next_state *) (Sys.time ())
;;
let init =
Graphics.open_graph " 800x500";
let start_time = (Sys.time ()) in
main (* start_state *) start_time
;;
对于此示例,该get_input
函数只是将击键打印到窗口。
输入.ml:
let get_input () =
let s = Graphics.wait_next_event
[Graphics.Key_pressed] in
if s.Graphics.keypressed then
Graphics.draw_char s.Graphics.key
;;
Makefile 便于测试:
main: input.cmo main.cmo
ocamlfind ocamlc -o $@ unix.cma -thread threads.cma graphics.cma $^
main.cmo: main.ml
ocamlfind ocamlc -c $< -thread
input.cmo: input.ml
ocamlfind ocamlc -c $<
这在大多数情况下都有效,但是当快速按下键时,程序会因以下错误而崩溃:
Fatal error: exception Unix.Unix_error(2, "select", "")
我相信这与Thread.delay
. 是什么导致了这个问题,实现恒定 FPS 的最佳方法是什么?