Reputation: 33
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
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