Вот простой игровой цикл в OCaml. Отображается состояние, принимается ввод и состояние расширяется. Количество кадров в секунду ограничивается 40 за счет задержки потока на 0,025 секунды в каждом цикле.
main.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
просто выводит нажатия клавиш в окно.
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?