Macromedia Flash非公式テクニカルノート
if/else if/elseアクションを使った処理
ID: FN0109008 |
Product: Flash |
Platform: All
Version: 5.0
1. 処理の流れ
'if'アクションは、条件を評価して、判定が'true'であればステートメントを実行します。'else'アクションを含むと、結果が'false'の場合に、指定されたステートメントを実行します。さらに、'else
if'アクションは、最初の'if'で条件が'false'と評価されたときに、さらに条件を指定してステートメントを処理することができます。
以下のサンプルスクリプトをMovieClipのオブジェクトアクションに設定すると、水平方向に往復を繰り返します。左右の折り返し座標は、左が0で右が550(デフォルトのステージの両端)、移動の速度は1フレーム10ピクセルです。これらの初期値は、'onClipEvent (load)'ハンドラで設定しています。なお、MovieClipの'_X'プロパティは、基準点の座標です。折り返し座標に達したかどうかは、この基準点をもとに計算しています。サンプルスクリプトで使用しているメソッド・アクション・演算子などについて、詳しくは「ActionScript辞書」をご参照ください。
//初期設定
onClipEvent (load) { //MovieClipが表示されたとき実行
nDirection = 1; //移動方向: 1が右/-1が左
nStep = 10; //1フレーム当たりの移動速度(ピクセル)
nMinX = 0; //左の折り返し地点の座標
nMaxX = 550; //右の折り返し地点の座標
}
//アニメーション処理
onClipEvent (enterFrame) { //フレーム移動時に実行
nNextX = _x+nStep*nDirection; //つぎの移動先のx座標を計算
if (nNextX>=nMaxX) { //つぎの移動先座標が右の折り返し地点を超えた場合
_x = nMaxX; //右の折り返し地点の座標に移動
nDirection = -1; //移動方向を左(-1)に設定
} else if (nNextXn<=MinX) { //つぎの移動先座標が左の折り返し地点を超えた場合
_x = nMinX; //左の折り返し地点の座標に移動
nDirection = 1; //移動方向を右(1)に設定
} else { //その他(左右の折り返し地点の中間)の場合
_x = nNextX; //つぎの移動先の座標に移動
}
}
'else if'は、'else'アクションの中に'if'アクションを記述(ネストあるいは入れ子に)したのと同じ処理になります。上述のスクリプトで条件判定の部分は、以下のように記述することもできます。'else if'アクションを使った方が、スクリプトは見やすくなります。
if (nNextX>=nMaxX) {
_x = nMaxX;
nDirection = -1;
} else {
if (nNextX<=nMinX) {
_x = nMinX;
nDirection = 1;
} else {
_x = nNextX;
}
}
なお、'else if'アクションは、「ActionScript辞書」に記載がありません。ただ、これは単なる漏れだと思われます。ActionScript Dictionary(ActionScript辞書英文改訂版)には、掲載されています。
2. 条件の順序
条件が'true'と評価されると、指定されたステートメントを実行して、そのレベルの条件分岐処理は終了します。続く'else if'の条件を同時に満たす場合であっても、そのステートメントは実行されません。したがって、条件を判定する順序は重要です。この点を理解して、うまく整理すると、すっきりとしたスクリプトを書くことができます。
2000年問題で、閏年が注目されました。閏年は、4で割れる年です。ただし、100で割り切れる場合には、例外として閏年になりません。さらにその例外として、400で割り切れる場合には閏年です。この最後の例外まで考慮していないプログラムは、2000年を閏年でないと判定して、問題の生じる可能性があった訳です。では、閏年を判定する関数をActionScriptで書くとどうなるでしょう。これは、例外から先に処理していくと、見やすい構造になります。
//閏年を判定する関数
function xIsLeapYear (nYear) {
var bResult; //ローカル変数宣言
//まず例外から判定
if (nYear%400 == 0) { //400で割り切れる
bResult = true; //閏年: 'true'を変数に代入
//400では割り切れない場合
} else if (nYear%100 == 0) { //100で割り切れる
bResult = false; //閏年でない: 'false'を変数に代入
//100でも割り切れない場合
} else if (nYear%4 == 0) { //4で割り切れる
bResult = true; //閏年: 'true'を変数に代入
} else { //その他の場合
bResult = false; //閏年でない: 'false'を変数に代入
}
return bResult; //変数の値を返す
}
3. 見やすさか速さか
閏年判定のスクリプトは、見やすい構造になっています。けれど、処理の速度を考えると、問題がないわけではありません。条件判定は、'true'と評価されたら指定のステートメントを実行して、その処理を抜けます。つまり、先に'true'と判定されれば、後の判定をやらずに済みます。最後の判定まで'true'と評価されなければ、条件の数だけ処理が増えることになります。
そう考えて上述のスクリプトを見ると、真っ先に処理を終えるのは400年に一度の閏年の場合です。逆に、約4分の3を占めるはずの通常の年は、最後の判定まで処理を抜けられません。処理の効率からいうと、これは決して最適とはいえないのです。効率を考えて条件の順序を変えたのが、以下のスクリプトです。
//効率を考えた閏年を判定する関数
function xIsLeapYear (nYear) {
var bResult;
//まず普通の年から判定
if (nYear%4 != 0) { //4で割り切れない
bResult = false; //普通の年
//4で割り切れる場合
} else if (nYear%100 != 0) { //100で割り切れない
bResult = true; //普通の閏年
//100で割り切れる場合
} else if (nYear%400 != 0) { //400で割り切れない
bResult = false; //例外的に閏年でない
} else { //400で割り切れる場合
bResult = true; //例外の例外の閏年
}
return bResult;
}
任意の年を大量に判定する場合には、このスクリプトの方が処理は速くなります。ただ、見やすい構造とはいえないかもしれません。見やすさと速さのどちらを優先するかは、その処理の内容によります。ゲームのアニメーションを制御するスクリプトでしたら、スピードが重要なことも多いです。閏年を判定する関数の場合には、大量一括処理をするというケースはあまり考えにくいといえます。そのときには、スクリプトの見やすさを優先した方がよいでしょう。
4. もっと速さを
上述の効率を考えたスクリプトには、まだ若干処理速度を改善する余地があります。まず、条件の判定で、0以外の数値は'true'と評価されます。したがって、(nYear%整数 != 0)は、単に(nYear%整数)と記述することができます。つぎに、判定後のステートメントで、結果を一旦変数bResultに代入している点です。これは、条件が'true'と評価された場合には、他の判定を行うことなく処理を抜けることを示すため、このような記述にしました。けれども、変数に代入せず、直接'return'アクションで値を返す方が、簡潔な処理になります。なお、'return'アクションは、値を返して、直ちに関数の実行を終了します(詳しくは、「ActionScript辞書」をご参照ください)。
なお、'?:'条件演算子を使うと、さらに処理が速くなります。'?:'は、条件の評価に対応して値を返す演算子です(詳しくは、「ActionScript辞書」をご参照ください)。Microsoft
Excelの'if'関数のようなものと考えればよいでしょう。いつも'if/else if/else'条件処理の代替になるとはかぎりません。ただ、今回の例のように、値を返す処理の場合には、この演算子を使うとスピードが速くなります。
以下が、'?:'演算子を使ったサンプルスクリプトです。処理構造は、上述の効率を考えたスクリプトと同じです。サンプルは見やすいように途中改行を入れていますが、「アクション」パネルの「ノーマルモード」では、'return'アクションのステートメント1行になります。とくに解説はつけませんので、練習問題として考えてみてください。
function xIsLeapYear (nYear) {
return (nYear%4) ? false :
((nYear%100) ? true :
((nYear%400) ? false :
true));
}
_____
作成者: 野中文雄
作成日: 2001年9月21日
© 2001 and beyond Fumio Nonaka All rights reserved.
|