簡易 RPG 戰鬥:攻擊與補血

題目來源: Alpha Camp 學期 2-1
題目的主要目的是 Javascript function 的練習。設計 function 的運作方式,利用 if + return 來控制需要提早跳出函式的情況,及使用 this 取到物件自身。

題目原本僅要求專注在 攻擊(attack)治療(cure) function 的撰寫,其餘流程已由原題目提供。但基於再次練習的目的,且題目其餘部分也是由學過的 while 迴圈組成,所以這次練習會從頭把整個流程寫出來。

解題工具

  1. function 函式
  2. while 迴圈
  3. if statement

題目要求

  1. 預設戰士 hp 為 100、 mp 為 30;魔法師 hp 為 30、 mp 為 100。
  2. 由魔法師先攻,若有任一方死掉,則遊戲結束,不能再有補血或攻擊動作;反之,若兩個角色都活著,則遊戲可一直正常執行,直到一方死掉。
  3. 攻擊者會呼叫 attack() 攻擊敵方,產生 1~100 點之間隨機點數的傷害。
  4. 若被攻擊方沒有死,則會呼叫 cure() 為自己補血,補血規格為:每次補血固定為 15 點 hp 、每補充 1 點 hp 需要 2 點 mp。補血結束後攻守交換。
  5. cure() 會傳入一個參數為 hp ,指的是想要補充的 hp
  6. 補血可以補超過原有的 hp,沒有 hp 最大值上限,只要有 mp 都可以補血。

    原題目是由戰士先攻,但為了方便觀察輸出結果,改由魔法師先攻。

解題過程

拆解流程

  1. 創建角色(含 namehpmpattack()cure() )
  2. 戰鬥流程
    1
    2
    3
    4
    5
    while 戰士及魔法師都活著
    則魔法師先攻、戰士師補血(補血是否執行由函式決定)
    if 戰士還活著
    則戰士攻擊、魔法師補血(補血是否執行由函式決定)
    任一方死掉,則遊戲結束。

解題開始

function 設計

  1. 攻擊動作 attack()

    • 產生攻擊點數、輸出攻擊資訊
    • 結果1(打死): 輸出”對手死亡”
    • 結果2(沒打死): 輸出”對手活著”,且對手啟動cure()
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      function attack (enemy) {
      hpLose = Math.floor(Math.random() * 100) + 1
      console.log(`${this.name} hit ${enemy.name}, ${enemy.name} lose ${hpLose} HP.`)
      enemy.hp -= hpLose

      if (enemy.hp <= 0) {
      console.log(`${enemy.name} is dead.\n`)
      return enemy.hp = 0
      } else {
      console.log(`${enemy.name} is still alive. (HP = ${enemy.hp})`)
      enemy.cure(15)
      }
      }
  2. 治療動作 cure()

    • 結果1(mp夠): 啟動治療並輸出治療結果
    • 結果2(mp不夠): 不治療繼續
    • 攻守互換
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      function cure (hp) {
      if(this.mp >= (hp * 2)) {
      this.hp += hp
      this.mp -= hp * 2
      console.log(`${this.name} recovered. (HP = ${this.hp};MP = ${this.mp})`)
      } else {
      console.log(`MP isn't enough! ${this.name} cannot use cure.`)
      }
      console.log(`\n-------------- Change Side ---------------`)
      }
  3. 角色建立 player()

    • 需含名稱、HP、MP、攻擊動作、治療動作
    • 練習不同的 function 使用方式(把 function 放進 function 裡)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      function player (name, hp, mp) {
      return {
      name: name,
      hp: hp,
      mp: mp,
      cure: function (hp) {......},
      attack: function (enemy) {......}
      }
      }

解題流程

  1. 創建並輸出角色資料
  2. 戰鬥開始(迴圈內容)
    • 如果兩人都活著,則戰鬥開始,魔術師先攻,回合結束
    • 如果上回合戰士還活著,則攻守交換
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      // create players
      const warrior = player('Warrior', 100, 30)
      const magician = player('Magician', 30 ,100)
      console.log(warrior)
      console.log(magician)

      // start fight
      console.log('-------------- Start Fight ---------------')
      while (warrior.hp > 0 && magician.hp > 0) {
      magician.attack(warrior)
      if (warrior.hp > 0) {
      warrior.attack(magician)
      }
      }
      console.log('--------------- Game Over ----------------')

小結

在重寫的過程中又發現了一些自己不熟的地方……寫物件的時候,居然把 key 跟 value 中間的 : 寫成 = 了!

這題練習對我其實滿有效的,包含 thisreturn 的使用時機,還有在函式裡呼叫函式的寫法(這部分讓我把 while 迴圈大改,在被攻擊的對象還活著的時候直接呼叫治療函式)。以自己覺得順暢的方式改完後,發現還是可以順利跑出相同結果,表示 function 目前的課程應該有一定程度的熟悉了!

文章內容如有錯誤,歡迎留言討論!


本 Blog 上的所有文章除特别聲明外,均採用 CC BY-SA 4.0 協議 ,轉載請註明出處!