Rework battle command selection menus
This commit is contained in:
@@ -1441,6 +1441,7 @@ type TargetingGuideCandidate = {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tone: number;
|
||||
metrics?: TargetingGuideMetric[];
|
||||
};
|
||||
|
||||
type TargetingGuideNotice = {
|
||||
@@ -4470,7 +4471,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
return {
|
||||
available: true,
|
||||
status: `대상 ${targets.length}`,
|
||||
detail: `${target.name} · 피해 ${preview.damage} · ${preview.hitRate}%`
|
||||
detail: `${target.name} · 피해 ${preview.damage} · ${preview.hitRate}% · ${preview.counterAvailable ? '반격 주의' : '반격 없음'}`
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4508,10 +4509,10 @@ export class BattleScene extends Phaser.Scene {
|
||||
this.hideCommandMenu();
|
||||
|
||||
const commands: BattleCommand[] = ['attack', 'strategy', 'item', 'wait'];
|
||||
const menuWidth = 300;
|
||||
const titleHeight = 46;
|
||||
const buttonHeight = 58;
|
||||
const gap = 7;
|
||||
const menuWidth = 330;
|
||||
const titleHeight = 54;
|
||||
const buttonHeight = 70;
|
||||
const gap = 8;
|
||||
const padding = 10;
|
||||
const menuHeight = padding * 2 + titleHeight + commands.length * buttonHeight + (commands.length - 1) * gap;
|
||||
const { left, top } = this.commandMenuPosition(pointerX, pointerY, menuWidth, menuHeight);
|
||||
@@ -4522,16 +4523,16 @@ export class BattleScene extends Phaser.Scene {
|
||||
panel.setDepth(14);
|
||||
this.commandMenuObjects.push(panel);
|
||||
|
||||
const title = this.add.text(left + 16, top + padding + 2, `${unit.name} 명령`, {
|
||||
const title = this.add.text(left + 16, top + padding + 3, `${unit.name} 명령`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '18px',
|
||||
fontSize: '20px',
|
||||
color: '#d8b15f',
|
||||
fontStyle: '700'
|
||||
});
|
||||
title.setDepth(15);
|
||||
this.commandMenuObjects.push(title);
|
||||
|
||||
const subtitle = this.add.text(left + 16, top + padding + 26, `HP ${unit.hp}/${unit.maxHp} · ${getUnitClass(unit.classKey).name}`, {
|
||||
const subtitle = this.add.text(left + 16, top + padding + 31, `HP ${unit.hp}/${unit.maxHp} · ${getUnitClass(unit.classKey).name}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
color: '#aeb7c2',
|
||||
@@ -4553,46 +4554,46 @@ export class BattleScene extends Phaser.Scene {
|
||||
background.setInteractive({ useHandCursor: true });
|
||||
background.setDepth(15);
|
||||
|
||||
const iconFrame = this.add.rectangle(left + 40, centerY, 42, 42, 0x0a0f14, 0.9);
|
||||
const iconFrame = this.add.rectangle(left + 46, centerY, 56, 56, 0x0a0f14, 0.93);
|
||||
iconFrame.setStrokeStyle(1, accent, info.available ? 0.72 : 0.44);
|
||||
iconFrame.setDepth(16);
|
||||
this.commandMenuObjects.push(iconFrame);
|
||||
|
||||
const icon = this.createBattleUiIcon(left + 40, centerY, this.commandIcon(command, unit), 38);
|
||||
const icon = this.createBattleUiIcon(left + 46, centerY, this.commandIcon(command, unit), 50);
|
||||
icon.setDepth(17);
|
||||
this.commandMenuObjects.push(icon);
|
||||
|
||||
const text = this.add.text(left + 68, buttonTop + 8, commandLabels[command], {
|
||||
const text = this.add.text(left + 84, buttonTop + 10, commandLabels[command], {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '19px',
|
||||
fontSize: '20px',
|
||||
color: info.available ? '#f2e3bf' : '#c8ced6',
|
||||
fontStyle: '700',
|
||||
fixedWidth: 86
|
||||
fixedWidth: 92
|
||||
});
|
||||
text.setDepth(16);
|
||||
|
||||
const detail = this.add.text(left + 68, buttonTop + 34, info.detail, {
|
||||
const detail = this.add.text(left + 84, buttonTop + 40, info.detail, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '11px',
|
||||
fontSize: '12px',
|
||||
color: info.available ? '#aeb7c2' : '#ffcf9a',
|
||||
fixedWidth: menuWidth - 164
|
||||
fixedWidth: menuWidth - 194
|
||||
});
|
||||
detail.setDepth(16);
|
||||
this.commandMenuObjects.push(detail);
|
||||
|
||||
const badgeLeft = left + menuWidth - 92;
|
||||
const badge = this.add.rectangle(badgeLeft, buttonTop + 15, 74, 28, 0x0b1118, 0.94);
|
||||
const badgeLeft = left + menuWidth - 106;
|
||||
const badge = this.add.rectangle(badgeLeft, buttonTop + 19, 88, 32, 0x0b1118, 0.95);
|
||||
badge.setOrigin(0);
|
||||
badge.setDepth(16);
|
||||
badge.setStrokeStyle(1, info.available ? accent : 0xb64a45, info.available ? 0.62 : 0.74);
|
||||
this.commandMenuObjects.push(badge);
|
||||
|
||||
const badgeText = this.add.text(badgeLeft + 37, buttonTop + 21, info.status, {
|
||||
const badgeText = this.add.text(badgeLeft + 44, buttonTop + 27, info.status, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '10px',
|
||||
fontSize: '11px',
|
||||
color: info.available ? '#d4dce6' : '#ffcf9a',
|
||||
fontStyle: '700',
|
||||
fixedWidth: 70,
|
||||
fixedWidth: 84,
|
||||
align: 'center'
|
||||
});
|
||||
badgeText.setOrigin(0.5, 0);
|
||||
@@ -4826,12 +4827,12 @@ export class BattleScene extends Phaser.Scene {
|
||||
targetCount,
|
||||
valueLabel: '피해',
|
||||
value: `${preview.damage}`,
|
||||
detail: `${target.name} · 피해 ${preview.damage} · ${successLabel} ${preview.hitRate}%`,
|
||||
detail: `${target.name} · 피해 ${preview.damage} · ${successLabel} ${preview.hitRate}% · ${preview.counterAvailable ? '반격 주의' : '반격 없음'}`,
|
||||
secondary: `치명 ${preview.criticalRate}% · 지형 ${preview.terrainLabel} · 사거리 ${usable.range}칸`,
|
||||
chips: [
|
||||
{ icon: this.usablePowerIcon(usable), label: '효과', value: this.usableEffectLabel(usable), tone: accent },
|
||||
{ icon: this.usablePowerIcon(usable), label: '피해', value: `${preview.damage}`, tone: 0xb64a45 },
|
||||
{ icon: usable.command === 'strategy' ? 'success' : 'hit', label: successLabel, value: `${preview.hitRate}%`, tone: this.rateTone(preview.hitRate) },
|
||||
{ icon: this.usableTargetIcon(usable), label: '대상', value: `${targetCount}명`, tone: 0xb64a45 }
|
||||
{ icon: 'counter', label: '반격', value: preview.counterAvailable ? '주의' : '없음', tone: preview.counterAvailable ? 0xd8732c : 0x59d18c }
|
||||
]
|
||||
};
|
||||
}
|
||||
@@ -4846,7 +4847,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
chips: [
|
||||
{ icon: this.usablePowerIcon(usable), label: '효과', value: this.usableEffectLabel(usable), tone: accent },
|
||||
{ icon: 'success', label: '성공률', value: '-', tone: 0x647485 },
|
||||
{ icon: this.usableTargetIcon(usable), label: '대상', value: '없음', tone: 0xb64a45 }
|
||||
{ icon: 'counter', label: '반격', value: '-', tone: 0x647485 }
|
||||
]
|
||||
};
|
||||
}
|
||||
@@ -4906,33 +4907,33 @@ export class BattleScene extends Phaser.Scene {
|
||||
tone: number,
|
||||
available: boolean
|
||||
) {
|
||||
const chip = this.add.rectangle(x, y, width, 40, 0x0b1118, available ? 0.95 : 0.87);
|
||||
const chip = this.add.rectangle(x, y, width, 44, 0x0b1118, available ? 0.96 : 0.88);
|
||||
chip.setOrigin(0);
|
||||
chip.setDepth(16);
|
||||
chip.setStrokeStyle(1, tone, available ? 0.64 : 0.38);
|
||||
this.commandMenuObjects.push(chip);
|
||||
|
||||
const iconImage = this.createBattleUiIcon(x + 20, y + 20, icon, 31);
|
||||
const iconImage = this.createBattleUiIcon(x + 22, y + 22, icon, 34);
|
||||
iconImage.setAlpha(available ? 0.98 : 0.72);
|
||||
iconImage.setDepth(17);
|
||||
this.commandMenuObjects.push(iconImage);
|
||||
|
||||
const labelText = this.add.text(x + 41, y + 5, label, {
|
||||
const labelText = this.add.text(x + 44, y + 6, label, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '10px',
|
||||
color: '#9fb0bf',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 48
|
||||
fixedWidth: width - 52
|
||||
});
|
||||
labelText.setDepth(17);
|
||||
this.commandMenuObjects.push(labelText);
|
||||
|
||||
const valueText = this.add.text(x + 41, y + 21, this.truncateUiText(value, 10), {
|
||||
const valueText = this.add.text(x + 44, y + 23, this.truncateUiText(value, 10), {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '13px',
|
||||
color: available ? '#f2e3bf' : '#c8ced6',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 48
|
||||
fixedWidth: width - 52
|
||||
});
|
||||
valueText.setDepth(17);
|
||||
this.commandMenuObjects.push(valueText);
|
||||
@@ -4953,17 +4954,17 @@ export class BattleScene extends Phaser.Scene {
|
||||
valueBox.setStrokeStyle(1, forecast.available ? tone : 0x6c7480, forecast.available ? 0.82 : 0.46);
|
||||
this.commandMenuObjects.push(valueBox);
|
||||
|
||||
const valueIcon = this.createBattleUiIcon(x + 30, y + height / 2, this.usablePowerIcon(usable), 46);
|
||||
const valueIcon = this.createBattleUiIcon(x + 32, y + height / 2, this.usablePowerIcon(usable), 52);
|
||||
valueIcon.setAlpha(forecast.available ? 1 : 0.72);
|
||||
valueIcon.setDepth(17);
|
||||
this.commandMenuObjects.push(valueIcon);
|
||||
|
||||
const valueLabel = this.add.text(x + 62, y + 12, forecast.valueLabel, {
|
||||
const valueLabel = this.add.text(x + 66, y + 13, forecast.valueLabel, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
color: '#9fb0bf',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 70
|
||||
fixedWidth: width - 74
|
||||
});
|
||||
valueLabel.setDepth(17);
|
||||
this.commandMenuObjects.push(valueLabel);
|
||||
@@ -5001,9 +5002,9 @@ export class BattleScene extends Phaser.Scene {
|
||||
|
||||
const forecasts = usables.map((usable) => ({ usable, forecast: this.usableMenuForecast(unit, usable) }));
|
||||
const readyCount = forecasts.filter(({ forecast }) => forecast.available).length;
|
||||
const menuWidth = 520;
|
||||
const menuWidth = 540;
|
||||
const titleHeight = 58;
|
||||
const rowHeight = 148;
|
||||
const rowHeight = 154;
|
||||
const padding = 10;
|
||||
const menuHeight = padding * 2 + titleHeight + usables.length * rowHeight;
|
||||
const { left, top } = this.commandMenuPosition(pointerX, pointerY, menuWidth, menuHeight);
|
||||
@@ -5057,7 +5058,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
const rowWidth = menuWidth - padding * 2;
|
||||
const rowRight = rowLeft + rowWidth;
|
||||
const contentLeft = rowLeft + 102;
|
||||
const sideBoxWidth = 124;
|
||||
const sideBoxWidth = 132;
|
||||
const sideBoxLeft = rowRight - sideBoxWidth - 10;
|
||||
const contentWidth = sideBoxLeft - contentLeft - 12;
|
||||
const baseFill = forecast.available ? 0x1a2630 : 0x151c23;
|
||||
@@ -5068,12 +5069,12 @@ export class BattleScene extends Phaser.Scene {
|
||||
bg.setInteractive({ useHandCursor: true });
|
||||
this.commandMenuObjects.push(bg);
|
||||
|
||||
const iconFrame = this.add.rectangle(rowLeft + 48, rowTop + 70, 86, 86, 0x0a0f14, forecast.available ? 0.94 : 0.87);
|
||||
const iconFrame = this.add.rectangle(rowLeft + 48, rowTop + 72, 84, 84, 0x0a0f14, forecast.available ? 0.94 : 0.87);
|
||||
iconFrame.setStrokeStyle(1, accent, forecast.available ? 0.72 : 0.42);
|
||||
iconFrame.setDepth(16);
|
||||
this.commandMenuObjects.push(iconFrame);
|
||||
|
||||
const icon = this.createBattleUiIcon(rowLeft + 48, rowTop + 70, this.usableIcon(usable), 78);
|
||||
const icon = this.createBattleUiIcon(rowLeft + 48, rowTop + 72, this.usableIcon(usable), 70);
|
||||
icon.setAlpha(forecast.available ? 1 : 0.72);
|
||||
icon.setDepth(17);
|
||||
this.commandMenuObjects.push(icon);
|
||||
@@ -5137,14 +5138,14 @@ export class BattleScene extends Phaser.Scene {
|
||||
secondary.setDepth(16);
|
||||
this.commandMenuObjects.push(secondary);
|
||||
|
||||
this.renderUsableMenuValueCard(sideBoxLeft, rowTop + 52, sideBoxWidth, 76, usable, forecast, accent);
|
||||
this.renderUsableMenuValueCard(sideBoxLeft, rowTop + 54, sideBoxWidth, 82, usable, forecast, accent);
|
||||
|
||||
const chipGap = 6;
|
||||
const chipWidth = (contentWidth - chipGap * 2) / 3;
|
||||
forecast.chips.slice(0, 3).forEach((chip, chipIndex) => {
|
||||
this.renderUsableMenuInfoChip(
|
||||
contentLeft + chipIndex * (chipWidth + chipGap),
|
||||
rowTop + 98,
|
||||
rowTop + 102,
|
||||
chipWidth,
|
||||
chip.icon,
|
||||
chip.label,
|
||||
@@ -5500,14 +5501,20 @@ export class BattleScene extends Phaser.Scene {
|
||||
const candidates = targets.slice(0, 3).map((target): TargetingGuideCandidate => {
|
||||
const preview = this.combatPreview(unit, target, action, usable);
|
||||
const distance = this.tileDistance(unit, target);
|
||||
const successLabel = this.previewSuccessLabel(preview);
|
||||
const counterLabel = preview.counterAvailable ? '반격 주의' : '반격 없음';
|
||||
return {
|
||||
icon: this.previewDamageIcon(preview),
|
||||
name: target.name,
|
||||
meta: `${getUnitClass(target.classKey).name} · 거리 ${distance}/${range}`,
|
||||
primary: `${preview.damage} 피해`,
|
||||
secondary: `${preview.hitRate}% ${this.previewSuccessLabel(preview)} · ${counterLabel}`,
|
||||
tone: this.previewAccentColor(preview)
|
||||
secondary: `${preview.hitRate}% ${successLabel} · ${counterLabel}`,
|
||||
tone: this.previewAccentColor(preview),
|
||||
metrics: [
|
||||
{ icon: this.previewDamageIcon(preview), label: '피해', value: `${preview.damage}`, tone: 0xb64a45 },
|
||||
{ icon: action === 'strategy' ? 'success' : 'hit', label: successLabel, value: `${preview.hitRate}%`, tone: this.rateTone(preview.hitRate) },
|
||||
{ icon: 'counter', label: '반격', value: preview.counterAvailable ? '주의' : '없음', tone: preview.counterAvailable ? 0xd8732c : 0x59d18c }
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
@@ -5546,7 +5553,18 @@ export class BattleScene extends Phaser.Scene {
|
||||
meta: `${getUnitClass(target.classKey).name} · 거리 ${distance}/${usable.range}`,
|
||||
primary: isHeal ? `+${preview.healAmount} 회복` : `공+${preview.attackBonus}`,
|
||||
secondary: isHeal ? `HP ${target.hp} → ${preview.projectedHp}` : `명+${preview.hitBonus} · 치+${preview.criticalBonus} · ${preview.duration}턴`,
|
||||
tone: isHeal ? 0x59d18c : accent
|
||||
tone: isHeal ? 0x59d18c : accent,
|
||||
metrics: isHeal
|
||||
? [
|
||||
{ icon: this.usablePowerIcon(usable), label: '회복', value: `+${preview.healAmount}`, tone: 0x59d18c },
|
||||
{ icon: 'hp', label: 'HP', value: `${preview.projectedHp}`, tone: 0x59d18c },
|
||||
{ icon: 'success', label: '적용', value: '100%', tone: 0x59d18c }
|
||||
]
|
||||
: [
|
||||
{ icon: 'focus', label: '공격', value: `+${preview.attackBonus}`, tone: palette.gold },
|
||||
{ icon: 'hit', label: '명중', value: `+${preview.hitBonus}`, tone: palette.blue },
|
||||
{ icon: 'critical', label: '치명', value: `+${preview.criticalBonus}`, tone: 0xd8732c }
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
@@ -5590,37 +5608,37 @@ export class BattleScene extends Phaser.Scene {
|
||||
const left = panelX + 24;
|
||||
const width = panelWidth - 48;
|
||||
const top = this.sideContentTop();
|
||||
const height = 416;
|
||||
const height = 492;
|
||||
const bg = this.trackSideObject(this.add.rectangle(left, top, width, height, 0x101820, 0.98));
|
||||
bg.setOrigin(0);
|
||||
bg.setStrokeStyle(2, options.accent, 0.78);
|
||||
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(left + 40, top + 42, 72, 72, 0x0a0f14, 0.94));
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(left + 46, top + 46, 84, 84, 0x0a0f14, 0.94));
|
||||
iconFrame.setStrokeStyle(1, options.accent, 0.76);
|
||||
this.trackSideIcon(left + 40, top + 42, options.icon, 64);
|
||||
this.trackSideIcon(left + 46, top + 46, options.icon, 70);
|
||||
|
||||
this.trackSideObject(this.add.text(left + 86, top + 11, options.title, {
|
||||
this.trackSideObject(this.add.text(left + 98, top + 12, options.title, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '20px',
|
||||
color: '#f4dfad',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 96
|
||||
fixedWidth: width - 108
|
||||
}));
|
||||
this.trackSideObject(this.add.text(left + 86, top + 39, options.subtitle, {
|
||||
this.trackSideObject(this.add.text(left + 98, top + 40, options.subtitle, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
color: '#9fb0bf',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 96
|
||||
fixedWidth: width - 108
|
||||
}));
|
||||
this.trackSideObject(this.add.text(left + 86, top + 57, `사용자 ${options.unit.name}`, {
|
||||
this.trackSideObject(this.add.text(left + 98, top + 61, `사용자 ${options.unit.name}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
color: '#c8d2dd',
|
||||
fixedWidth: width - 96
|
||||
fixedWidth: width - 108
|
||||
}));
|
||||
|
||||
const metricTop = top + 92;
|
||||
const metricTop = top + 104;
|
||||
const metricGap = 6;
|
||||
const metricWidth = (width - metricGap * 2) / 3;
|
||||
options.metrics.slice(0, 3).forEach((metric, index) => {
|
||||
@@ -5726,28 +5744,28 @@ export class BattleScene extends Phaser.Scene {
|
||||
this.renderTargetingGuideMetric(left + index * (metricWidth + metricGap), metricTop, metricWidth, metric);
|
||||
});
|
||||
|
||||
this.trackSideIcon(left + 17, top + 165, 'success', 26);
|
||||
this.trackSideObject(this.add.text(left + 36, top + 154, '대상 후보', {
|
||||
this.trackSideIcon(left + 17, top + 182, 'success', 28);
|
||||
this.trackSideObject(this.add.text(left + 38, top + 170, '대상 후보', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '17px',
|
||||
color: '#f2e3bf',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
|
||||
const rowTop = top + 188;
|
||||
const rowTop = top + 200;
|
||||
options.candidates.forEach((candidate, index) => {
|
||||
this.renderTargetingCandidateRow(left, rowTop + index * 58, width, candidate);
|
||||
this.renderTargetingCandidateRow(left, rowTop + index * 84, width, candidate);
|
||||
});
|
||||
|
||||
const footerTop = top + 368;
|
||||
const footer = this.trackSideObject(this.add.rectangle(left, footerTop, width, 34, 0x0b1118, 0.95));
|
||||
const footerTop = top + 454;
|
||||
const footer = this.trackSideObject(this.add.rectangle(left, footerTop, width, 28, 0x0b1118, 0.95));
|
||||
footer.setOrigin(0);
|
||||
const footerTone = options.notice?.tone ?? options.accent;
|
||||
footer.setStrokeStyle(1, footerTone, options.notice ? 0.72 : 0.52);
|
||||
this.trackSideIcon(left + 18, footerTop + 17, options.notice?.icon ?? 'success', 26);
|
||||
this.trackSideIcon(left + 18, footerTop + 14, options.notice?.icon ?? 'success', 24);
|
||||
const overflowText = options.overflowCount > 0 ? ` · 외 ${options.overflowCount}명` : '';
|
||||
const footerText = options.notice?.text ?? `${options.footer}${overflowText}`;
|
||||
this.trackSideObject(this.add.text(left + 38, footerTop + 8, footerText, {
|
||||
this.trackSideObject(this.add.text(left + 38, footerTop + 6, footerText, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
color: options.notice ? '#ffcf9a' : '#d4dce6',
|
||||
@@ -5757,62 +5775,71 @@ export class BattleScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
private renderTargetingGuideMetric(x: number, y: number, width: number, metric: TargetingGuideMetric) {
|
||||
const bg = this.trackSideObject(this.add.rectangle(x, y, width, 54, 0x16212d, 0.96));
|
||||
const bg = this.trackSideObject(this.add.rectangle(x, y, width, 62, 0x16212d, 0.97));
|
||||
bg.setOrigin(0);
|
||||
bg.setStrokeStyle(1, metric.tone, 0.62);
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(x + 20, y + 27, 38, 38, 0x0a0f14, 0.88));
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(x + 23, y + 31, 44, 44, 0x0a0f14, 0.9));
|
||||
iconFrame.setStrokeStyle(1, metric.tone, 0.54);
|
||||
this.trackSideIcon(x + 20, y + 27, metric.icon, 35);
|
||||
this.trackSideObject(this.add.text(x + 42, y + 7, metric.label, {
|
||||
this.trackSideIcon(x + 23, y + 31, metric.icon, 40);
|
||||
this.trackSideObject(this.add.text(x + 49, y + 9, metric.label, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '10px',
|
||||
color: '#9fb0bf',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 50
|
||||
fixedWidth: width - 56
|
||||
}));
|
||||
this.trackSideObject(this.add.text(x + 42, y + 26, this.truncateUiText(metric.value, 8), {
|
||||
this.trackSideObject(this.add.text(x + 49, y + 31, this.truncateUiText(metric.value, 8), {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: metric.value.length > 4 ? '13px' : '16px',
|
||||
color: '#f2e3bf',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 50
|
||||
fixedWidth: width - 56
|
||||
}));
|
||||
}
|
||||
|
||||
private renderTargetingCandidateRow(x: number, y: number, width: number, candidate: TargetingGuideCandidate) {
|
||||
const row = this.trackSideObject(this.add.rectangle(x, y, width, 52, 0x121a22, 0.97));
|
||||
const rowHeight = 78;
|
||||
const row = this.trackSideObject(this.add.rectangle(x, y, width, rowHeight, 0x121a22, 0.98));
|
||||
row.setOrigin(0);
|
||||
row.setStrokeStyle(1, candidate.tone, 0.58);
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(x + 23, y + 26, 40, 40, 0x0a0f14, 0.9));
|
||||
iconFrame.setStrokeStyle(1, candidate.tone, 0.52);
|
||||
this.trackSideIcon(x + 23, y + 26, candidate.icon, 36);
|
||||
this.trackSideObject(this.add.text(x + 50, y + 6, candidate.name, {
|
||||
row.setStrokeStyle(1, candidate.tone, 0.64);
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(x + 30, y + 39, 56, 56, 0x0a0f14, 0.92));
|
||||
iconFrame.setStrokeStyle(1, candidate.tone, 0.58);
|
||||
this.trackSideIcon(x + 30, y + 39, candidate.icon, 50);
|
||||
this.trackSideObject(this.add.text(x + 64, y + 7, candidate.name, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '15px',
|
||||
color: '#f2e3bf',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 158
|
||||
fixedWidth: width - 74
|
||||
}));
|
||||
this.trackSideObject(this.add.text(x + 50, y + 27, candidate.meta, {
|
||||
this.trackSideObject(this.add.text(x + 64, y + 29, candidate.meta, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '10px',
|
||||
color: '#9fb0bf',
|
||||
fixedWidth: width - 158
|
||||
fixedWidth: width - 74
|
||||
}));
|
||||
const primary = this.trackSideObject(this.add.text(x + width - 10, y + 7, candidate.primary, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '15px',
|
||||
color: '#f4dfad',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
primary.setOrigin(1, 0);
|
||||
const secondary = this.trackSideObject(this.add.text(x + width - 10, y + 29, candidate.secondary, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '10px',
|
||||
color: '#c8d2dd',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
secondary.setOrigin(1, 0);
|
||||
const metrics = candidate.metrics ?? [
|
||||
{ icon: candidate.icon, label: '결과', value: candidate.primary, tone: candidate.tone },
|
||||
{ icon: 'success', label: '판정', value: candidate.secondary, tone: 0x647485 }
|
||||
];
|
||||
const chipGap = 5;
|
||||
const chipLeft = x + 64;
|
||||
const chipTop = y + 49;
|
||||
const chipWidth = (width - 74 - chipGap * 2) / 3;
|
||||
metrics.slice(0, 3).forEach((metric, index) => {
|
||||
const chipX = chipLeft + index * (chipWidth + chipGap);
|
||||
const chip = this.trackSideObject(this.add.rectangle(chipX, chipTop, chipWidth, 22, 0x0b1118, 0.94));
|
||||
chip.setOrigin(0);
|
||||
chip.setStrokeStyle(1, metric.tone, 0.54);
|
||||
this.trackSideIcon(chipX + 12, chipTop + 11, metric.icon, 19);
|
||||
this.trackSideObject(this.add.text(chipX + 25, chipTop + 5, this.truncateUiText(metric.value, 7), {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '11px',
|
||||
color: '#f2e3bf',
|
||||
fontStyle: '700',
|
||||
fixedWidth: chipWidth - 30
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private showTargetingRangeTiles(unit: UnitData, range: number, fillColor: number, strokeColor: number) {
|
||||
|
||||
Reference in New Issue
Block a user