UintCycle 循環する整数を返すクラス
2007/03/06 22:12 - AS3.0
アクションスクリプトも 3.0 に進化して、かなり Java っぽくなってきたことですし、ここらでスタンダードなコード記述に改めた方がよろしいね、ということで現在、俺ルール撲滅キャンペーン実施中な私です。
そんなわけでクラスの見直しを図っているところですが、このエントリーは作り直したクラスについて。
私の作品には、配列に対して循環的にアクセスするパターンを使ったものがいくつかあります。
一例を挙げると、下にリストアップした 3D 表現では、ステージクリックごとに各頂点座標を変更する機構に使用しています。
これらの作品では、各隊列の全頂点の座標を、下記のように array と object の 二次元配列に格納しています。
array = [ { x:x0 , y:y0 , z:z0 } , { x:x1 , y:y1 , z:z1 } , { x:x2 , y:y2 , z:z2 } , ... ... ];
そしてステージをクリックするたびに、下記のように配列へ循環アクセスし、その中身である座標を取得、隊列の変更をおこなっています。
array[0] → array[1] → array[2] → array[0] → array[1] → ...
その他にも以下のモーションタイポ作品では、複数の文字列のカレント切り替えに配列への循環アクセスを使用したりしています。
こんな感じで私は、クリック系作品ではかなりの頻度でこの仕組みを使っています (ちなみに上記サンプルは Flash 8 によるもので、その当時はまだクラス化していませんでした)。
自分にとってはかなり重要なユーティリティ系機構なんですが、今回、この循環アクセスのためのインデックス計算に今まで使っていたクラスをリライト&リネームしました。
その際、おおいに参考にさせてもらったのが以下のエントリーです。
- 循環する数値・配列を取得する (にゃあプロジェクト ウェブログ)
今までのクラスは実にド阿呆なコードで、以下のような評価をしていました。
- 普通時に if ( カウンター > 配列の長さ ) { カウンター = 0; }
- 逆転時に if ( カウンター <= 0 ) { カウンター = 配列の長さ; }
恥ずかしいっ!
何で「カウンターを配列の長さで割った余りは 0 ~ 配列の長さ-1 の値しか取らない」という基本的なことを失念していたのか。 頭悪いにも程があろうというもの。
で、リライトの結果、以下のような実にスッキリとしたコードになりました。
public class UintCycle { // -------------------- プロパティ -------------------- private var range:uint; private var flg:int = 1; private var val:int = 0; // -------------------- メソッド -------------------- // コンストラクタ public function UintCycle( range:uint , ... flg ) { // range : 循環範囲 // flg : 正逆フラグ( -1 で逆転) this.range = range; if ( flg[0] == -1 ) { this.flg = -1; } } // 循環実行 public function get cycle():uint { val += flg; val %= range; // 逆転時の判定 var offset:int = 0; if ( ( flg == -1 ) && ( val != 0 ) ) { offset = range; } return val + offset; } }
実際の使用は、以下のような感じになるでしょうか。
var array:Array = new Array(); array[0] = ○○; array[1] = ××; array[2] = □□; var uintCycle:UintCycle = new UintCycle( array.length ); ... ... ... function btnClick() { 取り出した要素 = array[ uintCycle.cycle ]; }