Improve unit detail panel readability
This commit is contained in:
@@ -12416,99 +12416,119 @@ export class BattleScene extends Phaser.Scene {
|
||||
const terrainRating = unitClass.terrainRatings[terrain];
|
||||
const direction = this.currentUnitDirection(unit);
|
||||
|
||||
const header = this.trackSideObject(this.add.rectangle(left, top, width, 60, 0x101820, 0.94));
|
||||
const header = this.trackSideObject(this.add.rectangle(left, top, width, 64, 0x101820, 0.96));
|
||||
header.setOrigin(0);
|
||||
header.setStrokeStyle(1, factionColor, 0.76);
|
||||
|
||||
const classIcon = this.trackSideIcon(left + 26, top + 31, this.unitMoveIcon(unit), 38);
|
||||
const classIcon = this.trackSideIcon(left + 28, top + 32, this.unitMoveIcon(unit), 42);
|
||||
classIcon.setAlpha(acted ? 0.86 : 0.96);
|
||||
const headerTextX = left + 58;
|
||||
this.trackSideObject(this.add.text(headerTextX, top + 9, `${rosterLabels[unit.faction]} / ${unitClass.family}`, {
|
||||
this.trackSideObject(this.add.text(headerTextX, top + 7, `${rosterLabels[unit.faction]} / ${unitClass.family}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '14px',
|
||||
fontSize: '13px',
|
||||
color: unit.faction === 'ally' ? '#9fd0ff' : '#ffb2a4',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
this.trackSideObject(this.add.text(headerTextX, top + 29, `${unit.name} ${unitClass.name}`, {
|
||||
this.trackSideObject(this.add.text(headerTextX, top + 27, `${unit.name} ${unitClass.name}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '22px',
|
||||
fontSize: '21px',
|
||||
color: acted ? '#bdbdbd' : '#f2e3bf',
|
||||
fontStyle: '700'
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 154
|
||||
}));
|
||||
const growthText = this.trackSideObject(this.add.text(left + width - 14, top + 42, `Lv ${unit.level} EXP ${unit.exp}/100`, {
|
||||
|
||||
const levelBadge = this.trackSideObject(this.add.rectangle(left + width - 84, top + 8, 70, 26, 0x1b2834, 0.94));
|
||||
levelBadge.setOrigin(0);
|
||||
levelBadge.setStrokeStyle(1, factionColor, 0.6);
|
||||
const levelText = this.trackSideObject(this.add.text(left + width - 49, top + 21, `Lv ${unit.level}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '13px',
|
||||
fontSize: '16px',
|
||||
color: acted ? '#d8cfb5' : '#f4dfad',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
growthText.setOrigin(1, 0);
|
||||
levelText.setOrigin(0.5);
|
||||
|
||||
if (this.phase !== 'command') {
|
||||
const backBg = this.trackSideObject(this.add.rectangle(left + width - 66, top + 10, 52, 28, 0x1b2834, 0.9));
|
||||
const backBg = this.trackSideObject(this.add.rectangle(left + width - 72, top + 38, 58, 22, 0x223142, 0.95));
|
||||
backBg.setOrigin(0);
|
||||
backBg.setStrokeStyle(1, palette.gold, 0.72);
|
||||
backBg.setInteractive({ useHandCursor: true });
|
||||
backBg.on('pointerdown', () => this.returnToRosterPanel(unit.faction));
|
||||
|
||||
const backText = this.trackSideObject(this.add.text(left + width - 40, top + 24, '목록', {
|
||||
const backText = this.trackSideObject(this.add.text(left + width - 43, top + 49, '목록', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '14px',
|
||||
fontSize: '13px',
|
||||
color: '#f4dfad',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
backText.setOrigin(0.5);
|
||||
} else {
|
||||
const actionText = this.trackSideObject(this.add.text(left + width - 49, top + 48, acted ? '행동완료' : `EXP ${unit.exp}/100`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
color: acted ? '#bdbdbd' : '#c8d2dd',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
actionText.setOrigin(0.5);
|
||||
}
|
||||
|
||||
this.trackSideIcon(left + 13, top + 88, 'hp', 26);
|
||||
this.trackSideObject(this.add.text(left + 26, top + 78, '병력', {
|
||||
const hpPanel = this.trackSideObject(this.add.rectangle(left, top + 72, width, 34, 0x101820, 0.92));
|
||||
hpPanel.setOrigin(0);
|
||||
hpPanel.setStrokeStyle(1, 0x40515e, 0.58);
|
||||
this.trackSideIcon(left + 18, top + 89, 'hp', 29);
|
||||
this.trackSideObject(this.add.text(left + 40, top + 79, '병력', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '17px',
|
||||
color: '#d4dce6',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
const hpValue = this.trackSideObject(this.add.text(left + width, top + 76, `${unit.hp} / ${unit.maxHp}`, {
|
||||
const hpValue = this.trackSideObject(this.add.text(left + width - 12, top + 79, `${unit.hp} / ${unit.maxHp}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '18px',
|
||||
color: '#f0e4c8',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
hpValue.setOrigin(1, 0);
|
||||
this.drawGauge(left + 102, top + 84, width - 186, 10, unit.hp / unit.maxHp, 0x59d18c);
|
||||
this.drawGauge(left + 104, top + 93, width - 168, 10, unit.hp / unit.maxHp, 0x59d18c);
|
||||
|
||||
const attackBonus = this.equipmentAttackBonus(unit);
|
||||
const summaryGap = 6;
|
||||
const summaryBoxWidth = (width - summaryGap * 2) / 3;
|
||||
this.renderCompactValueBox(left, top + 112, summaryBoxWidth, 'attack', '공격', `${unit.attack + attackBonus}`);
|
||||
this.renderCompactValueBox(left + summaryBoxWidth + summaryGap, top + 112, summaryBoxWidth, 'defense', '방어+', `${this.equipmentDefenseBonus(unit)}`);
|
||||
this.renderCompactValueBox(left, top + 114, summaryBoxWidth, 'attack', '공격', `${unit.attack + attackBonus}`);
|
||||
this.renderCompactValueBox(left + summaryBoxWidth + summaryGap, top + 114, summaryBoxWidth, 'defense', '방어+', `${this.equipmentDefenseBonus(unit)}`);
|
||||
this.renderCompactValueBox(
|
||||
left + (summaryBoxWidth + summaryGap) * 2,
|
||||
top + 112,
|
||||
top + 114,
|
||||
summaryBoxWidth,
|
||||
this.unitMoveIcon(unit),
|
||||
'방향',
|
||||
`${this.directionSymbol(direction)} ${this.unitDirectionLabel(direction)}`
|
||||
);
|
||||
|
||||
const statTop = top + 158;
|
||||
const statTop = top + 164;
|
||||
statLabels.forEach((stat, index) => {
|
||||
this.renderStatRow(stat.key, stat.label, unit.stats[stat.key], left, statTop + index * 28, width);
|
||||
this.renderStatRow(stat.key, stat.label, unit.stats[stat.key], left, statTop + index * 24, width);
|
||||
});
|
||||
|
||||
const effects = this.unitEffectSummaries(unit);
|
||||
const effectText = effects.length > 0 ? `\n효과 ${this.compactUnitEffectText(effects)}` : '';
|
||||
const positionText = `위치 ${unit.x + 1}, ${unit.y + 1} / ${terrainRule.label} ${terrainRating}% / 이동 ${unit.move}${acted ? ' / 행동완료' : ''}${effectText}`;
|
||||
this.trackSideIcon(left + 13, top + 294, effects[0]?.icon ?? (acted ? 'counter' : this.unitMoveIcon(unit)), 24);
|
||||
this.trackSideObject(this.add.text(left + 28, effects.length > 0 ? top + 280 : top + 285, positionText, {
|
||||
const effectText = effects.length > 0 ? ` / 효과 ${this.compactUnitEffectText(effects)}` : '';
|
||||
const positionText = `위치 ${unit.x + 1}, ${unit.y + 1} · ${terrainRule.label} ${terrainRating}% · 이동 ${unit.move}${acted ? ' · 행동완료' : ''}${effectText}`;
|
||||
const statusPanel = this.trackSideObject(this.add.rectangle(left, top + 288, width, 32, 0x101820, 0.9));
|
||||
statusPanel.setOrigin(0);
|
||||
statusPanel.setStrokeStyle(1, 0x40515e, 0.5);
|
||||
this.trackSideIcon(left + 17, top + 304, effects[0]?.icon ?? (acted ? 'counter' : this.unitMoveIcon(unit)), 25);
|
||||
this.trackSideObject(this.add.text(left + 36, top + 294, positionText, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '14px',
|
||||
fontSize: '12px',
|
||||
color: acted ? '#bdbdbd' : '#9fb0bf',
|
||||
wordWrap: { width: width - 24, useAdvancedWrap: true }
|
||||
wordWrap: { width: width - 48, useAdvancedWrap: true },
|
||||
lineSpacing: 2
|
||||
}));
|
||||
|
||||
const equipmentTop = effects.length > 0 ? top + 318 : top + 302;
|
||||
const equipmentTop = top + 326;
|
||||
this.renderEquipmentSummary(unit, left, equipmentTop, width);
|
||||
if (message) {
|
||||
this.renderPanelMessage(message, left, equipmentTop + 154, width, 40);
|
||||
this.renderPanelMessage(message, left, equipmentTop + 156, width, 42);
|
||||
}
|
||||
this.showFacingIndicator(unit);
|
||||
}
|
||||
@@ -12551,7 +12571,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
|
||||
private renderEquipmentSummary(unit: UnitData, x: number, y: number, width: number) {
|
||||
this.trackSideIcon(x + 15, y + 12, 'mastery', 30);
|
||||
this.trackSideObject(this.add.text(x + 31, y, '장비 / 숙련도', {
|
||||
this.trackSideObject(this.add.text(x + 32, y, '장비 / 숙련도', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '17px',
|
||||
color: '#f2e3bf',
|
||||
@@ -12559,7 +12579,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
}));
|
||||
|
||||
equipmentSlots.forEach((slot, index) => {
|
||||
this.renderEquipmentRow(unit, slot, x, y + 26 + index * 42, width);
|
||||
this.renderEquipmentRow(unit, slot, x, y + 28 + index * 40, width);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12568,47 +12588,37 @@ export class BattleScene extends Phaser.Scene {
|
||||
const item = getItem(state.itemId);
|
||||
const next = equipmentExpToNext(state.level);
|
||||
const isTreasure = item.rank === 'treasure';
|
||||
const bg = this.trackSideObject(this.add.rectangle(x, y, width, 40, isTreasure ? 0x1f2430 : 0x101820, isTreasure ? 0.97 : 0.94));
|
||||
const bg = this.trackSideObject(this.add.rectangle(x, y, width, 38, isTreasure ? 0x1f2430 : 0x101820, isTreasure ? 0.98 : 0.95));
|
||||
bg.setOrigin(0);
|
||||
bg.setStrokeStyle(1, isTreasure ? palette.gold : 0x53606c, isTreasure ? 0.66 : 0.5);
|
||||
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(x + 23, y + 20, 38, 38, 0x0a0f14, 0.9));
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(x + 23, y + 19, 36, 36, 0x0a0f14, 0.92));
|
||||
iconFrame.setStrokeStyle(1, isTreasure ? palette.gold : 0x53606c, isTreasure ? 0.78 : 0.54);
|
||||
|
||||
this.trackSideIcon(x + 23, y + 20, this.itemIcon(item, slot), 34);
|
||||
this.trackSideIcon(x + 23, y + 19, this.itemIcon(item, slot), 34);
|
||||
|
||||
this.trackSideObject(this.add.text(x + 50, y + 4, equipmentSlotLabels[slot], {
|
||||
this.trackSideObject(this.add.text(x + 48, y + 3, equipmentSlotLabels[slot], {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
fontSize: '11px',
|
||||
color: '#9fb0bf',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
this.trackSideObject(this.add.text(x + 94, y + 4, item.name, {
|
||||
const bonusText = this.itemBonusText(item);
|
||||
this.trackSideObject(this.add.text(x + 86, y + 3, bonusText, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '11px',
|
||||
color: '#aeb7c2',
|
||||
fixedWidth: width - 170
|
||||
}));
|
||||
this.trackSideObject(this.add.text(x + 48, y + 17, item.name, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '15px',
|
||||
color: isTreasure ? '#f4dfad' : '#d4dce6',
|
||||
fontStyle: '700',
|
||||
fixedWidth: width - 148
|
||||
fixedWidth: width - 150
|
||||
}));
|
||||
|
||||
const bonusText = this.itemBonusText(item);
|
||||
this.trackSideObject(this.add.text(x + 50, y + 22, bonusText, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '11px',
|
||||
color: '#aeb7c2',
|
||||
fixedWidth: 72
|
||||
}));
|
||||
|
||||
this.trackSideIcon(x + width - 82, y + 20, 'mastery', 21);
|
||||
const expText = this.trackSideObject(this.add.text(x + width - 58, y + 22, `${state.exp}/${next}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
color: '#c8d2dd',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
expText.setOrigin(1, 0);
|
||||
|
||||
const levelText = this.trackSideObject(this.add.text(x + width - 8, y + 8, `Lv ${state.level}`, {
|
||||
const levelText = this.trackSideObject(this.add.text(x + width - 10, y + 5, `Lv ${state.level}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '15px',
|
||||
color: isTreasure ? '#f2e3bf' : '#d4dce6',
|
||||
@@ -12616,7 +12626,16 @@ export class BattleScene extends Phaser.Scene {
|
||||
}));
|
||||
levelText.setOrigin(1, 0);
|
||||
|
||||
this.drawGauge(x + 126, y + 31, width - 202, 6, state.exp / next, isTreasure ? 0xd8b15f : 0x58aee0);
|
||||
this.trackSideIcon(x + width - 76, y + 27, 'mastery', 20);
|
||||
const expText = this.trackSideObject(this.add.text(x + width - 10, y + 24, `${state.exp}/${next}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '11px',
|
||||
color: '#c8d2dd',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
expText.setOrigin(1, 0);
|
||||
|
||||
this.drawGauge(x + 48, y + 32, width - 132, 5, state.exp / next, isTreasure ? 0xd8b15f : 0x58aee0);
|
||||
}
|
||||
|
||||
private createBattleUiIcon(x: number, y: number, icon: BattleUiIconKey, size = 22) {
|
||||
@@ -12741,20 +12760,21 @@ export class BattleScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
private renderCompactValueBox(x: number, y: number, width: number, icon: BattleUiIconKey, label: string, value: string) {
|
||||
const bg = this.trackSideObject(this.add.rectangle(x, y, width, 46, 0x16212d, 0.97));
|
||||
const bg = this.trackSideObject(this.add.rectangle(x, y, width, 42, 0x16212d, 0.97));
|
||||
bg.setOrigin(0);
|
||||
bg.setStrokeStyle(1, 0x647485, 0.72);
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(x + 18, y + 23, 32, 32, 0x0a0f14, 0.82));
|
||||
const iconFrame = this.trackSideObject(this.add.rectangle(x + 17, y + 21, 30, 30, 0x0a0f14, 0.86));
|
||||
iconFrame.setStrokeStyle(1, 0x53606c, 0.52);
|
||||
this.trackSideIcon(x + 18, y + 23, icon, 29);
|
||||
this.trackSideObject(this.add.text(x + 38, y + 7, label, {
|
||||
this.trackSideIcon(x + 17, y + 21, icon, 28);
|
||||
this.trackSideObject(this.add.text(x + 36, y + 5, label, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '12px',
|
||||
color: '#9fb0bf'
|
||||
fontSize: '11px',
|
||||
color: '#9fb0bf',
|
||||
fixedWidth: Math.max(36, width - 42)
|
||||
}));
|
||||
const valueText = this.trackSideObject(this.add.text(x + width - 8, y + 25, value, {
|
||||
const valueText = this.trackSideObject(this.add.text(x + width - 7, y + 29, value, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '15px',
|
||||
fontSize: '14px',
|
||||
color: '#f2e3bf',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
@@ -12762,19 +12782,21 @@ export class BattleScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
private renderStatRow(key: keyof UnitStats, label: string, value: number, x: number, y: number, width: number) {
|
||||
this.trackSideIcon(x + 13, y + 10, this.statIcon(key), 26);
|
||||
this.trackSideObject(this.add.text(x + 36, y, label, {
|
||||
const rowBg = this.trackSideObject(this.add.rectangle(x, y - 1, width, 22, 0x101820, 0.5));
|
||||
rowBg.setOrigin(0);
|
||||
this.trackSideIcon(x + 14, y + 10, this.statIcon(key), 23);
|
||||
this.trackSideObject(this.add.text(x + 34, y + 1, label, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '16px',
|
||||
fontSize: '14px',
|
||||
color: '#d4dce6',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
|
||||
this.drawGauge(x + 104, y + 8, width - 158, 10, value / 100, value >= 80 ? 0xd8b15f : 0x58aee0);
|
||||
this.drawGauge(x + 104, y + 7, width - 158, 8, value / 100, value >= 80 ? 0xd8b15f : 0x58aee0);
|
||||
|
||||
const valueText = this.trackSideObject(this.add.text(x + width, y - 1, `${value}`, {
|
||||
const valueText = this.trackSideObject(this.add.text(x + width - 8, y - 1, `${value}`, {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '17px',
|
||||
fontSize: '16px',
|
||||
color: '#f2e3bf',
|
||||
fontStyle: '700'
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user