プログラム講座 中級編11
- 簡易アニメーションを作ろう -
 中級編11です。今回はピクチャーフィールドとPICTリソースを使って簡易アニメーションを作成してみましょう。
◆ピクチャーフィールド
 C言語などで今回作成するようなアニメーション表示アプリは結構面倒です。ちょっと画像を表示させたりする場合Future BASICは大変便利です。なんと言ってもPICT画像ハンドルかPICTリソース番号を指定するだけで表示から画面のアップデート(自動更新)まで行ってくれます。
 これがピクチャーフィールド(Picture Field)と呼ばれるものです。プログラム上でもわずか1行で終わります。
◆PICTリソースとPICTファイル
 今回のプログラムではPICTリソースを使用しますので、先にMacのファイルシステムについて簡単に説明しておきます。
 PICTファイルは「データフォーク」にPICT画像が格納されています。これに対してPICTリソースはPICT画像データが「リソースフォーク」に格納されています。Macintoshのファイルシステムは単なるデータだけでなく、さまざまなリソースを格納できるようになっています。図にすると以下のようになります。
 ピクチャーフィールドは「PICT画像」「PICTリソース」どちらでも指定することが出来ます。リソースかどうによってピクチャーフィールドの指定が異なります。リソースを指定する場合は以下のようにします。
PICTURE FIELD #1,%128
 上記の例ではピクチャーフィールドの1番に128番のリソースを表示します。詳しい書式はリファレンスマニュアルの247〜249ページに掲載されていますので、そちらを参照してください。
 PICTリソースを表示する場合は先頭に%を付加しなければなりません。直接数値を指定するだけでなく変数でも指定できますが、変数の場合でも%AnimeNoといったように先頭に%を付加しなければいけません。
 ピクチャーフィールドをウィンドウのどこに表示するかも指定しなければなりません。今回はウィンドウサイズと同じ大きさにしてあります。(アニメーションの画像サイズに合わせてウィンドウサイズを決めるといった方がよいでしょう。)
 サイズは以下のようにリソース番号の後に指定します。
PICTURE FIELD #1,%128,(0,0)-(320,24)
 サイズは定数を使用するか変数を使用した方がよいでしょう。直接数値を指定すると後々の変更が面倒になるためです。
◆PICTリソースの作り方
 PICTリソースを作るにはアプリケーションで生成する方法とリソースエディタを使用する方法があります。ここではリソースエディタを使ってPICTリソースを作成してみましょう。以下にPICTリソースを作成する手順を示します。
【1】画像を用意します。
- 今回はフォトショップを使用しました。アニメーションの作成はDirectorで行いPICTファイルで書き出しを行っています。
 
【2】画像をコピーします。

- 画像を選択しコピーします。
 
【3】リソースエディタを起動します。
【4】新しいリソースを作成します。
【5】画像をペーストします。


- ペーストすると自動的にPICTリソースになります。この時、PICTリソースの番号は128番になります(後で変更できます)。
 
【6】同様に2枚目をコピーしペースとします。
【7】自動的に番号が付き新しいPICTリソースが作成されます。

◆繰り返すアニメーション
 画像を用意したら後はプログラムするだけです。Macのアプリケーションは同じ雛形を用意するか前回のプログラムを流用すれば一応出来ます。今回のプログラムも、ほとんどの中級編と変わりません。
 今回のアニメーションは128〜133番まで合計6枚あります。普通に繰り返すプログラムを作成すると以下のようになります。(変数gPictNum%はアニメーション番号を示します)
gPictNum% = gPictNum% + 1
if gPictNum% > 133 then gPictNum% = 128
 Future BASICは、このような処理を一命令で行うことが出来ます。
DEF CYCLE (開始番号, 終了番号, gPictNum%)
 カーソルアニメーションや今回のような繰り返しする場合には便利な命令です。
- 参考
 - 上記のような繰り返し処理には別の方法もあります。繰り返す回数が2nの場合、「2n−1との論理積」を取るという方法があります。例えば8枚のアニメ画像を切り替える場合
- gPictNum% = gPictNum% AND 7
- となります。論理演算は勉強してください(^^;
- 繰り返す回数が2nでない場合は「剰余」を取ります。要するに余りを求めることになります。例えば13回繰り返す場合
- gPictNum% = gPictNum% MOD 13
- となります。PictNum%は0〜12になりますので、ちゃんと繰り返し処理が出来るのがわかると思います。
      
◆終わりに
 画像のアップデート等は自動的に行われるので何も処理する必要はありません。一定時間毎に処理を行わせるにはON TIMER(1) 関数名のようにします。
 Future BASICは便利な命令がいくつか用意されています。が、どんな時に使えば有効なのか、便利なのかは実際にプログラミングしていかないとわからない事もあります。いろいろプログラムを作成し勉強するのが一番よいでしょう。
◆今回のプログラムリスト
RESOURCES "pict.res":                             ' "結合するリソースファイル名"
OUTPUT FILE "FutureAnime":                        ' "保存するアプリケーション名"
'------------------------ "定数" ---------------------------
_startNum = 128:                                  ' "最初の画像のリソース番号"
_endNum = 133:                                    ' "最後の画像のリソース番号"
_windowLX = 256:                                  ' "ウィンドウの横幅"
_windowLY = 192:                                  ' "ウィンドウの縦幅"
'-------------------- "グローバル変数" ----------------------
gPictNum% = _startNum:                            ' "最初の画像から表示"
gQuit_flag = _false:                              ' "終了フラグ (_zTrueになると終了)"
END GLOBALS
'------------------------------------------------------
' "PICTリソースをウィンドウに表示する"
'------------------------------------------------------
LOCAL FN displayPICT
  ' "Pictureフィールドを使用してPICTリソースを表示する"
  PICTURE FIELD #1, %gPictNum%,(0,0)-(_windowLX,_windowLY),_statNoFramed + _statKeepBG,_centerPict
END FN
'------------------------------------------------------
' "PICTリソースの番号を増加させる"
'------------------------------------------------------
LOCAL FN movePICT
  DEF CYCLE (_startNum, _endNum, gPictNum%):      ' "画像ファイルの番号を増加させる"
  FN displayPICT:                                 ' "画像を表示する"
END FN
'------------------------------------------------------
' "アップデートイベントを処理"
'------------------------------------------------------
LOCAL FN eventProc
  evnt = DIALOG(0):                               ' "イベントを得る"
  IF evnt = _wndRefresh THEN FN displayPICT:      ' "アップデートイベントの時に画像を表示"
END FN
'------------------------------------------------------
' "メニュー構築"
'------------------------------------------------------
LOCAL FN initMenu
  APPLE MENU "Future Anime について..."
  
  ' "ファイルメニュー"
  MENU 1,0,_enable,"ファイル"
  MENU 1,1,_enable,"/Q終 了"
END FN
'------------------------------------------------------
' "Aboutの処理"
'------------------------------------------------------
LOCAL FN ABOUT
  err% = FN ALERT(128,0):                         ' "アバウトの表示"
END FN
'------------------------------------------------------
' "メニュー分岐処理"
'------------------------------------------------------
LOCAL FN doMenu
  menuID = MENU(_menuID):                         ' "メニューバー項目を得る"
  itemID = MENU(_itemID):                         ' "選択項目番号を得る"
  
  SELECT menuID
    CASE 255,127
      SELECT itemID
        CASE 1
          FN ABOUT:                               ' "About...が選択されたので呼び出す"
      END SELECT
    CASE 1 :                                      ' "終了メニュー"
      SELECT itemID
        CASE 1:
          gQuit_flag = _zTrue
      END SELECT
  END SELECT
  MENU
END FN
' "初期化"
ON TIMER(1) FN movePICT:                          ' "1秒毎に画像を書き換える"
ON MENU FN doMenu:                                ' "メニュー選択時の処理先"
ON DIALOG FN eventProc:                           ' "イベント発生時の処理先"
FN initMenu:                                      ' "メニューの初期化"
WINDOW OFF
WINDOW #1,"Future Anime",(4,42)-(4 + _windowLX,42 + _windowLY),_dialogMovable
FN displayPICT
' "メインルーチン"
DO
  HANDLEEVENTS
UNTIL gQuit_flag