Simple Scheme で電卓をつくってみる(2)

Simple Schemeで電卓を作っています。前回はキーボードの画像を表示するところまで作りました

続いて、ボタンをタップしたらとりあえずなにか反応を返すようにしてみましょう。

タップされたボタンの位置に黒い円盤を表示させます。

前回は画像の表示にshow-imageを使いましたが、show-imageでは画像を表示することしかできません。画面のタップに反応させるにはbig-bangを使います。

big-bangの詳しい使い方はリンク先に書いてあります*1

というわけでshow-imageによる描画の部分を以下のコードに置き替えます。

(big-bang keyboard
          (on-draw (lambda (b) b))
          (on-mouse
           (lambda (b x y what)
             (if (string=? what "button-down")
                 (place-image (circle 80 "solid" "black")
                              (conv-x (inv-x x)) (conv-y (inv-y y))
                              keyboard)
                 keyboard))))

画面に指を置くと、on-mouseに渡された関数の中でキーボードに円盤を重ねた画像が生成されます。

その画像がon-drawに渡された関数に渡され、画面に描画されるというのが基本的な流れです。

画面に指を置く以外の操作(画面から指を離す等)をするとon-mouseに渡された関数がキーボードだけの画像を生成し、この画像がon-drawに渡された関数によって描画され、円盤が消えます(消えたように見えます)。

*2

(ボタンのない場所をタップしても円盤が表示されますが、これへの対処は、具体的な機能を入れる際にどうせしないといけないので、後回しにします)

on-mouseに渡された関数内のinv-xinv-yは次のように定義されています。

(define (inv-x x) (round (- (/ (* 7.0 x) width) 1)))
(define (inv-y y) (round (- (/ (* 7.0 y) width) 2)))

conv-xconv-y逆関数ですね。

(define (conv-x x) (/ (* width (+ 1 x)) 7))
(define (conv-y y) (/ (* width (+ 2 y)) 7))

タップした場所を中心とする円ではなく、タップした場所にあるボタンの真ん中辺りを中心とする円を描画するために、これらの関数を使って、座標を離散化しているわけです。

続きます。

(ここまでのコード)

*1:ただし、リンク先で
mouse-func should be of type: World Number Number String -> Scene
となっている部分は恐らく
mouse-func should be of type: World Number Number String -> World
の誤記です。

*2:はてなは動画を直接埋め込めないのでツイッターに投稿したのを貼っています。