Felipe Flores
Felipe Flores

Reputation: 33

How can i read two buttons being pressed at the same time in Ocaml Graphics?

I'm making a simple space invaders in Ocaml using the graphics module. You can move the ship with 'a' and 'd', and shoot with space. My problem is that i cant make that you move and shoot at the same time. When I'm pressing 'd' to move and then i press space to shoot, the ship shoots but stop moving even if i never stop pressing '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
;;

I know about read_key reading from a queue and all that, but the problem is that he stops seeing that i'm holding down a key when i press another key.

Does anyone know how to solve this?
thanks.

Upvotes: 2

Views: 244

Answers (1)

tbrk
tbrk

Reputation: 1298

The keyboard interface exposed by the graphics module is a bit limited.

You might consider using OCamlSDL instead. The Sdlkey and Sdlevent modules provide a more fine grained interface to the keyboard (amongst other things). In particular, you can detect KEYDOWN and KEYUP events.

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 ()

Upvotes: 2

Related Questions