スクリプト講座その5 〜else文と複雑な条件式〜
去年すぐに頓挫してしまいましたスクリプト講座のボツ下書きが残ってたので
破棄するのももったいない気がするので公開しておきます。(その2)
現在、日記のおまけにつけている講座内容が難しく感じる場合は、
第1回の記事から順に読んでもらえると多少分かるようになるかもです!
また、講座一覧のページもまとめてみましたので貼っておきます。
* RPGツクールMV講座まとめ【スクリプト他】
こんにちは、シロップです!
前回はif文の使い方が途中で終わっていましましたね!
今回は、いくつもの条件が重なった複雑な条件分岐をする方法を解説していきます!
前回はif文を使って条件に当てはまる場合の処理を実行する方法を教えました
if(条件式){
//条件式が真<true>であるときの処理
}
else文
では、ツクールの条件分岐のように、条件式を満たさない時の処理も書くにはどうすればよいでしょうか?
答えは↓こうです!!
if($gameParty.gold() >= 100){
//100ゴールド以上持っている場合の処理
}else{
//それ以外の場合(100ゴールド未満の場合の処理
}
"それ以外"を意味する「else文」を使います!
if文の終わりの中括弧「}」のあとに、else{ //それ以外の場合の処理 }
と分岐させることができます。
if else文
さらに、このelse文ですが、それ以外の場合からさらに条件を絞る「else if」という使い方ができます!
if($gameParty.gold() >= 100){
//100ゴールド以上持っている場合の処理
}else if($gameParty.gold() >= 50){
//1つ目のif文の条件を満たさず(ゴールド100未満)、かつ50ゴールド以上の場合
}else if($gameParty.gold() >= 20){
//上の条件式をすべて満たさず(100未満かつ50未満)、かつゴールド20以上の場合
}else{
//上の条件式をすべて満たさない場合の処理
}
ツクールの条件分岐で表すと
こんな感じで、それ以外の場合の中に入れ子状態になってしまいますね。
この入れ子の状態をネストと呼ぶのですが…
ネストが深くなると今書いている処理がどの条件を満たす場合なのか分かりづらくなってしまうため嫌われています!
入れ子状態は見やすい範囲で減らしていくと「バグや意図しない動作」を避けられます。
例えば「毒状態か猛毒状態で、かつ毒消し草を持っていない場合に毒消し草を貰える」という処理を表してみると…
var leader = $gameParty.leader(); //パーティー先頭のアクター
var item = $dataItems[毒消し草のID]); //毒消し草のアイテムデータ
//leaderが毒ステートIDのステート(State)に影響されて(Affected)いるかをチェック
if( leader.isStateAffected(毒ステートID) ){
//パーティーがアイテム(item)を持って(has)いるかを問い合わせて、
//「!」で否定反転して持っていない状態なら真<true>
if(!$gameParty.hasItem(item)){
//アイテムを1つ取得(gain)
$gameParty.gainItem(item,1);
}
//leaderが猛毒ステート状態かチェックして、以下同じ内容
}else if( leader.isStateAffected(猛毒ステートID) ){
if($gameParty.hasItem(item)){
$gameParty.gainItem(item,1);
}
}
ここまでに解説した方法だけではこのようにif文が2重になってしまい、さらに毒の場合と猛毒の場合をelse if文で分けて、そこから毒消し草を持っていなければ1つ取得するという同じ内容を2回書かなければなりません。
同じ処理を何回も書くのは、修正が大変になりバグの温床となるため避けるべきです!
論理演算子
そこで、複数の条件を1つにまとめあげる「論理演算子」というものを使います。
名前だけ聞くと何じゃそれは?…とおもうかもしれませんが、「AND」と「OR」と聞けば何となくわかると思います。
「A かつ B」を表すANDは、「&&」記号で表し、
「A または B」を表すORは、「||」記号で表します!
if (条件1 && 条件2){
//条件1と条件2を両方満たす場合の処理
}
if (条件1 || 条件2){
//条件1と条件2のどちらかを満たす場合の処理
}
また、論理演算子はいくつもつなげて使えます。
括弧「()」で括って判別順を精確に指定しましょう。
「AかBで、かつCを満たす場合」というのは
「(A || B) で、かつC」と、まず最初の条件2つを括弧でくくり、
「(A || B) && C」とCの条件と&&で繋ぎます。
「A || B && C」としてしまうと、後ろから順に処理されてしまい
「A || (B && C)」、つまり「Aまたは、BかつC」と違った条件になってしまいます。
括弧()で括って、判別順を精確に!!
さぁ、先の毒消し草取得のスクリプトを書き換えてみましょう
var leader = $gameParty.leader(); //パーティー先頭のアクター
var item = $dataItems[毒消し草のID]); //毒消し草のアイテムデータ
//leaderが毒ステートIDのステート(State)に影響されて(Affected)いるかをチェック
if((leader.isStateAffected(毒ステートID) || leader.isStateAffected(猛毒ステートID)) && !$gameParty.hasItem(item)){
//アイテムを1つ取得(gain)
$gameParty.gainItem(item,1);
}
ずいぶんとすっきりしました!!
アイテムの所得処理$gameParty.gainItem(item,1)
を1回にまとめられたのは大きいでス!
……けど、これはこれで見づらいですね。
また、毒ステートか猛毒ステートかの判断を括弧で括っていますが、括弧が多くて分かりづらくなってます。
ネスト(入れ子)をへらすというのはあくまで見やすくするためですので、それでif文の条件式が見づらくなったら元も子もありません!
見やすい範囲で整理しましょう!
//leaderが毒ステートIDのステート(State)に影響されて(Affected)いるかをチェック
if(leader.isStateAffected(毒ステートID) || leader.isStateAffected(猛毒ステートID){
if(!$gameParty.hasItem(item)){
//アイテムを1つ取得(gain)
$gameParty.gainItem(item,1);
}
}
また、条件式ごとに真偽値を変数にしまっておくこともできます。
var stateCondition = (leader.isStateAffected(毒ステートID) || leader.isStateAffected(猛毒ステートID);
//leaderが毒ステートIDのステート(State)に影響されて(Affected)いるかをチェック
if(stateCondition && !$gameParty.hasItem(item)){
//アイテムを1つ取得(gain)
$gameParty.gainItem(item,1);
}
事前に変数stateCondition(訳:"ステート条件")を用意して毒か猛毒の状態であるかを代入しておき、if文の中でアイテムの所持条件と&&(AND)でつなげて判別しています。
これだと入れ子が無くて、なおかつ読みやすくなったのではないでしょうか?
ネストの仕方や条件の書き方は人によって流儀があるので、各自で見やすい書き方を試してみてください!