From afa17f091db0999431496106ed09042e98235965 Mon Sep 17 00:00:00 2001 From: Nicolas Glondu Date: Sun, 6 Nov 2011 13:50:04 +0100 Subject: [PATCH] Some fixes for walls - prevent_default added (requires a fix in the stdlib) - high scores stored on server (insecurely) --- src/info.opa | 35 +++++++++++++++++++++++++++- src/opacman.opa | 54 ++++++++++++++++++++++++++++++++++-------- src/types.opa | 2 ++ src/wall.opa | 62 +++++++++++++++++++++++++------------------------ 4 files changed, 112 insertions(+), 41 deletions(-) diff --git a/src/info.opa b/src/info.opa index 7710d93..5aa6157 100644 --- a/src/info.opa +++ b/src/info.opa @@ -37,6 +37,15 @@ do Canvas.restore(ctx) + do Canvas.save(ctx) + do Canvas.set_font(ctx, "bold 20px Arial") + do Canvas.translate(ctx, 12+base_size*grid_width, 250) + do cft("HIGH SCORES:", 30) + do List.iter( + (score, name) -> cft(" - {name} {score}", 30), + g.scores) + do Canvas.restore(ctx) + do Canvas.save(ctx) do Canvas.set_font(ctx, "bold 20px Arial") do Canvas.translate(ctx, 2+base_size*grid_width, 0) @@ -58,7 +67,6 @@ w=2+base_size*grid_width h=2+base_size*grid_heigth do Canvas.save(ctx) - do Canvas.set_text_align(ctx, {align_center}) do Canvas.set_font(ctx, "bold {f}px Arial") do Canvas.fill_text(ctx, text, w/2, (h-f)/2) @@ -79,6 +87,31 @@ draw_game_over(ctx) = draw_in_center(ctx, "GAME OVER", some("'r' to restart")) + @private scorify(name) = + ll = String.length(name) + c1 = if ll < 1 then "_" else String.get(0, name) + c2 = if ll < 2 then "_" else String.get(1, name) + c3 = if ll < 3 then "_" else String.get(2, name) + "{c1} {c2} {c3}" + + draw_score_entry(ctx, name) = + f = 70 + w=2+base_size*grid_width + h=2+base_size*grid_heigth + do Canvas.save(ctx) + + do Canvas.set_text_align(ctx, {align_center}) + do Canvas.set_font(ctx, "bold {f}px Arial") + do Canvas.fill_text(ctx, "HIGH SCORE", w/2, (h-f)/2) + + do Canvas.set_font(ctx, "bold {f/2}px Arial") + do Canvas.fill_text(ctx, "Type your initials, submit with 'enter'", w/2, h/2) + + do Canvas.set_font(ctx, "bold 50px Arial") + do Canvas.fill_text(ctx, scorify(name), w/2, h/2+60) + do Canvas.restore(ctx) + void + draw_pause(ctx) = draw_in_center(ctx, "PAUSE", some("'space' or any direction to resume")) diff --git a/src/opacman.opa b/src/opacman.opa index 32c5542..8731755 100644 --- a/src/opacman.opa +++ b/src/opacman.opa @@ -28,6 +28,7 @@ default_game = { score = 0 lives = 3 on_steroids = none + scores = [] } : Game.status /* Game */ @@ -92,15 +93,22 @@ check_collision(g:Game.status):Game.status = lives = g.lives + (score/life_points - g.score/life_points) {g with ~ghosts ~score ~lives ~on_steroids} | {none} -> - if g.lives == 1 then - {g with - state = {game_over} + if g.lives < 2 then + scores = Scores.get() + cur_min = + if scores == [] then 0 + else List.rev(scores) |> List.head |> _.f1 + state = + if g.score > cur_min then {score=""} + else {game_over} + {g with ~scores ~state lives = 0} else {default_game with food = g.food score = g.score - lives = g.lives-1} + lives = g.lives-1 + scores = Scores.get()} @client clean_frame(ctx:Canvas.context) = Canvas.clear_rect( @@ -112,7 +120,7 @@ check_collision(g:Game.status):Game.status = t = Date.now() |> Date.in_milliseconds t = t / 100 t = t - (t/10)*10 - if t > 5 then f() + if t > 3 then f() @client next_frame(ctx:Canvas.context)() = draw_board(g) = @@ -128,6 +136,9 @@ check_collision(g:Game.status):Game.status = | {game_over} -> do blink(->Info.draw_game_over(ctx)) g + | {score=name} -> + do blink(->Info.draw_score_entry(ctx, name)) + g | {pause} -> do blink(->Info.draw_pause(ctx)) g @@ -151,7 +162,7 @@ check_collision(g:Game.status):Game.status = @client keyfun(e) = g = game.get() p = g.pacman - do Dom.transform([#debug <- "{e.key_code}"]) + // do Dom.transform([#debug <- "{e.key_code}"]) dir_key = key_to_dir(e.key_code ? -1) p = match (p.base.dir, dir_key) with | ({down}, {some={dir_up}}) -> @@ -181,7 +192,28 @@ check_collision(g:Game.status):Game.status = | _ -> p g = match (g.state, e.key_code) with // r (reset if game over) - | ({game_over}, {some=114}) -> default_game + | ({game_over}, {some=82}) -> + { default_game with scores=Scores.get() } + + // any letter for high score + | ({score=name}, {some=key}) -> + if key == 13 then + scores = Scores.add(name, g.score) + {g with ~scores state={game_over}} + else + char_idx = key - 65 + new_char = + if char_idx >= 0 && char_idx < 26 then + String.get(char_idx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") + else "" + ll = String.length(name) + score = + if key == 8 && ll != 0 then + String.substring_unsafe(0, ll-1, name) + else if new_char == "" then name + else if ll < 3 then "{name}{new_char}" + else name + {g with state={~score}} // space (pause start) | ({running}, {some=32}) -> {g with state={pause}} @@ -201,7 +233,8 @@ check_collision(g:Game.status):Game.status = | _ -> {g with pacman=p} game.set(g) -@client init() = +@client init(scores) = + do game.set({game.get() with ~scores}) do match Canvas.get(#bg_holder) with | {none} -> void | {some=canvas} -> @@ -212,12 +245,13 @@ check_collision(g:Game.status):Game.status = | {some=canvas} -> ctx = Canvas.get_context_2d(canvas) |> Option.get t = Scheduler.make_timer(1000/fps, next_frame(ctx)) - _ = Dom.bind(Dom.select_document(), {keydown}, keyfun) + _ = Dom.bind_with_options(Dom.select_document(), {keydown}, keyfun, [{prevent_default}]) t.start() body() = width = 2+base_size*grid_width+info_width height = 2+base_size*grid_heigth + scores = Scores.get() <> You can't see canvas, upgrade your browser ! @@ -226,7 +260,7 @@ body() = You can't see canvas, upgrade your browser !
- init()}> + init(scores)}>
diff --git a/src/types.opa b/src/types.opa index 310e68e..d58a758 100644 --- a/src/types.opa +++ b/src/types.opa @@ -51,6 +51,7 @@ type Game.state = {game_start} / {running} / {pause} + / {score:string} / {game_over} type Game.status = { @@ -62,4 +63,5 @@ type Game.status = { lives : int on_steroids : option({cycles:int combo:int}) /* Number of cycles on steroids and ghost combo */ + scores : list((int, string)) } diff --git a/src/wall.opa b/src/wall.opa index 0bc6e9e..75817c6 100644 --- a/src/wall.opa +++ b/src/wall.opa @@ -12,11 +12,17 @@ x >= grid_width || y >= grid_heigth || x < 0 || y < 0 border || Set.mem(~{x y}, Default.walls) - @private draw_angle(ctx, x, y, angle) = + @private common_env(ctx, x, y, f:->void) = w = base_size do Canvas.save(ctx) - do Canvas.set_fill_style(ctx, {color=Color.darkblue}) + do Canvas.set_fill_style(ctx, {color=Color.lightslategray}) do Canvas.translate(ctx, 1+x*w+w/2, 1+y*w+w/2) + do f() + Canvas.restore(ctx) + + @private draw_angle(ctx, x, y, angle) = + w = base_size + common_env(ctx, x, y, (-> do Canvas.rotate(ctx, angle) do Canvas.begin_path(ctx) do Canvas.move_to(ctx, w/4, w/2) @@ -26,23 +32,19 @@ do Canvas.line_to(ctx, w/2, -w/4) do Canvas.line_to(ctx, w/2, w/4) do Canvas.arc(ctx, w/2, w/2, w/4, 3.*Math.PI/2., Math.PI, true) - do Canvas.fill(ctx) - Canvas.restore(ctx) + Canvas.fill(ctx) + )) @private draw_line(ctx, x, y, angle) = w = base_size - do Canvas.save(ctx) - do Canvas.set_fill_style(ctx, {color=Color.darkblue}) - do Canvas.translate(ctx, 1+x*w+w/2, 1+y*w+w/2) + common_env(ctx, x, y, (-> do Canvas.rotate(ctx, angle) - do Canvas.fill_rect(ctx, w/2, w/4, -w, -w/2) - Canvas.restore(ctx) + Canvas.fill_rect(ctx, w/2, w/4, -w, -w/2) + )) @private draw_corner(ctx, x, y, angle) = w = base_size - do Canvas.save(ctx) - do Canvas.set_fill_style(ctx, {color=Color.darkblue}) - do Canvas.translate(ctx, 1+x*w+w/2, 1+y*w+w/2) + common_env(ctx, x, y, (-> do Canvas.rotate(ctx, angle) do Canvas.begin_path(ctx) do Canvas.move_to(ctx, w/4, 0) @@ -50,14 +52,12 @@ do Canvas.line_to(ctx, -w/4, w/2) do Canvas.line_to(ctx, w/4, w/2) do Canvas.line_to(ctx, w/4, 0) - do Canvas.fill(ctx) - Canvas.restore(ctx) + Canvas.fill(ctx) + )) @private draw_t(ctx, x, y, angle) = w = base_size - do Canvas.save(ctx) - do Canvas.set_fill_style(ctx, {color=Color.darkblue}) - do Canvas.translate(ctx, 1+x*w+w/2, 1+y*w+w/2) + common_env(ctx, x, y, (-> do Canvas.rotate(ctx, angle) do Canvas.begin_path(ctx) do Canvas.move_to(ctx, w/4, w/2) @@ -67,14 +67,12 @@ do Canvas.line_to(ctx, w/2, -w/4) do Canvas.line_to(ctx, w/2, w/4) do Canvas.arc(ctx, w/2, w/2, w/4, 3.*Math.PI/2., Math.PI, true) - do Canvas.fill(ctx) - Canvas.restore(ctx) + Canvas.fill(ctx) + )) @private draw_cross(ctx, x, y) = w = base_size - do Canvas.save(ctx) - do Canvas.set_fill_style(ctx, {color=Color.darkblue}) - do Canvas.translate(ctx, 1+x*w+w/2, 1+y*w+w/2) + common_env(ctx, x, y, (-> do Canvas.begin_path(ctx) do Canvas.move_to(ctx, w/4, w/2) do Canvas.line_to(ctx, -w/4, w/2) @@ -85,8 +83,16 @@ do Canvas.arc(ctx, w/2, -w/2, w/4, Math.PI, Math.PI/2., true) do Canvas.line_to(ctx, w/2, w/4) do Canvas.arc(ctx, w/2, w/2, w/4, 3.*Math.PI/2., Math.PI, true) - do Canvas.fill(ctx) - Canvas.restore(ctx) + Canvas.fill(ctx) + )) + + @private draw_circle(ctx, x, y) = + w = base_size + common_env(ctx, x, y, (-> + do Canvas.begin_path(ctx) + do Canvas.arc(ctx, 0, 0, w/4, 0., 2.*Math.PI, true) + Canvas.fill(ctx) + )) @private neighbors(x, y) = right = at(x+1, y, true) @@ -96,7 +102,6 @@ (top, left, bottom, right) draw(ctx:Canvas.context) = - w = base_size do Set.iter( ~{x y} -> match neighbors(x, y) with @@ -135,11 +140,8 @@ | ({true}, {true}, {true}, {true}) -> draw_cross(ctx, x, y) - | _ -> - do Canvas.save(ctx) - do Canvas.set_fill_style(ctx, {color=Color.darkblue}) - do Canvas.fill_rect(ctx, 1+x*w, 1+y*w, w, w) - Canvas.restore(ctx), + | ({false}, {false}, {false}, {false}) -> + draw_circle(ctx, x, y), Default.walls) void