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(); } |