Here is a simple game loop in OCaml. The state is displayed, input is received, and the state is advanced. The number of frames per second is contrained to 40 by delaying the thread for 0.025 seconds each loop.
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
;;
For this example, the get_input
function simply prints keystrokes to the window.
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 for easy testing:
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 $<
This works for the most part, but when keys are pressed very quickly, the program crashes with this error:
Fatal error: exception Unix.Unix_error(2, "select", "")
I believe it has something to do with Thread.delay
. What is causing this issue, and what is the best way to achieve a constant FPS?