【四川省への道】第3話


こんにちは、トラップですぅ。(^o^)/

とりあえず、苦労して作った牌を表示することができました。
さて、お次はペンでタッチしたら反転するといった、ザウルスに
不可欠なペンの処理をやってみましょう。

◎ペンタッチによる処理

 さて、ペンの動作にはどんなものがあるか・・ですが、基本的には
 「画面にタッチする」、「離す」、「タッチしたままペンを動かす」
 といったところでしょう。
 ザウルスのAdd-In BASICでは、TOUCH命令1つでこれらを知ることが
 できるようになっています。

  TOUCH X     :  最後にペンが画面に触れた時の横座標(0〜239)
  TOUCH Y     :          〃     縦座標(0〜168)
  TOUCH @X    :  現在ペンが触れている又はペンが離れた時の横座標
  TOUCH @Y    :            〃         縦座標
  TOUCH @Z    :  現在ペンが触れていれば -1, 離れていれば 1

 仮に、(110,125)の座標をペンでタッチし、そのまま(200,150)まで
 なぞってから離したとしますね。すると、次のような感じになります。

         TOUCH X , TOUCH Y , TOUCH @X , TOUCH @Y , TOUCH @Z
  ペンが触れた    110       125        110       125         -1
  そのまま移動    110       125        155       140         -1
  更に移動        110       125        200       150         -1
  ペンを離す      110       125        200       150         1
         (以下、新たにペンタッチするまで値は変わらない)

 ちょっとややこしいですが、四川省の場合は触った座標がわかれば
 いいだけですから、TOUCH X,TOUCH Y を使って考えてみましょう。
 流れは、こんな感じかなぁ・・。

  (1) ペンがタッチされるまで待つ。
  (2) 座標を TOUCH X, TOUCH Y で得る。
    (3) ドット座標から、牌の座標に変換
  (4) その位置に表示した牌を選択表示(反転)する。
    (5) (1)〜(4)くり返し

 これをそのままプログラムにすると、こんなとこでしょうか。
 (前回のプログラムと合成して、実行してください。)

    1 REMサンプル No.2
    100 WIDTH,M,N:CLS
    110 ON ERROR GOTO *ERR
    150 LOCATE0,0:PRINT"終了"
    160 *LP1
    170 CALL @11                               :'タッチされるまで待つ
    180 IF TOUCH(&0,&0,&18,&F) THEN *THEEND    :'「終了」ならTHEENDへ
    190 IF NOT TOUCH(&B,&1D,&E2,&9C) THEN *LP1 :'(11,29)-(226,156)以外ならLP1へ
    200 TX = TOUCH X                           :'タッチされた横座標を得る
    210 TY = TOUCH Y                           :'   〃  縦座標を得る
    220 PX = INT((TX+&1)/&C)                   :'牌の座標に変換
    230 PY = INT((TY-&D)/&10)                  :'   〃
    240 CALL@41,(PX*12-1,PY*16+13)-(PX*12+9,PY*16+27),1,1  :'反転
    250 GOTO *LP1
    980 *THEEND:CLS:WIDTH,,N:CALL@20:CALL@18:KEY 0,"":END
    990 *ERR:CLS:WAIT&0:PRINT ERN;ERL:CALL@11:GOTO *THEEND

 実行すると、前回同様に画面に牌が並びますので、どれでも結構ですから
 ペンでタッチしてみてください。タッチした牌が反転するでしょう。(^^)
 他の牌も同様に反転しますし、もう1度タッチすると元に戻ります。

 あ、説明せずに使いましたが、TOUCH(a,b,c,d)というのはタッチされた
 座標が、ある矩形領域内であるか否かを判定する時に使うものでして、
 180行では、左上の「終了」の領域がタッチされたかの判定用として、
 190行では、牌が描かれている範囲以外をタッチした場合に、何もせず
 *LP1 へ飛ぶための判定として用いています。

 後は、その座標をもとに、どこの牌が押されたかを調べた上で反転を
 行なうようにしています。220, 230行で INT() を利用していますが、
 これを外すとどんな事になるか試してみるのも一興ですね。(^^)

☆補足:数値の16進数表記

 Add-In BASIC では、先頭に「&」をつけた数値は16進数を示します。
 従って、「&9C」は10進数でいうところの「156」を意味しています。
 (ちなみに、これはAdd-Inのサイズを小さくする為なのです。(^^ゞ)

◎エラー処理ルーチン

 プログラム・・・それはエラーとの闘い・・・。(^^;)

 小さいプログラムならともかく、大きなものになってくると、
 どこでエラーがあったのか、探すだけでも大変な作業になります。
 そこで、少しだけ楽にするために、「ON ERROR GOTO」文を使って
 みましょう。この命令を実行しておくと、何かエラーが発生した
 時に、指定した行番号(ラベル)へ処理をまわすことができるんです。

 上のリストですと 110行にて、「エラーが起きたら*ERRに行け」と
 指定しておきましたので、実行中に何かエラーが起きたら、その
 時点で、*ERR に処理が移るというわけです。今回のエラー処理
 ルーチンでは、単にエラーの番号と、それが発生した行番号とを
 表示して、画面をタッチされるまで待つだけとなってます。

 もっとも、これでも有ると無いとではデバッグ効率が違いますから、
 もう、「WIDTH と CLS と ON ERROR GOTO 〜」 は、Add-In初期化
 処理の必須科目と思ってくださいね。(^^)

☆次回予告

 画面表示も、牌をタッチして選ぶこともできるようになりました。
 次回は、牌のプログラム的表現法にてお会いしましょう。
【今回のソースお持ち帰り】 SAMPLE2.SRC