2012年12月5日水曜日

ClojureScriptでgoog.graphics

altjs Advent Calendar 2012
5日目の記事です。

三目並べ

Cojureで三目並べの続き。

ここでは三目並べのClojureScriptによる実装について書きます。

ゲームのロジックは作ってあるのであとは描画のところを実装するだけ。

goog.graphics


描画にはgoog.graphicsを使うことにします。

ClojureScriptはGoogle Closure Libraryで実装されており、nsでJavaScriptのライブラリをrequireすることが出来ます。

(ns tic-tac-toe.main
(:require [cljs.core.logic :as logic]
[tic-tac-toe.game :as game]
[goog.dom :as dom]
[goog.graphics :as graphics]
[goog.events.EventType :as event-type]))
view raw ns.clj hosted with ❤ by GitHub
各種定数。

(def white-fill (graphics/SolidFill. "white"))
(def gray-fill (graphics/SolidFill. "gray"))
(def black-fill (graphics/SolidFill. "black"))
(def black-stroke (graphics/Stroke. 1 "black"))
(def font (graphics/Font. game/font-size "monospace"))
view raw const.clj hosted with ❤ by GitHub
tic-tac-toe.game.Canvasを実装します。

(def g (graphics/createGraphics 300 300))
(def canvas
(reify game/Canvas
(draw-circle [this panel]
(.drawCircle g
(+ (:x panel) game/radius)
(+ (:y panel) game/radius)
game/radius
nil
black-fill))
(draw-cross [this panel]
(let [{:keys [x y]} panel
x' (+ x game/panel-size)
y' (+ y game/panel-size)]
(doto g
(.drawPath (doto (graphics/Path.)
(.moveTo x y)
(.lineTo x' y'))
black-stroke
nil)
(.drawPath (doto (graphics/Path.)
(.moveTo x' y)
(.lineTo x y'))
black-stroke
nil))))
(draw-text [this s]
(.drawText g s 0 0 game/panel-size game/font-size "left" "top" font nil gray-fill))))
view raw canvas.clj hosted with ❤ by GitHub
main関数を定義します。

(defn main []
(doseq [panel game/panels]
(doto (.drawRect g (:x panel) (:y panel) game/panel-size game/panel-size black-stroke white-fill)
(.addEventListener event-type/CLICK
(fn [event]
(game/play canvas panel)))))
(.render g (dom/getElement "canvas")))
view raw main.clj hosted with ❤ by GitHub
HTMLはコンパイルされたJavaScriptを読み込み、main関数を呼び出します。

<!DOCTYPE html>
<html>
<head>
<title>tic tac toe</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="application/javascript" src="main.js"></script>
</head>
<body>
<div id="canvas"></div>
<script type="application/javascript">
tic_tac_toe.main.main();
</script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub
これで動いてほしいところですが、cljs.core.logicがバグってるので、コンパイルされた.jsの修正が必要です。
cljs.core.logic.macros._take_STAR_のところをcljs.core.logic._take_STAR_に変更します。

masterでは直ってますが、修正版がpublishされていないのが悲しいですね。

雑感


いままでもClojureScriptについていろいろ書いてますが、やはりClojureは書いてて楽しいです。                                                            
最近はprotocolとrecordとmacroが好みです。                                                                                                           

論理プログラミングで書いたコードがWeb上で動いているのはなかなかおもしろいと思うのですが、コンパイルされたJavaScriptのコードをみるとものすごくカオスです。

Google Closure Compilerによるアシストがあるとはいえ、ファイルサイズは比較的大きくなるので、注意です。

cljsbuildのおかげで、今回のようなJVMとWebの両方で動くようなコードが書けるので、これからClojureScriptを使う人には是非知ってもらいたいものです。

0 件のコメント:

コメントを投稿