JavaScriptでドラゴンクエストのようなRPGをつくる(2)の続きです。
プレイヤーによる攻撃
敵を攻撃するときは通常攻撃と攻撃魔法があります。前者のときは引数falseでFight関数が、後者のときは引数trueで同関数が呼び出されます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12  | 
						// 通常攻撃 function NormalAttack(){     Fight(false); } // 魔法による攻撃 function Magic1(){     if(playerMP >= 3){         playerMP -= 3;         Fight(true);     } }  | 
					
Fight関数は敵を攻撃する処理をおこないます。攻撃の結果は自作関数ShowAttackResultで表示されます。そのあと敵を倒したときはOnPlayerWin関数で、敵を倒せなかったときはEnemyAttack関数を実行して敵に攻撃をさせます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36  | 
						function Fight(isMagic) {     if(!showCommandButtons)         return;     showCommandButtons = false;     let wait = 750;     messageOnBattle = `${playerName}の攻撃`;     let interval = wait;     let interval2 = wait * 2;     if(isMagic){         interval = wait * 2;         interval2 = wait * 3;         setTimeout(() =>{             messageOnBattle = `${playerName}は${magicName}を唱えた`;             magicSound.currentTime = 0;             magicSound.play();         }, wait);     }     let isPlayerWin = false;     setTimeout(() =>{         isPlayerWin = ShowAttackResult(isMagic);     }, interval);     setTimeout(() =>{         if(isPlayerWin){             OnPlayerWin(wait);             return;         }         EnemyAttack(wait);     }, interval2); }  | 
					
ShowAttackResult関数はプレイヤーによる攻撃結果を取得して表示します。その攻撃で敵を倒すことができた場合はtrueを、そうでない場合はfalseを返します。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36  | 
						function ShowAttackResult(isMagic){     // 敵に与えるダメージを乱数で取得     let damage = Math.ceil(Math.random() * 10);     // 攻撃魔法を用いたときはダメージを加重する     if(isMagic)         damage += 16;     if(scene == SCENE_ZAKO_BATTLE){         if(isMagic)             messageOnBattle = `敵に${damage}のダメージ`;         else             messageOnBattle = `敵に${damage}のダメージ`;         hitSound.currentTime = 0;         hitSound.play();         enemyHP -= damage;         if(enemyHP <= 0)             return true;         else             return false;     }     if(scene == SCENE_BOSS_BATTLE){         if(isMagic)             messageOnBattle = `魔王に${damage}のダメージ`;         else             messageOnBattle = `魔王に${damage}のダメージ`;         hitSound.currentTime = 0;         hitSound.play();         bossHP -= damage;         if(bossHP <= 0)             return true;         else             return false;     }     return false; }  | 
					
敵を倒したときの処理
OnPlayerWin関数は敵を倒したあとの処理をおこないます。
ザコ敵を倒したらシーンはSCENE_BLACK_OUTを経てSCENE_FIELDに変わります。ボス敵を倒したときはゲームクリアの処理をおこないます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33  | 
						function OnPlayerWin(wait){     if(scene == SCENE_ZAKO_BATTLE){         messageOnBattle = `敵をたおした。`;     }     if(scene == SCENE_BOSS_BATTLE){         messageOnBattle = `魔王をたおした。`;         cleared = true;     }     StopBgm();     battleEndSound.currentTime = 0;     battleEndSound.play();     setTimeout(() =>{         messageOnBattle = '';         if(scene == SCENE_ZAKO_BATTLE){             scene = SCENE_BLACK_OUT;             setTimeout(() =>{                 playerMaxHP++;                 scene = SCENE_FIELD;                 PlayBgm(bgm);             }, wait);         }         if(scene == SCENE_BOSS_BATTLE){             scene = SCENE_BLACK_OUT;             setTimeout(() =>{                 ToGameClear();             }, wait * 2);         }     }, wait); }  | 
					
ゲームクリア後の処理
ゲームクリア後の処理を行なうToGameClear関数を示します。
シーンをSCENE_MY_CASTLEに戻してプレイヤーをゲーム開始時の位置に戻します。そして王女にお礼の言葉を語らせます。そのあと’GAME CLEAR’の文字ともう一度ゲームをするためのボタンを表示させます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  | 
						function ToGameClear(){     scene = SCENE_MY_CASTLE;     PlayBgm(bgm);     cleared = true;     InitPlayerPosition();     message = "魔王を倒していただき\nありがとうございました。";     let wait = 2000;     setTimeout(()=>{         message = 'GAME CLEAR';     }, wait);     setTimeout(()=>{         if($retry != null)             $retry.style.display = 'block';     }, wait * 2); }  | 
					
敵の攻撃
敵を攻撃してそのターンで倒すことができなかった場合は敵の攻撃がおこなわれます。攻撃の結果、プレイヤーのHPが0にならなかった場合は次のターンに移ります。HPが0になった場合はプレイヤーの負けです。OnLosePlayer関数を呼び出して敗戦後の処理をおこないます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24  | 
						function EnemyAttack(wait){     if(scene == SCENE_ZAKO_BATTLE)         messageOnBattle = `敵の攻撃`;     if(scene == SCENE_BOSS_BATTLE)         messageOnBattle = `魔王の攻撃`;     setTimeout(() =>{         let damage = Math.ceil(Math.random() * 10);         messageOnBattle = `${playerName}に${damage}のダメージ`;         damageSound.currentTime = 0;         damageSound.play();         playerHP -= damage;         if(playerHP < 0)             playerHP = 0;         setTimeout(() =>{             if(playerHP > 0)                 showCommandButtons = true;             else                 OnLosePlayer(wait);         }, wait);     }, wait); }  | 
					
敗北時の処理
敵にやられてしまったときの処理を示します。自分の城に移動し、王女に’おお、死んでしまうとは情けない。’という定番の台詞を語らせます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35  | 
						function OnLosePlayer(wait){     messageOnBattle = `${playerName}はきずつきたおれた`;     StopBgm();     setTimeout(() =>{         scene = SCENE_BLACK_OUT;         setTimeout(() =>{             // スタート地点に戻る             messageOnBattle = ``;             ToStart();         }, wait * 2);     }, wait); } function ToStart(){     scene = SCENE_MY_CASTLE;     InitPlayerPosition();     playerHP = playerMaxHP;     playerMP = playerMaxMP;     PlayBgm(bgm);     let talkSpeed = 2000;     message = 'おお、死んでしまうとは情けない。';     setTimeout(()=>{         message = 'もう一度チャンスをやる。\n今度こそ魔法を倒してこい。';     }, talkSpeed);     setTimeout(()=>{         message = '';     }, talkSpeed * 2); }  | 
					
回復魔法
回復魔法を唱えたときの処理を示します。MP3を減らしてプレイヤーのHPを全回復させ、敵に攻撃させます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  | 
						function Magic2(){     let wait = 750;     if(!showCommandButtons || playerMP < 3)         return;     showCommandButtons = false;     playerMP -= 3;     messageOnBattle = `${playerName}は回復魔法を使った`;     magicSound.currentTime = 0;     magicSound.play();     setTimeout(()=>{         messageOnBattle = `${playerName}のHPが全回復した`;         playerHP = playerMaxHP;     }, wait);     setTimeout(()=>{         EnemyAttack(wait);     }, wait * 2); }  | 
					
ゲーム開始と再プレイ
最後にゲームを開始するための処理と再プレイするときの処理を示します。
開始ボタンをクリックしたときはStart関数が呼び出されます。ゲームをスタートするためのボタンを非表示にし、王女に魔王を倒すように依頼させます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26  | 
						function Start() {     if($start != null)         $start.style.display = 'none';     InitPlayerStatus();     InitPlayerPosition();     cleared = false;     PlayBgm(bgm);     message = `${playerName}さま、お願いです。\n東の城にいる魔王を倒してください。`;     messageOnBattle = '';     let talkSpeed = 2000;     setTimeout(()=>{         message = '体力を消耗したら\n私のもとに戻ってきてください。';     }, talkSpeed);     setTimeout(()=>{         message = 'けっして無理はなさらぬように。';     }, talkSpeed * 2);     setTimeout(()=>{         message = '';         this.talking = false;         started = true;     }, talkSpeed * 3); }  | 
					
InitPlayerStatus関数はプレイヤーのHPとMPを初期の最大HPとMPに設定します。
| 
					 1 2 3 4 5 6 7  | 
						function InitPlayerStatus(){     playerMaxHP = initPlayerMaxHP;     playerHP = playerMaxHP;     playerMaxMP = initPlayerMaxMP;     playerMP = playerMaxMP; }  | 
					
再プレイするボタンをクリックしたときはRetry関数が呼び出されます。
| 
					 1 2 3 4 5 6  | 
						function Retry(){     if($retry != null)         $retry.style.display = 'none';     Start(); }  | 
					
