HotSoupProcessorの記録 -6ページ目

HotSoupProcessorの記録

コンピューター言語 HotSoupProcessor の練習記録です

今日は単純です。

テキストファイルを読んで、画面に表示するプログラムです。

---
; 外部ファイルを読む
; (テキストファイル)
  ; 対象バッファを指定
  notesel fpRead
  ; ファイルを読み込む
  noteload ".\\test.txt"

  ; 出力
  mes fpRead

  stop
---

notesel でバッファを指定して、
noteload で実際に読み込む。

簡単☆


バッファを指定というのの、実際の処理のイメージがぜんぜんわかないけど、
きっとC言語で言うファイルポインタで、それを定義して、
noteloadではそこに突っ込むんだろうと推測。
なので、ファイルポインタっぽい変数名にしました。

大丈夫なのかわからないけど、
ファイルクローズの処理がないのがちょっと気になった。。
あ、noteloadの中で、オープン・読み込み・クローズ してるのかな。

間違ってるかもしれないけど、
何もなくただ記憶すると忘れちゃうので、
ファイルポインタっぽい使い方だと覚えておくことにします。
考えに違いがわかるようなことが起きたらまた報告します。
前回、クリック間を円が移動するプログラムを作りましたが、
ほんの少し手を入れるだけで、画像が移動するようにできます。
その方法のご説明です。

今回は修正箇所以外は、文字色をグレーにしてみました。
---
; クリックした2点間で絵を移動する2(画像編)
  ; クリックフラグ [ 1回目のクリック:1 | 2回目以降のクリック:0 ]
  bIsFirstClick = 1
  ; クリック座標(x,y)の2次元
  dim naPoints, 2, 2
  naPoints(0,0) = 0    ; 始点初期化(0,0)
  naPoints(0,1) = 0
  naPoints(1,0) = 0    ; 終点初期化(0,0)
  naPoints(1,1) = 0
  
  ; 絵を描く点(x,y)(WriteImageで利用する)
  dim naImagePoints, 2
  naImagePoints = 0, 0  ; 初期化(0,0)

  ; 絵を読み込む
  celload "Pacman.bmp"  ; 画像ファイル
  imgPac = stat      ; 画像のIDを保存
  ; 背景
  color 0, 0, 0
  boxf

  
  onclick gosub *DoClickEvent
  stop

; クリックイベント
*DoClickEvent
  if( bIsFirstClick=1 ){
    ; 1回目のクリック
    ; 画面をクリア
    color 255,255,255
    boxf
    
    ; 始点座標
    naPoints(0,0) = mousex
    naPoints(0,1) = mousey

    ; スタート地点に画像を書く
    naImagePoints = mousex, mousey
    gosub *WriteImage

    bIsFirstClick = 0
  }else{
    ; 2回目以降のクリック

    ; 終点座標
    naPoints(1,0) = mousex
    naPoints(1,1) = mousey
    
    ; 始点から終点に移動
    gosub *MoveImage

    ; 終点を始点に
    naPoints(0,0) = naPoints(1,0)
    naPoints(0,1) = naPoints(1,1)
  }

  return

; 画像を移動
*MoveImage
  ; クリックイベントをオフ
  onclick 0

  ; ループカウント(10回で移動する)
  i = 0
  max_i = 10

  ; 移動距離を計算
  dim naDistance, 2
  naDistance(0) = int((naPoints(1,0) - naPoints(0,0)) / max_i)
  naDistance(1) = int((naPoints(1,1) - naPoints(0,1)) / max_i)

  ; 開始位置を設定
  naImagePoints = naPoints(0)

  ; 移動ループ
  for i, 0, max_i, 1
    ; 初期化
    color 255,255,255
    boxf

    ; 移動距離を加算
    naImagePoints(0) = naImagePoints(0) + naDistance(0)
    naImagePoints(1) = naImagePoints(1) + naDistance(1)

    ; 画像を描画
    gosub *WriteImage

    await 40
  next

  ; クリックイベントをオン(復活)
  onclick 1
  
  return

; naImagePointsに画像を描く
*WriteImage
  ; 描画停止
  redraw 0

  ; 背景
  color 0, 0, 0
  boxf

  ; 画像
  gmode 2              ; 透明色ありの指定
  pos naImagePoints(0)-8, naImagePoints(1)-8
                  ; 表示位置の設定
  celput imgPac          ; 画像コピー
  
  ; 描画再開
  redraw 1

  
  return

---

修正箇所は3箇所です。

1.
初期処理で画像を読み込んでおきます。
こうすることで、後から何度も読み直す必要がなくなり、
パフォーマンスがよくなります。
(ファイルを読むことはコンピューターの世界ではかなり遅い処理)

2.
boxfしていた箇所を消しました。
理由は3.

3.
下記の処理に変更しました。
  描画を停止
  boxfで背景を塗る
  画像を表示
  描画を再開
描画の停止/再開は、画面のちらつき防止です。
(ですが今回のような簡単な絵のケースでは、ちらつきません。。
 だからどっちでもいいけど、絵を描くときはやるもんだと思っていた方がよさげです。)
boxfで背景を塗るのをこの間に入れました。
画像の表示は、一度覚えておけばずっと使える技です。



と、予想通り、簡単にできちゃいました。
最終的には絵を動かしたいので、絵が2点間を移動するプログラムを作ってみました。
絵は今回は円ですが、画像にも変更しやすいように少しだけ気を使いました。


●機能概要
1回目のクリックで、始点に円を描く
2回目以降のクリックで、前回クリックした点から今回クリックした点へ円が移動する

●実装方法概要
1回目のクリックで、始点を登録し円を描く
以後は2回目以降の処理
今回クリック座標を、終点に登録
始点⇒終点のXY座標値の差をとり、それぞれ1/10値を算出
円を描く座標に始点を設定
10回ループ{
  円を描く座標に1/10値を加算
  円を描く

今回クリック座標を始点に登録


●実装
------------
; クリックした2点間で絵を移動する
  ; クリックフラグ [ 1回目のクリック:1 | 2回目以降のクリック:0 ]
  bIsFirstClick = 1
  ; クリック座標(x,y)の2次元
  dim naPoints, 2, 2
  naPoints(0,0) = 0    ; 始点初期化(0,0)
  naPoints(0,1) = 0
  naPoints(1,0) = 0    ; 終点初期化(0,0)
  naPoints(1,1) = 0
  
  ; 絵を描く点(x,y)(WriteImageで利用する)
  dim naImagePoints, 2
  naImagePoints = 0, 0  ; 初期化(0,0)
  
  onclick gosub *DoClickEvent
  stop

; クリックイベント
*DoClickEvent
  if( bIsFirstClick=1 ){
    ; 1回目のクリック
    ; 画面をクリア
    color 255,255,255
    boxf
    
    ; 始点座標
    naPoints(0,0) = mousex
    naPoints(0,1) = mousey

    ; スタート地点に画像を書く
    naImagePoints = mousex, mousey
    gosub *WriteImage

    bIsFirstClick = 0
  }else{
    ; 2回目以降のクリック

    ; 終点座標
    naPoints(1,0) = mousex
    naPoints(1,1) = mousey
    
    ; 始点から終点に移動
    gosub *MoveImage

    ; 終点を始点に
    naPoints(0,0) = naPoints(1,0)
    naPoints(0,1) = naPoints(1,1)
  }

  return

; 画像を移動
*MoveImage
  ; クリックイベントをオフ
  onclick 0

  ; ループカウント(10回で移動する)
  i = 0
  max_i = 10

  ; 移動距離を計算
  dim naDistance, 2
  naDistance(0) = int((naPoints(1,0) - naPoints(0,0)) / max_i)
  naDistance(1) = int((naPoints(1,1) - naPoints(0,1)) / max_i)

  ; 開始位置を設定
  naImagePoints = naPoints(0)

  ; 移動ループ
  for i, 0, max_i, 1
    ; 初期化
    color 255,255,255
    boxf

    ; 移動距離を加算
    naImagePoints(0) = naImagePoints(0) + naDistance(0)
    naImagePoints(1) = naImagePoints(1) + naDistance(1)

    ; 画像を描画
    gosub *WriteImage

    await 40
  next

  ; クリックイベントをオン(復活)
  onclick 1
  
  return

; naImagePointsに画像を描く
*WriteImage
  ; 今回は円
  color 255, 100, 100
  circle naImagePoints(0)-20, naImagePoints(1)-20, naImagePoints(0)+20, naImagePoints(1)+20, 1
  return
---------
長っ!



●考えたことのいくつか

移動中にクリックイベントが起こるとやっかいになりそうなので、止めました。


2次元配列の初期化の仕方がよくわからなかったので、地道に1要素ずつ書きました。
  naPoints(0) = 0, 0
って書きたかったんだけど、コンパイルエラーだった。残念。


円じゃないもの(画像とか)へ変更しやすいように、gosubで別関数にしてみました。
最初は気にせず goto って書いてて、
return で元の位置に戻ってこないのでびびりました。
  ※dialogでダイアログボックスを出しながらデバッグして気づきました。


距離に応じて移動数(今回は10)が変わると気持ちいいかも。
めんどくさいからやらないけど。



●備考

最初、移動距離の引き算を間違えて逆にして、真逆方向へ移動するプログラムができあがりましたw