« get me outta code hell

csb-game - Pixelly spin-off of the Command Synergy Battle system used in Final Fantasy XIII
summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--index.js90
1 files changed, 83 insertions, 7 deletions
diff --git a/index.js b/index.js
index ec0830a..c3f6e6c 100644
--- a/index.js
+++ b/index.js
@@ -3,7 +3,11 @@
 const canvas = document.getElementById('canvas')
 
 class ATBBar {
-  constructor() {
+  constructor(battleCharacter) {
+    // Parts
+
+    this.battleCharacter = battleCharacter
+
     // State
 
     this.progress = 0
@@ -70,7 +74,21 @@ class ATBBar {
   }
 
   update(dt) {
-    this.progress = Math.min(1, this.progress + dt / 6)
+    // ATB gauge progressing
+    if (!this.battleCharacter.isExecutingChain) {
+      this.progress = Math.min(1, this.progress + dt / this.segmentCount)
+    }
+
+    // Action chaining
+    if (this.battleCharacter.isExecutingChain && !this.battleCharacter.isExecutingAction) {
+      if (this.queuedActions.length) {
+        const action = this.queuedActions.shift()
+        this.battleCharacter.executeAction(action)
+        this.progress -= 1 / this.segmentCount * action.size
+      } else {
+        this.battleCharacter.isExecutingChain = false
+      }
+    }
   }
 
   getRemainingSpace() {
@@ -82,9 +100,24 @@ class ATBBar {
   }
 
   activate() {
-    this.queuedActions.splice(0)
-    // TODO: Do something
-    // (We won't actually be splicing just like that later - it'll activate actions one by one, unshifting each as it goes, with the action menu hidden until the queue is empty, or cancelled)
+    if (this.queuedActions.length) {
+      // Cut off the actions that we don't have enough ATB charge for
+      let cutoff = 0, segment = 0
+      while (cutoff < this.queuedActions.length) {
+        segment += this.queuedActions[cutoff].size
+        if (segment > this.progress * this.segmentCount) {
+          break
+        }
+        cutoff++
+      }
+      if (cutoff === 0) {
+        // If we don't have enough charge to execute even one action, just don't do anything
+        return
+      }
+      this.queuedActions.splice(cutoff)
+
+      this.battleCharacter.isExecutingChain = true
+    }
   }
 }
 
@@ -208,7 +241,50 @@ class ActionMenu {
   }
 }
 
-const atbBar = new ATBBar()
+class BattleCharacter {
+  constructor() {
+    // Parts
+
+    this.atbBar = new ATBBar(this)
+
+    // State
+
+    this.isExecutingChain = false
+    this.isExecutingAction = false
+    this.actionExecuteTime = 0
+  }
+
+  executeAction(action) {
+    if (this.isExecutingActions) {
+      throw new Error('Called executeAction while already executing actions')
+    }
+
+    this.isExecutingChain = true
+    this.isExecutingAction = true
+    this.actionExecuteTime = 1
+  }
+
+  update(dt) {
+    this.atbBar.update(dt)
+
+    if (this.isExecutingChain && !this.isExecutingAction) {
+      throw new Error('Executing chain but not action for more than one update.. ATB Bar should have queued an action or ended the chain')
+    }
+
+    if (this.actionExecuteTime) {
+      this.actionExecuteTime -= dt
+
+      if (this.actionExecuteTime <= 0) {
+        this.actionExecuteTime = 0
+        this.isExecutingAction = false
+      }
+    }
+  }
+}
+
+const battleCharacter = new BattleCharacter()
+
+const atbBar = battleCharacter.atbBar
 atbBar.queuedActions = [{label: 'Fire', size: 1}, {label: 'Blizz', size: 1}, {label: 'Zap', size: 1}, {label: 'Firaga', size: 3}]
 
 const actionMenu = new ActionMenu()
@@ -219,7 +295,7 @@ function drawLoop() {
   const dt = (Date.now() - lastTime) / 1000
   lastTime = Date.now()
 
-  atbBar.update(dt)
+  battleCharacter.update(dt)
   atbBar.draw()
 
   actionMenu.draw()