add topbar with mana, fix bug where newly created state was not stored

in the hashtbl 😠, clean code
This commit is contained in:
zapashcanon 2023-01-08 04:10:15 +01:00
parent 51129ecb2e
commit 3a9d5daf02
No known key found for this signature in database
GPG key ID: 8981C3C62D1D28F1
11 changed files with 177 additions and 89 deletions

View file

@ -12,7 +12,7 @@ end
let get_el id =
match Document.find_el_by_id G.document (Jstr.of_string id) with
| None -> failwith (Format.sprintf {|Could not find element by id: "%s"|} id)
| None -> Log.err "could not find element with id `%s`" id
| Some el -> el
let tile_size = 40
@ -51,17 +51,16 @@ let papy_up = C2d.image_src_of_el (get_el "papy_up")
let water = C2d.image_src_of_el (get_el "water")
let draw =
let draw_canvas =
let papy_x = float_of_int (width - tile_size) /. 2. in
let papy_y = (float_of_int height /. 2.) -. (float_of_int tile_size *. 1.5) in
fun state ->
let open State in
let player_x, player_y, player_dir = state.player_pos in
for x = 0 to tiles_per_w - 1 do
let map_x = x + player_x - (tiles_per_w / 2) in
let map_x = x + state.player_pos.x - (tiles_per_w / 2) in
let tile_x = float_of_int ((x * tile_size) + orig_x) in
for y = 0 to tiles_per_h - 1 do
let map_y = y + player_y - (tiles_per_h / 2) in
let map_y = y + state.player_pos.y - (tiles_per_h / 2) in
let tile_y = float_of_int ((y * tile_size) + orig_y) in
let tile_img =
match Map.get_tile_kind ~x:map_x ~y:map_y state.map with
@ -73,7 +72,7 @@ let draw =
done
done;
let papy =
match player_dir with
match state.player_pos.dir with
| Left -> papy_left
| Right -> papy_right
| Down -> papy_down
@ -81,6 +80,11 @@ let draw =
in
C2d.draw_image context papy ~x:papy_x ~y:papy_y
let draw_topbar state =
let mana_lvl = Jv.get Jv.global "mana_lvl" in
Jv.set mana_lvl "innerHTML"
(Jv.of_string @@ string_of_int state.Shared.State.mana)
(* queue for action to be done *)
let input_queue = Queue.create ()
@ -89,8 +93,13 @@ let to_apply_queue : State.action' Queue.t = Queue.create ()
let send_action state action =
match State.check_action state action with
| Error e -> Format.printf "Invalid action: %s@\n" e
| Ok _ -> Ws_client.send (Network.Action_msg action)
| Error e ->
(* TODO: display this in the window *)
Log.debug "invalid action: %s@\n" e
| Ok Look_at_the_sky -> ()
| Ok _ ->
Log.debug "sending action %a to server@\n" State.pp_action action;
Ws_client.send (Network.Action_msg action)
let kb_handler ev =
let open State in
@ -105,31 +114,31 @@ let kb_handler ev =
in
Queue.add act input_queue
let last_auto_state_update = ref 0.
let render state =
draw_canvas state;
draw_topbar state
let rec game_loop state timestamp =
draw state;
let new_state =
(* TODO repesct order of action *)
(* apply to_apply_queue *)
let rec game_loop state last_auto_update timestamp =
render state;
let should_auto_update =
timestamp -. last_auto_update
>= Time.ms_to_float (Time.s_to_ms State.auto_update_rate)
in
let last_auto_update =
if should_auto_update then timestamp else last_auto_update
in
let state =
(* apply queue of actions *)
let state = Queue.fold State.perform_action state to_apply_queue in
(* TODO can this bug because of concurrency? *)
Queue.clear to_apply_queue;
(* send input action to server *)
Queue.iter (send_action state) input_queue;
Queue.clear input_queue;
(* auto_update *)
if
timestamp -. !last_auto_state_update
>= float_of_int @@ (State.auto_state_update_rate * 1000)
then (
Format.printf "MANA: %d@." state.mana;
last_auto_state_update := timestamp;
State.auto_update state )
else state
(* state auto update *)
if should_auto_update then State.auto_update state else state
in
G.request_animation_frame (game_loop new_state)
G.request_animation_frame (game_loop state last_auto_update)
let () =
(* init canvas *)
@ -147,10 +156,10 @@ let () =
match server_msg with
| Full_state _state ->
(* TODO reset state to received state *)
Format.printf "received Full_state message@\n"
Log.debug "received `Full_state` message@\n"
| Update_result res -> (
match res with
| Error e -> Format.printf "received update result error: %s" e
| Error e -> Log.debug "received update result error: %s@\n" e
| Ok action' -> Queue.add action' to_apply_queue ) );
(* bind keys *)
let _e : Ev.listener =
@ -160,9 +169,9 @@ let () =
Fut.await initial_state_fut (fun msg ->
match Ws_client.to_server_msg msg with
| Update_result _res_msg ->
failwith
Log.err
"invalid first server message received; received Update expected \
Full_state"
| Full_state state ->
(* start game *)
G.request_animation_frame (game_loop state) )
G.request_animation_frame (game_loop state 0.) )