Last active
March 19, 2019 04:36
-
-
Save f-space/afc6b12500d8d7154808ebdb1e560b9d to your computer and use it in GitHub Desktop.
不思議のダンジョン風のUIをマップ画面に表示するRPGツクールMVプラグイン
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*: | |
* @plugindesc マップ画面上にステータスを表示する | |
* @author F_ | |
* | |
* @param horizontal_margin | |
* @desc 横方向の余白(px) | |
* @default 50 | |
* | |
* @param vertical_margin | |
* @desc 縦方向の余白(px) | |
* @default 20 | |
* | |
* @param floor_unit | |
* @desc 階層の単位 | |
* @default F | |
* | |
* @param separator | |
* @desc 現在値と最大値の仕切り | |
* @default / | |
* | |
* @param max_floor | |
* @desc 最大階層 | |
* @default 99 | |
* | |
* @param max_level | |
* @desc 最大レベル | |
* @default 99 | |
* | |
* @param max_hp | |
* @desc 最大HP | |
* @default 999 | |
* | |
* @param max_gold | |
* @desc 最大ゴールド | |
* @default 999999 | |
* | |
* @param gauges | |
* @desc 描画するゲージ一覧(コンマ区切りで記述 [exp, hp, mp]) | |
* @default exp, hp, mp | |
* | |
* @help | |
* XXX階と表示するにはマップのメモ欄に<floor:XXX>と記述します。 | |
* | |
* Copyright (c) 2019 F_ | |
* Released under the MIT license | |
* http://opensource.org/licenses/mit-license.php | |
*/ | |
!function () { | |
const PLUGIN_NAME = document.currentScript.src.split("/").pop().slice(0, -3); | |
const PARAMS = PluginManager.parameters(PLUGIN_NAME); | |
function positiveInteger(name) { | |
const value = Number(PARAMS[name]); | |
if (!Number.isSafeInteger(value) || value < 0) { | |
throw new Error(`parameter '${name}' must be a positive integer.`); | |
} | |
return value; | |
} | |
const params = { | |
horizontalMargin: Number(PARAMS['horizontal_margin']), | |
verticalMargin: Number(PARAMS['vertical_margin']), | |
floorUnit: String(PARAMS['floor_unit']), | |
separator: String(PARAMS['separator']), | |
maxFloor: positiveInteger('max_floor'), | |
maxLevel: positiveInteger('max_level'), | |
maxHp: positiveInteger('max_hp'), | |
maxGold: positiveInteger('max_gold'), | |
gauges: String(PARAMS['gauges']).split(",").map(x => x.trim().toLowerCase()), | |
}; | |
class InfoWindow extends Window_Base { | |
constructor(...args) { | |
super(...args); | |
} | |
initialize() { | |
super.initialize(0, 0, this.windowWidth(), this.windowHeight()); | |
this.opacity = 0; | |
this._values = {}; | |
} | |
windowWidth() { | |
return Graphics.boxWidth; | |
} | |
windowHeight() { | |
return this.fittingHeight(1) | |
+ (this.gaugeSpacing() + this.gaugeHeight()) * 2 | |
+ params.verticalMargin * 2; | |
} | |
standardFontSize() { | |
return 42; | |
} | |
standardPadding() { | |
return 0; | |
} | |
textPadding() { | |
return 8; | |
} | |
update() { | |
super.update(); | |
const map = $dataMap; | |
const floorTag = Number(map && map.meta['floor']); | |
const actor = $gameParty.leader(); | |
const floor = !Number.isNaN(floorTag) ? floorTag.clamp(0, params.maxFloor) : undefined; | |
const level = actor.level.clamp(0, params.maxLevel); | |
const hp = actor.hp.clamp(0, params.maxHp); | |
const mhp = actor.mhp.clamp(0, params.maxHp); | |
const mp = actor.mp; | |
const mmp = actor.mmp; | |
const exp = actor.isMaxLevel() ? 0 : actor.currentExp() - actor.currentLevelExp(); | |
const mexp = actor.nextLevelExp() - actor.currentLevelExp(); | |
const gold = $gameParty.gold(); | |
const values = { floor, level, hp, mhp, mp, mmp, exp, mexp, gold }; | |
const dirty = Object.entries(values).some(([k, v]) => v !== this._values[k]); | |
if (dirty) { | |
this._values = values; | |
this.refresh(); | |
} | |
} | |
refresh() { | |
this.contents.clear(); | |
const layout = this.measureInfoText(); | |
this.drawInfoText(layout); | |
} | |
gaugeSpacing() { | |
return 4; | |
} | |
gaugeHeight() { | |
return 8; | |
} | |
measureInfoText() { | |
const offsetX = params.horizontalMargin; | |
const offsetY = params.verticalMargin; | |
const floorWidth = this.measureFloorText(); | |
const levelWidth = this.measureLevelText(); | |
const hpWidth = this.measureHPText(); | |
const goldWidth = this.measureGoldText(); | |
const width = this.contents.width; | |
const totalWidth = floorWidth + levelWidth + hpWidth + goldWidth; | |
const totalSpace = width - totalWidth - params.horizontalMargin * 2; | |
const spacing = Math.round(totalSpace / 3); | |
return { offsetX, offsetY, floorWidth, levelWidth, hpWidth, goldWidth, spacing }; | |
} | |
measureFloorText() { | |
const digits = this.getDigits(params.maxFloor); | |
let width = 0; | |
width += this.measureNumberText(digits); | |
width += this.textPadding(); | |
width += this.textWidth(params.floorUnit); | |
return width; | |
} | |
measureLevelText() { | |
const digits = this.getDigits(params.maxLevel) | |
let width = 0; | |
width += this.textWidth(TextManager.levelA); | |
width += this.textPadding(); | |
width += this.measureNumberText(digits); | |
return width; | |
} | |
measureHPText() { | |
const digits = this.getDigits(params.maxHp); | |
let width = 0; | |
width += this.textWidth(TextManager.hpA); | |
width += this.textPadding(); | |
width += this.measureNumberText(digits) * 2; | |
width += this.textWidth(params.separator); | |
return width; | |
} | |
measureGoldText() { | |
const digits = this.getDigits(params.maxGold); | |
let width = 0; | |
width += this.measureNumberText(digits); | |
width += this.textPadding(); | |
width += this.textWidth(TextManager.currencyUnit); | |
return width; | |
} | |
measureNumberText(length) { | |
return this.textWidth('0') * length; | |
} | |
drawInfoText(layout) { | |
const { offsetX, offsetY } = layout; | |
const lineHeight = this.lineHeight() + this.gaugeSpacing(); | |
const gaugeHeight = this.gaugeHeight() + this.gaugeSpacing(); | |
const floorX = offsetX; | |
const floorY = offsetY; | |
this.drawFloorText(floorX, floorY, layout.floorWidth); | |
const levelX = floorX + layout.floorWidth + layout.spacing; | |
const levelY = offsetY; | |
this.drawLevelText(levelX, levelY, layout.levelWidth); | |
if (params.gauges.includes('exp')) { | |
const expGaugeX = levelX; | |
const expGaugeY = levelY + lineHeight; | |
this.drawExpGauge(expGaugeX, expGaugeY, layout.levelWidth); | |
} | |
const hpX = levelX + layout.levelWidth + layout.spacing; | |
const hpY = offsetY; | |
this.drawHPText(hpX, hpY, layout.hpWidth); | |
let gaugeY = hpY + lineHeight; | |
if (params.gauges.includes('hp')) { | |
const hpGaugeX = hpX; | |
const hpGaugeY = gaugeY; | |
this.drawHPGauge(hpGaugeX, hpGaugeY, layout.hpWidth); | |
gaugeY += gaugeHeight; | |
} | |
if (params.gauges.includes('mp')) { | |
const mpGaugeX = hpX; | |
const mpGaugeY = gaugeY; | |
this.drawMPGauge(mpGaugeX, mpGaugeY, layout.hpWidth); | |
gaugeY += gaugeHeight; | |
} | |
const goldX = hpX + layout.hpWidth + layout.spacing; | |
const goldY = offsetY; | |
this.drawGoldText(goldX, goldY, layout.goldWidth); | |
} | |
drawFloorText(x, y, width) { | |
const { floor } = this._values; | |
const digits = this.getDigits(params.maxFloor); | |
if (floor !== undefined) { | |
const text0 = String(floor).padStart(digits); | |
const text1 = params.floorUnit; | |
const width0 = this.textWidth(text0); | |
const width1 = this.textWidth(text1); | |
const padding = this.textPadding(); | |
this.drawText(text0, x, y, width0, 'left'); | |
this.drawText(text1, x + width0 + padding, y, width1, 'left'); | |
} | |
} | |
drawLevelText(x, y, width) { | |
const { level } = this._values; | |
const digits = this.getDigits(params.maxLevel); | |
const text0 = TextManager.levelA; | |
const text1 = String(level).padStart(digits); | |
const width0 = this.textWidth(text0); | |
const width1 = this.textWidth(text1); | |
const padding = this.textPadding(); | |
this.drawText(text0, x, y, width0, 'left'); | |
this.drawText(text1, x + width0 + padding, y, width1, 'left'); | |
} | |
drawExpGauge(x, y, width) { | |
const { exp, mexp } = this._values; | |
const rate = mexp !== 0 ? (exp / mexp).clamp(0, 1) : 1; | |
const color1 = this.tpGaugeColor1(); | |
const color2 = this.tpGaugeColor2(); | |
this.drawGauge(x, y, width, rate, color1, color2); | |
} | |
drawHPText(x, y, width) { | |
const { hp, mhp } = this._values; | |
const digits = this.getDigits(params.maxHp); | |
const text0 = TextManager.hpA; | |
const text1 = String(hp).padStart(digits) + params.separator + String(mhp).padStart(digits); | |
const width0 = this.textWidth(text0); | |
const width1 = this.textWidth(text1); | |
const padding = this.textPadding(); | |
this.drawText(text0, x, y, width0, 'left'); | |
this.drawText(text1, x + width0 + padding, y, width1, 'left'); | |
} | |
drawHPGauge(x, y, width) { | |
const { hp, mhp } = this._values; | |
const rate = mhp !== 0 ? (hp / mhp).clamp(0, 1) : 0; | |
const color1 = this.hpGaugeColor1(); | |
const color2 = this.hpGaugeColor2(); | |
this.drawGauge(x, y, width, rate, color1, color2); | |
}; | |
drawMPGauge(x, y, width) { | |
const { mp, mmp } = this._values; | |
const rate = mmp !== 0 ? (mp / mmp).clamp(0, 1) : 0; | |
const color1 = this.mpGaugeColor1(); | |
const color2 = this.mpGaugeColor2(); | |
this.drawGauge(x, y, width, rate, color1, color2); | |
} | |
drawGoldText(x, y, width) { | |
const { gold } = this._values; | |
const digits = this.getDigits(params.maxGold); | |
const text0 = String(gold).padStart(digits); | |
const text1 = TextManager.currencyUnit; | |
const width0 = this.textWidth(text0); | |
const width1 = this.textWidth(text1); | |
const padding = this.textPadding(); | |
this.drawText(text0, x, y, width0, 'left'); | |
this.drawText(text1, x + width0 + padding, y, width1, 'left'); | |
} | |
drawGauge(x, y, width, rate, color1, color2) { | |
const filledAreaWidth = Math.floor(width * rate); | |
const height = this.gaugeHeight(); | |
const background = this.gaugeBackColor(); | |
this.contents.fillRect(x, y, width, height, background); | |
this.contents.gradientFillRect(x, y, filledAreaWidth, height, color1, color2); | |
} | |
getDigits(x) { | |
return x !== 0 ? Math.floor(Math.log10(x)) + 1 : 1; | |
} | |
} | |
const Scene_Map_createAllWindows = Scene_Map.prototype.createAllWindows; | |
Scene_Map.prototype.createAllWindows = function () { | |
Scene_Map_createAllWindows.apply(this, arguments); | |
this.createInfoWindow(); | |
} | |
Scene_Map.prototype.createInfoWindow = function () { | |
this._infoWindow = new InfoWindow(); | |
this.addWindow(this._infoWindow); | |
} | |
}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment