diff options
Diffstat (limited to 'index.js')
-rw-r--r-- | index.js | 119 |
1 files changed, 72 insertions, 47 deletions
diff --git a/index.js b/index.js index e6aae70..6621c98 100644 --- a/index.js +++ b/index.js @@ -201,25 +201,12 @@ class HPBar { } } -class ActionMenu { - constructor() { +class BaseBattleMenu { + constructor({options}) { this.canvas = document.createElement('canvas') - // State - - this.options = [ - ['Fire', 'Fira', 'Firaga'], - ['Blizz', 'Blizza', 'Blizzaga'], - ['Aero', 'Aerora', 'Aeroga'], - ['Zap', 'Zappa', 'Zappaga'], - ['Bio', 'Biora'], - ['Stun', 'Stunra', 'Stunga'] - ] - + this.options = options this.currentOptionIndex = 0 - this.uiLevel = 1 // 1-3 -- which of "fire", "fira", "firaga" is selected. - - // Drawing // Button height is 9, with a margin of 1 between each plus 1 at the top and bottom. const visibleButtonCount = 3 @@ -238,40 +225,33 @@ class ActionMenu { const len = this.options.length - let y = 1 + this.drawY = 1 for (let i = startIndex; i < endIndex; i++) { const option = this.options[i === -1 ? len - 1 : i === len ? 0 : i] - const maxLevel = option.length - const effectiveLevel = Math.min(maxLevel, this.uiLevel) - const text = option[effectiveLevel - 1] - const rectW = this.getRectW(effectiveLevel) - if (effectiveLevel < maxLevel) { - const ghostRectW = this.getRectW(maxLevel) - ctx.fillStyle = 'rgba(255, 255, 255, 0.3)' - ctx.fillRect(1.5, y + 0.5, ghostRectW, 8) - ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)' - ctx.strokeRect(1.5, y + 0.5, ghostRectW, 8) - } - if (i === this.currentOptionIndex) { - const mul = Math.sin(Date.now() / 200) * 0.125 + 0.875 - ctx.fillStyle = `rgb(${mul * 255}, ${mul * 127}, 0)` - } else { - ctx.fillStyle = 'white' - } - ctx.fillRect(1, y, rectW, 9) - ctx.strokeStyle = 'black' - ctx.strokeRect(1.5, y + 0.5, rectW - 1, 8) - ctx.textAlign = 'center' - ctx.fillStyle = 'black' - ctx.font = '5px pixel-font' - ctx.fillText(text, 1 + Math.round(rectW / 2), y + 2 + 9 / 2) - - y += 10 + this.drawOption(option, ctx) } } - getRectW(level) { - return Math.floor((this.canvas.width - 2) / 3 * level) + drawOption(option, ctx) { + const rectW = this.getOptionW(option) + if (option === this.options[this.currentOptionIndex]) { + const mul = Math.sin(Date.now() / 200) * 0.125 + 0.875 + ctx.fillStyle = `rgb(${mul * 255}, ${mul * 127}, 0)` + } else { + ctx.fillStyle = 'white' + } + ctx.fillRect(1, this.drawY, rectW, 9) + ctx.strokeStyle = 'black' + ctx.strokeRect(1.5, this.drawY + 0.5, rectW - 1, 8) + ctx.textAlign = 'center' + ctx.fillStyle = 'black' + ctx.font = '5px pixel-font' + ctx.fillText(option.label, 1 + Math.round(rectW / 2), this.drawY + 2 + 9 / 2) + this.drawY += 10 + } + + getOptionW(option) { + return this.canvas.width } downOption() { @@ -289,6 +269,51 @@ class ActionMenu { this.currentOptionIndex = this.options.length - 1 } } +} + +class ActionMenu extends BaseBattleMenu { + constructor() { + super({options: [ + ['Fire', 'Fira', 'Firaga'], + ['Blizz', 'Blizza', 'Blizzaga'], + ['Aero', 'Aerora', 'Aeroga'], + ['Zap', 'Zappa', 'Zappaga'], + ['Bio', 'Biora'], + ['Stun', 'Stunra', 'Stunga'] + ].map(arr => ({levelTexts: arr}))}) + + this.uiLevel = 1 // 1-3 -- which of "fire", "fira", "firaga" is selected. + } + + drawOption(option, ctx) { + const maxLevel = this.getMaxLevel(option) + const effectiveLevel = this.getEffectiveLevel(option) + option.label = option.levelTexts[effectiveLevel - 1] + if (effectiveLevel < maxLevel) { + const ghostRectW = this.getLevelW(maxLevel) + ctx.fillStyle = 'rgba(255, 255, 255, 0.3)' + ctx.fillRect(1.5, this.drawY + 0.5, ghostRectW, 8) + ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)' + ctx.strokeRect(1.5, this.drawY + 0.5, ghostRectW, 8) + } + super.drawOption(option, ctx) + } + + getOptionW(option) { + return this.getLevelW(this.getEffectiveLevel(option)) + } + + getEffectiveLevel(option) { + return Math.min(option.levelTexts.length, this.uiLevel) + } + + getMaxLevel(option) { + return option.levelTexts.length + } + + getLevelW(level) { + return Math.floor((this.canvas.width - 2) / 3 * level) + } increaseLevel() { this.uiLevel++ @@ -306,13 +331,13 @@ class ActionMenu { queueTo(atbBar) { const option = this.options[this.currentOptionIndex] - const maxLevel = option.length + const maxLevel = this.getMaxLevel(option) const effectiveLevel = Math.min(maxLevel, this.uiLevel) const remainingSpace = atbBar.getRemainingSpace() if (effectiveLevel <= remainingSpace) { atbBar.queuedActions.push({ - label: option[effectiveLevel - 1], + label: option.levelTexts[effectiveLevel - 1], size: effectiveLevel }) } else { |