HOME > ActionScript > スライドアルゴリズム > データの更新

データの更新

移動した距離の算出

残りの処理の大まかな流れは以下の様になります。

  1. 「移動した距離の算出」
  2. 「フィールドデータの更新」
  3. 「ピース絵柄の更新」

ソースファイル slide04.zip

まず移動した距離の算出です。スライド操作終了後にピースを初期配置座標へ全て戻したら、マウスプレスからマウスリリースまでの間にマウスポインタが動いた距離を調べ、その距離を素にピースが何セル動いたかを算出します。
piecesPutBack()(main.as 450行目辺り)の後半でその処理を行っています。

移動距離をピクセルからセル単位に

スライド操作でマウスがどれだけ移動したかを計測し、その距離をピクセルからセル単位に変換して、そのセル数をピースの移動量に適用します。
例として、マウスの移動距離が80pxの場合、セルのサイズは縦横40pxの正方形ですので、ピースは2セル分スライド(移動)したという事になります。

移動距離はグローバル変数measureに記録します。onPiecesScroll()(main.as 366行目)の中で、フレーム毎にマウスの移動距離を算出しているのでそれを加算しておきます。

スナップ

マウスの移動距離は大抵中途半端な数値になりますのでセルの位置にピッタリ合うように補正してしまいます。これをここではスナップと呼びます。
スナップする場合に、マウスリリースした位置から左右(もしくは上下)のどちらのセルにスナップするかを決めなくてはなりません。今回は半端な数値がセルの幅や高さの半分よりも大きい場合には一つ先のセルにスナップする用に補正しています。

フィールドデータ更新

ピースを何セル動かしたかがわかったら、実際にフィールドのデータ(piecesFieldData)を更新していきます。
データの置き換えは、fieldDataUpdate()(main.as 221行目)で処理しています。
fieldDataUpdate()が実行されるのはpiecesPutBack()内のピースの移動量を算出した後です(main.ass 459行目)。

あまり起きない状況なのですが、スライドの有効領域ギリギリで一番端から端まで動かしたりした場合や、高速にマウスをスライドすると稀に大きな値が計測される事があるので、そんな時の為にfieldDataUpdate()を実行しない評価を用意しておきます(main.ass 456行目)。
この評価によりピースの移動したセル数が、表示エリアセルの縦の並び数や横の並び数と同じか、それよりも大きい場合にはfieldDataUpdate()は実行されません。
要するにスクロールが一回りしたら元に戻るので、フィールドのデータも更新せずにそのままにしておくという理屈です。

fieldDataUpdata()内の処理についてですが、パッと見るとちょっとややこしそうにみえるかもしれませんので、順を追って説明して行きます。
処理の流れの大枠としては次の様なフローです。

  1. 入れ替わる一連のピースが配置されているセルの番号をグループ化(Vector配列)
  2. ピースが移動したセル数分、グループ化した配列要素を入れ替える
  3. 更新用のデータを用意して上書き

1. 入れ替わる一連のピースが配置されているセルの番号をグループ化(Vector配列)

まずは入れ替わる一連のピースが配置されているセルの番号をVector配列に保存してグループ化します。
ピースを動かす処理のところでグループ化(グローバル変数scrollPiecesData)した番号は、実際に配置されているピースインスタンスの参照を保持しているpieces配列のインデックス(つまりピースインスタンスを特定する為の番号)のグループ化でした。
今回はpiecesFieldData配列に収まっている、フィールド上に配置されたピースの絵柄情報のデータを操作する為に必要な番号(piecesFieldData配列のインデックス)のグループ化です。
といっても、両者の番号は実は同じピースを指しているのでここまでの処理で既に作成済みのscrollPiecesDataを流用します。

scrollPiecesDataに保存してあるデータは、pieces配列の要素の中で「スクロールさせるピースの参照を保持する要素のインデックス」をグループとして保存してあるので、表示エリアに関わる部分だけをコピーして新しい配列を用意します。
例として横スクロールした場合、scrollPiecesDataのデータの内容は下の図のようになっていますので、表示エリアに相当するインデックス位置の要素だけを抜き出します。

この抜き出して作成した配列は、移動前の状態を保存して全く変更しないものと、移動した後の状態を作成して保存するものを用意します。
二つの配列はfieldDataUpdata()のローカル変数として宣言します(main.as 232、233行目)。

var indexes:Vector.<int>; // 移動前のインデックスの並びを保存しておく配列
var shiftIndexes:Vector.<int>; // 移動した後のインデックスの並びを保存する配列

2. ピースが移動したセル分、要素を入れ替える

抜き出して用意した配列のshiftIndexesを使用して、この配列の要素をピースが移動したセル数分入れ替えます。例として12番のピースをマウスプレスして、そのままピースを左へ2セル分スライドさせた場合の入れ替え処理です。

左へ2セル分スライドすると言う事は、プレスされたピースよりも左にある二つが右側へ移る事になります。データの状態で言いますと右図のような入れ替えになります。

具体的な手順ですが、プレスされたピースの位置よりも左にある二つのピースの番号が入っているのは、shiftIndexes配列の先頭二つの要素です。まずこの先頭の要素二つの値を順に配列の末尾に追加します。その後、値の追加元になった先頭二つの要素を削除します。
(ここでもshift()、unshift()メソッドは処理が遅いのでループ処理内では使用しないようにしています。それらの処理が必要な時は一旦reverse()を実行してからpush()して再度reverse()する方が処理が速かったりします。ただし、reverse()も随分と遅い処理ですので最小限の実行で済ませるような構成が理想です。)

これで移動後の状態、つまりどのセルにあったピースがどのセルへ移動するかの情報の準備は完了です。
ですが、これだけですと「左へ2セル移動した」という経過がわかっただけです。10番の位置にあったピースが13番の位置へ、11番の位置にあったピースが14番の位置へというように移動先を示しているだけにすぎません。

piecesFieldDataを更新する為には「移動して絵柄がこうなった」という絵柄のコードをまとめたデータを用意しなければなりません。

3. 更新用のデータを用意して上書き

では移動後のピースの絵柄はどう変わったかのデータを用意します。そのデータが用意できれば後はpiecesFieldDataの対象要素の値をそのデータで上書きするだけです。
この移動後の絵柄のデータはVector配列replacedDataにまとめます。この配列もfieldDataUpdata()のローカル変数として宣言しています(main.as 234行目)。

// 移動した後の絵柄の並びを保存する配列
var replacedData:Vector.<int> = new Vector.<int>();

「移動後のピースの絵柄はどう変わったか」とは先の例で言いますと、10番のピースの絵柄が今度は13番のピースの絵柄に。11番のピースの絵柄が今度は14番のピースの絵柄に。。。という入れ替わりの状態の事ですので、先のステップで用意したshiftIndexesの値をここで利用します。

shiftIndexesの要素順で、要素に入っている値(piecesFieldDataのインデックス番号)の通りに、piecesFieldDataから値を取り出して新しい配列を作れば、更新用データの出来上がります。
これは移動後の状態を保存したshiftIndexesと、移動前の状態のままを保存したしたindexesの両方で、PiecesFieldDataから値を取り出して作った配列の状態を比較するとわかりやすいです。

あとは移動前の状態保存したindexesの値の通りに、replacedData配列の値をpiecesFieldDataに上書きを書ければデータの更新は完了です。

絵柄の更新

最後に移動後の状態で更新されたpiecesFieldDataにしたがって、フィールド上に存在する全てのピースの絵柄を変更すればスライド処理は終了です。
絵柄の更新はpiecesUpdate()(main.as 328行目)で行い、piecesPutBack()内でfieldDataUpdate()の実行後に続けて実行されます(main.ass 462行目)。 その後再びマウスプレスのイベントリスナーを登録(main.ass 465行目)して、処理は振り出しに戻ります。

動作確認

説明はしませんがピースにマウスオーバーした際の処理をおまけでつけてます。
簡単ですのでソースを追ってみてください。

Flashファイルをご覧いただくためには、
アドビシステム株式会社のフラッシュプレーヤー(Flash Player)が必要です。
インストールされていない方は下のボタンから、最新版が無償で入手できます。

Adobe Flash Playerのダウンロード

ソースファイルについて

ダウンロードリンクにあるzipファイルの中にはドキュメントクラスとなるMain.asファイルの他に、CS5とCS4形式で保存したflaファイルが一つずつ入っています。これらのflaファイルはCS4とCS5のバージョン以外では開けません。中のフォルダ構成がそのままならflaファイルをFlash CS5もしくはCS4で開いてパブリッシュすれば動作するはずですが、フォルダやファイルを個別に移動した場合はそれに合わせて適宜flaファイルの設定を変更して下さい。

  • PiecesSlide.fla (CS5用)
  • PiecesSlide_forCS4.fla (CS4用)
  • src/Main.as
  • bin/

基本的にはCS5用のファイルを使用する事が前提で進めますが、FlashCS4を使用している方はCS4用の方を使用して下さい。
ただしCS4用のflaファイルについてはFlash CS5でCS4用に保存したものですので動作確認はしておりません。開けなかったり使用できない場合があるかもしれませんが、その際はどうぞご容赦願います。
またファイルの設定などはWindows環境での作業を想定していますので、Flash CS5を使用していてもそのままの設定では使えない場合があります。適宜設定を変更するなどしてご使用願います。
flaファイルの設定などがわからない場合は公式リファレンスを参考にして下さい。申し訳ありませんがご質問等にはお答えできません。

TOP