「JavaScriptでサイコロ後の処理」の編集履歴(バックアップ)一覧に戻る
JavaScriptでサイコロ後の処理」を以下のとおり復元します。
サイコロはただ振るために存在するのではない。サイコロの目によって、必ず何かをするためにある。戦闘中以外に限っても、「治療薬を飲んで生命点を回復する」「魔法が効いたか判定する」「眠って生命点の回復を試みる」「戦闘前に敵が友好的か調べる」「戦闘前に敵にワイロが効くか調べる」。。。いっぱいある。

サイコロを振りはじめる関数 dice.start(num, str) に2つの引数を持たせた。第1引数はサイコロの数。第2引数はサイコロを振った後の指示を遺言 dice.after_do で残しておく。これでうまくいく。

ユーザーが「治療薬を飲む」というボタンをクリックして、 click_Healing_Potion() を呼び出したとしよう。

 <INPUT TYPE="button" NAME="治療薬" VALUE="飲む" onClick="click_Healing_Potion()">

click_Healing_Potion() 関数は最後に dice.start() を実行する。dice.start() の第2引数として "Healing_Potion" という遺言を残しておく。

 click_Healing_Potion = function() {
     if (Pip_event[i].num <= 0) { // 所持する治療薬の数を調べる。iは別で計算している
         add_msg("治療薬はもう残っていない。");
     } else if (combat.onCombat === true) { // 戦闘中
         add_msg("治療薬を飲む。サイコロを2個振れ。");
         combat.do_next = "Healing_Potion"; // この遺言は実際は使ってない
         dice.start(2, "Healing_Potion");
     } else { // 移動中
         add_msg("治療薬を飲む。サイコロを2個振れ。");
         dice.start(2, "Healing_Potion");
     }
 }

そして、dice.start() 関数は、dice.after_do に遺言の "Healing_Potion" を書き留めておき、 dice.roll2dice() 関数を0ミリ秒後に実行する。

 dice.start = function(num, str) {
     this.rolling_state = "rolling"; // サイコロを "rolling" として
     dice.after_do = str; // 遺言を書き留める
     switch (num) {
         case 1:
             setTimeout("dice.roll1die()" ,0); // サイコロ1個を振る
             break;
         case 2:
             setTimeout("dice.roll2dice()" ,0); // サイコロ2個を振る
             break;
         case 3:
             setTimeout("dice.roll3dice()" ,0);  // サイコロ3個を振る
             break;
     }
 }

dice.roll2dice() 関数は、dice.stop() が外から実行されるまで、100ミリ秒毎にサイコロ2個を回し続ける。

 dice.roll2dice = function() {
     // ユーザーがdice.stop();を押すとdice.rolling_state === "rolled"になり、止まる
     if (this.rolling_state === "rolling") { 
     
         ctx.clearRect(0, 0, 500, 210); // canvasをいったんクリア
 
         this.die1pip = Math.ceil(Math.random() * 6); // 左のサイコロの目
         switch (this.die1pip) {
             case 1:
                 draw_pip1(150, 105); // 1の目のサイコロを描く
                 break;
             case 2:
                 draw_pip2(150, 105); // 2の目のサイコロを描く
                 break;
             case 3:
                 draw_pip3(150, 105); // 3の目のサイコロを描く
                 break;
             case 4:
                 draw_pip4(150, 105); // 4の目のサイコロを描く
                 break;
             case 5:
                 draw_pip5(150, 105); // 5の目のサイコロを描く
                 break;
             case 6:
                 draw_pip6(150, 105); // 6の目のサイコロを描く
                 break;
         }
 
           this.die2pip = Math.ceil(Math.random() * 6); // 右のサイコロの目
         switch (this.die2pip) {
             case 1:
                 draw_pip1(350, 105); // 1の目のサイコロを描く
                 break;
             case 2:
                 draw_pip2(350, 105); // 2の目のサイコロを描く
                 break;
             case 3:
                 draw_pip3(350, 105); // 3の目のサイコロを描く
                 break;
             case 4:
                 draw_pip4(350, 105); // 4の目のサイコロを描く
                 break;
             case 5:
                 draw_pip5(350, 105); // 5の目のサイコロを描く
                 break;
             case 6:
                 draw_pip6(350, 105); // 6の目のサイコロを描く
                 break;
        } 
 
         // dice.roll_speed === 100ミリ秒後に自分自身を呼び出す
         setTimeout("dice.roll2dice()", this.roll_speed); 
     }
 }

 <canvas id="dice_canvas" width="500" height="210" onclick="dice.stop()" style="background: #ccffcc;"></canvas>

ユーザーが回っているサイコロをクリックすると、 dice.stop() が呼び出され、dice.rolling_state が "rolling" から "rolled" になり、dice.roll2dice() が自分自身を呼び出さなくなり、サイコロが止まる。

さらに、if - else if のカスケードで、遺言の dice.after_do が何だったのか調べ、その遺言に応じた関数を呼び出す。治療薬の場合は dice.after_do が "Healing_Potion" になっているので、0ミリ秒後に use_potion() 関数が実行される。

 dice.stop = function () {
     if (this.rolling_state === "rolling") { // サイコロが回っていないと何もしない
         this.rolling_state = "rolled"; // サイコロを止める。
     }
     dice.dice12pip = dice.die1pip + dice.die2pip; // 2個のサイコロの目の合計
     dice.dice123pip = dice.die1pip + dice.die2pip + dice.die3pip; // 3個のサイコロの目の合計
 
     if (dice.after_do === "Healing_Potion") { // 治療薬を飲んだ
         window.setTimeout(use_potion, 0);
     } else if (dice.after_do === "honey") { // ハチミツを食べた
         window.setTimeout(use_honey, 0);
     } else if (dice.after_do === "sumonFred") { // 悪魔フレッドを召還した
         window.setTimeout(sumonFred, 0);
     } else if (dice.after_do === "Resurrection_Wand") { // 復活の杖を試みた
         window.setTimeout(use_Resurrection_Wand, 0);
     } else if (combat.onCombat === true) { // 戦闘中なら
         window.setTimeout(combat.ctrl, 0); // combat.ctrl()関数に制御を渡せ
     } else if (dice.after_do === "section_ctrl") { // セクション内の処理なら
         window.setTimeout(Section.ctrl, 0); // Section.ctrl()関数に制御を渡せ
     } else if (dice.after_do === "Pip_Sleep"){ // 眠りを選んだ
         window.setTimeout(Pip_Sleep, 0); 
     } else if (dice.after_do === "good_Sleep"){ // 眠りで安眠できた
         window.setTimeout(good_Sleep_recovery, 0); 
     } else if (dice.after_do === "Dreamtime"){ // 眠りで夢時間行きになった
         Section.num = "D" + this.dice12pip; // 夢時間セクションは D + 2個のサイコロの目
         window.setTimeout(Section.ctrl, 0); // 指定した夢時間セクションに行け
     } else if (dice.after_do === "Marlins_house"){ // マーリンの隠れ家に瞬間移動
         Section.num = "M" + this.die1pip; // マーリンの隠れ家は M + 1個のサイコロの目
         window.setTimeout(Section.ctrl, 0); // 指定した面からマーリンの隠れ家に入れ
     } else if (dice.after_do === "fix_magic_num"){ // マーリンの隠れ家の魔法の品の個数を決める
         window.setTimeout(Marling_magic_num, 0);
     } else if (dice.after_do === "Friendly_Reaction_Pip"){ // 友好反応を次はピップがサイコロを振る番
         window.setTimeout(Friendly_Reaction_Pip, 0);
     } else if (dice.after_do === "Friendly_Reaction_decision"){ // 友好反応の正否を判断
         window.setTimeout(Friendly_Reaction_decision, 0);
     } else if (dice.after_do === "Bribery_decison"){ // ワイロの正否の判断
         window.setTimeout(Bribery_decision, 0);
     } else { // 例外処理
         add_msg("サイコロ振った後なにもしなかった。ちなみにdice.after_do = " + dice.after_do);
     }
 }

use_potion() 関数は、lose_event("治療薬", 1) 関数で治療薬を1個消費して、ピップの生命点 Pip.LIFE_POINT を回復させ、画面の更新関数 updata_status() を実行する。

 function use_potion() {
     add_msg("ピップは治療薬を使った。");
     lose_event("治療薬", 1);
 
     Pip.LIFE_POINT = Math.min(Pip.LIFE_POINT + dice.dice12pip, Pip.max_LIFE_POINT); // 生命点は最大値を超えない
 
     add_msg("ピップの生命点が" + dice.dice12pip + "点回復した。");
     update_status(); // 変数をWeb画面表示に反映
 
     if (combat.onCombat === true) { //戦闘中なら
         combat.Pip2enemy_turn(); // ピップから敵へ順番を渡すか調べる
     }
 }

移動中の場合は処理は終わり。もし戦闘中の場合には(combat.onCombat === true)、これはピップの戦闘中の行動なので、ピップから敵へ攻撃順序を回してよいか調べる combat.Pip2enemy_turn() を呼び出す。

復元してよろしいですか?