Improve armor equipment icon silhouettes
This commit is contained in:
30
docs/equipment-icon-armor-pass.md
Normal file
30
docs/equipment-icon-armor-pass.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Armor Equipment Icon Pass
|
||||
|
||||
Generated after the armor icon rework in `src/game/scenes/BootScene.ts`.
|
||||
|
||||
## Scope
|
||||
|
||||
- `oath-robe`
|
||||
- `reinforced-lamellar`
|
||||
- `cloth-armor`
|
||||
- `lamellar-armor`
|
||||
- `rebel-vest`
|
||||
|
||||
## Before and After
|
||||
|
||||
| item id | previous helper | current helper | previous primitives | current primitives | audit concerns |
|
||||
| --- | --- | --- | ---: | ---: | --- |
|
||||
| `oath-robe` | `drawRobeIcon` | `drawOathRobeIcon` | 7 | 25 | none |
|
||||
| `reinforced-lamellar` | `drawArmorIcon` | `drawReinforcedLamellarIcon` | 12 | 24 | none |
|
||||
| `cloth-armor` | `drawRobeIcon` | `drawClothArmorIcon` | 7 | 24 | none |
|
||||
| `lamellar-armor` | `drawArmorIcon` | `drawLamellarArmorIcon` | 12 | 23 | none |
|
||||
| `rebel-vest` | `drawVestIcon` | `drawRebelVestIcon` | 4 | 24 | none |
|
||||
|
||||
## Browser QA
|
||||
|
||||

|
||||
|
||||
- URL checked: `http://127.0.0.1:4198/heros_web/?debug&debugSortiePrep&renderer=canvas`
|
||||
- Result: sortie prep opened on a desktop 1280x720 canvas and rendered the generated armor textures in roster, slot, and detail surfaces.
|
||||
- Browser console warnings/errors: none observed.
|
||||
- Follow-up target from the updated audit: accessory charms and tokens.
|
||||
BIN
docs/equipment-icon-armor-sortie-prep.png
Normal file
BIN
docs/equipment-icon-armor-sortie-prep.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
@@ -26,27 +26,24 @@ Generated by `scripts/audit-equipment-icon-quality.mjs`.
|
||||
|
||||
- weapon spear/polearm family: `green-dragon-glaive`, `serpent-spear`, `sky-piercer-halberd`, `iron-spear`, `western-cavalry-spear`
|
||||
- The previous shared spear/polearm silhouettes now use item-specific helper shapes with enough primitive detail for 20px and 30px equipment UI reads.
|
||||
- armor silhouettes: `oath-robe`, `reinforced-lamellar`, `cloth-armor`, `lamellar-armor`, `rebel-vest`
|
||||
- The previous shared armor and robe silhouettes now use item-specific helper shapes with stronger outer contours and material cues.
|
||||
|
||||
## Next Improvement Target
|
||||
|
||||
- Target: armor silhouettes
|
||||
- Item ids: `oath-robe`, `reinforced-lamellar`, `cloth-armor`, `lamellar-armor`, `rebel-vest`
|
||||
- Reason: Armor and robes are readable but still depend on simple triangular torsos and small color accents; this is now the largest remaining shared-equipment silhouette group.
|
||||
|
||||
## Follow-Up Targets
|
||||
|
||||
- accessory charms and tokens: `bravery-token`, `mountain-guide-scroll`, `peach-charm`, `war-manual`, `wind-quiver`, `grain-pouch`, `yellow-scarf-charm`
|
||||
- Accessories are the smallest UI read and several use compact badge-like shapes.
|
||||
- Target: accessory charms and tokens
|
||||
- Item ids: `bravery-token`, `mountain-guide-scroll`, `peach-charm`, `war-manual`, `wind-quiver`, `grain-pouch`, `yellow-scarf-charm`
|
||||
- Reason: Accessories are the smallest UI read and several use compact badge-like shapes.
|
||||
|
||||
## Highest-Risk Shared Silhouette Groups
|
||||
|
||||
| score | signature | slots | ranks | items |
|
||||
| ---: | --- | --- | --- | --- |
|
||||
| 8 | `drawArmorIcon` | armor | common, treasure | `reinforced-lamellar`, `lamellar-armor` |
|
||||
| 8 | `drawCharmIcon` | accessory | common, treasure | `peach-charm`, `yellow-scarf-charm` |
|
||||
| 8 | `drawRobeIcon` | armor | common, treasure | `oath-robe`, `cloth-armor` |
|
||||
| 6 | `drawAxeIcon` | weapon | common | `leader-axe` |
|
||||
| 6 | `drawSaberIcon` | weapon | common | `yellow-turban-saber` |
|
||||
| 6 | `drawSwordIcon` | weapon | common | `training-sword` |
|
||||
| 5 | `drawFanIcon` | weapon | treasure | `white-feather-fan` |
|
||||
|
||||
## Full Item Inventory
|
||||
|
||||
@@ -63,11 +60,11 @@ Generated by `scripts/audit-equipment-icon-quality.mjs`.
|
||||
| `training-sword` | weapon | common | `drawSwordIcon` | 1 | 16 | 4 | low primitive detail |
|
||||
| `western-cavalry-spear` | weapon | common | `drawWesternCavalrySpearIcon` | 1 | 27 | 7 | none |
|
||||
| `yellow-turban-saber` | weapon | common | `drawSaberIcon` | 1 | 12 | 2 | low primitive detail |
|
||||
| `oath-robe` | armor | treasure | `drawRobeIcon` | 1 | 7 | 3 | shared helper silhouette<br>low primitive detail |
|
||||
| `reinforced-lamellar` | armor | treasure | `drawArmorIcon` | 1 | 12 | 3 | shared helper silhouette<br>low primitive detail |
|
||||
| `cloth-armor` | armor | common | `drawRobeIcon` | 1 | 7 | 3 | shared helper silhouette<br>low primitive detail |
|
||||
| `lamellar-armor` | armor | common | `drawArmorIcon` | 1 | 12 | 3 | shared helper silhouette<br>low primitive detail |
|
||||
| `rebel-vest` | armor | common | `drawVestIcon` | 1 | 4 | 3 | low primitive detail |
|
||||
| `oath-robe` | armor | treasure | `drawOathRobeIcon` | 1 | 25 | 6 | none |
|
||||
| `reinforced-lamellar` | armor | treasure | `drawReinforcedLamellarIcon` | 1 | 24 | 5 | none |
|
||||
| `cloth-armor` | armor | common | `drawClothArmorIcon` | 1 | 24 | 6 | none |
|
||||
| `lamellar-armor` | armor | common | `drawLamellarArmorIcon` | 1 | 23 | 4 | none |
|
||||
| `rebel-vest` | armor | common | `drawRebelVestIcon` | 1 | 24 | 7 | none |
|
||||
| `bravery-token` | accessory | treasure | `drawTokenIcon` | 1 | 4 | 2 | low primitive detail |
|
||||
| `mountain-guide-scroll` | accessory | treasure | `drawMapScrollIcon` | 1 | 13 | 5 | low primitive detail |
|
||||
| `peach-charm` | accessory | treasure | `drawCharmIcon` | 1 | 4 | 2 | shared helper silhouette<br>low primitive detail |
|
||||
@@ -78,8 +75,8 @@ Generated by `scripts/audit-equipment-icon-quality.mjs`.
|
||||
|
||||
## Recommended Next Batch Definition
|
||||
|
||||
- Scope: improve armor silhouettes while keeping `item-${itemId}` texture keys stable.
|
||||
- Item ids: `oath-robe`, `reinforced-lamellar`, `cloth-armor`, `lamellar-armor`, `rebel-vest`
|
||||
- Success criteria: Each armor item should keep its slot identity while gaining a distinct outer silhouette and material cue at 20px and 30px.
|
||||
- Scope: improve accessory charms and tokens while keeping `item-${itemId}` texture keys stable.
|
||||
- Item ids: `bravery-token`, `mountain-guide-scroll`, `peach-charm`, `war-manual`, `wind-quiver`, `grain-pouch`, `yellow-scarf-charm`
|
||||
- Success criteria: Each accessory should keep a compact footprint while gaining a distinct readable prop shape at 20px and 30px.
|
||||
- Keep the existing 64px texture size unless a UI-wide equipment icon pass is planned.
|
||||
- Add before/after contact sheets and verify the sortie equipment list and equipment swap panel in a desktop browser.
|
||||
|
||||
@@ -313,58 +313,84 @@ function buildRecommendations(itemRows, groupedRows) {
|
||||
'sky-piercer-halberd',
|
||||
'western-cavalry-spear'
|
||||
];
|
||||
const weaponPolearmRows = itemRows.filter((row) => weaponPolearmTargetIds.includes(row.itemId));
|
||||
const armorIds = itemRows.filter((row) => row.slot === 'armor').map((row) => row.itemId);
|
||||
const armorTargetIds = ['oath-robe', 'reinforced-lamellar', 'cloth-armor', 'lamellar-armor', 'rebel-vest'];
|
||||
const accessoryIds = itemRows.filter((row) => row.slot === 'accessory').map((row) => row.itemId);
|
||||
const weaponPolearmComplete =
|
||||
weaponPolearmRows.length === weaponPolearmTargetIds.length &&
|
||||
weaponPolearmRows.every((row) => row.icon && row.primitiveCount >= 18) &&
|
||||
new Set(weaponPolearmRows.map((row) => row.signature)).size === weaponPolearmRows.length;
|
||||
|
||||
const completedTargets = weaponPolearmComplete
|
||||
? [
|
||||
{
|
||||
title: 'weapon spear/polearm family',
|
||||
itemIds: weaponPolearmRows.map((row) => row.itemId),
|
||||
reason: 'The previous shared spear/polearm silhouettes now use item-specific helper shapes with enough primitive detail for 20px and 30px equipment UI reads.'
|
||||
}
|
||||
]
|
||||
: [];
|
||||
const targets = [
|
||||
{
|
||||
title: 'weapon spear/polearm family',
|
||||
itemIds: weaponPolearmTargetIds,
|
||||
completeReason:
|
||||
'The previous shared spear/polearm silhouettes now use item-specific helper shapes with enough primitive detail for 20px and 30px equipment UI reads.',
|
||||
openReason:
|
||||
'These are high-frequency equipment surfaces and several treasure/common weapons share a thin diagonal shaft silhouette; upgrading this group gives the clearest identity gain in sortie prep and equipment swap screens.',
|
||||
successCriteria:
|
||||
'Each item should read as a distinct weapon silhouette at 20px and 30px, with treasure weapons visibly richer than common weapons.'
|
||||
},
|
||||
{
|
||||
title: 'armor silhouettes',
|
||||
itemIds: armorTargetIds,
|
||||
completeReason:
|
||||
'The previous shared armor and robe silhouettes now use item-specific helper shapes with stronger outer contours and material cues.',
|
||||
openReason:
|
||||
'Armor and robes are readable but still depend on simple triangular torsos and small color accents; this is now the largest remaining shared-equipment silhouette group.',
|
||||
successCriteria:
|
||||
'Each armor item should keep its slot identity while gaining a distinct outer silhouette and material cue at 20px and 30px.'
|
||||
},
|
||||
{
|
||||
title: 'accessory charms and tokens',
|
||||
itemIds: accessoryIds,
|
||||
completeReason:
|
||||
'Accessory icons now use distinct badge, scroll, charm, pouch, manual, and quiver silhouettes at small camp UI sizes.',
|
||||
openReason: 'Accessories are the smallest UI read and several use compact badge-like shapes.',
|
||||
successCriteria:
|
||||
'Each accessory should keep a compact footprint while gaining a distinct readable prop shape at 20px and 30px.'
|
||||
}
|
||||
].map((target) => ({
|
||||
...target,
|
||||
rows: itemRows.filter((row) => target.itemIds.includes(row.itemId))
|
||||
}));
|
||||
const completedTargets = targets
|
||||
.filter((target) => improvementTargetComplete(target))
|
||||
.map((target) => ({
|
||||
title: target.title,
|
||||
itemIds: target.rows.map((row) => row.itemId),
|
||||
reason: target.completeReason
|
||||
}));
|
||||
const nextTarget =
|
||||
targets.find((target) => !improvementTargetComplete(target)) ?? {
|
||||
title: 'remaining low-detail equipment icons',
|
||||
rows: itemRows.filter((row) => row.concerns.length > 0),
|
||||
openReason: 'All named batches are complete; remaining work should be selected from the low-detail inventory rows.',
|
||||
successCriteria: 'Clear remaining low-detail concerns without changing stable texture keys.'
|
||||
};
|
||||
const nextTargetIndex = targets.findIndex((target) => target.title === nextTarget.title);
|
||||
const followUps = targets
|
||||
.filter((target, index) => index > nextTargetIndex && !improvementTargetComplete(target))
|
||||
.map((target) => ({
|
||||
title: target.title,
|
||||
itemIds: target.rows.map((row) => row.itemId),
|
||||
reason: target.openReason
|
||||
}));
|
||||
|
||||
return {
|
||||
completedTargets,
|
||||
firstTargetTitle: weaponPolearmComplete ? 'armor silhouettes' : 'weapon spear/polearm family',
|
||||
firstTargetIds: weaponPolearmComplete ? armorIds : weaponPolearmRows.map((row) => row.itemId),
|
||||
firstTargetReason: weaponPolearmComplete
|
||||
? 'Armor and robes are readable but still depend on simple triangular torsos and small color accents; this is now the largest remaining shared-equipment silhouette group.'
|
||||
: 'These are high-frequency equipment surfaces and several treasure/common weapons share a thin diagonal shaft silhouette; upgrading this group gives the clearest identity gain in sortie prep and equipment swap screens.',
|
||||
firstTargetSuccessCriteria: weaponPolearmComplete
|
||||
? 'Each armor item should keep its slot identity while gaining a distinct outer silhouette and material cue at 20px and 30px.'
|
||||
: 'Each item should read as a distinct weapon silhouette at 20px and 30px, with treasure weapons visibly richer than common weapons.',
|
||||
followUps: weaponPolearmComplete
|
||||
? [
|
||||
{
|
||||
title: 'accessory charms and tokens',
|
||||
itemIds: accessoryIds,
|
||||
reason: 'Accessories are the smallest UI read and several use compact badge-like shapes.'
|
||||
}
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: 'armor silhouettes',
|
||||
itemIds: armorIds,
|
||||
reason: 'Armor and robes are readable but depend on simple triangular torsos and small color accents.'
|
||||
},
|
||||
{
|
||||
title: 'accessory charms and tokens',
|
||||
itemIds: accessoryIds,
|
||||
reason: 'Accessories are the smallest UI read and several use compact badge-like shapes.'
|
||||
}
|
||||
],
|
||||
firstTargetTitle: nextTarget.title,
|
||||
firstTargetIds: nextTarget.rows.map((row) => row.itemId),
|
||||
firstTargetReason: nextTarget.openReason,
|
||||
firstTargetSuccessCriteria: nextTarget.successCriteria,
|
||||
followUps,
|
||||
topRiskGroups: groupedRows.slice(0, 5)
|
||||
};
|
||||
}
|
||||
|
||||
function improvementTargetComplete(target) {
|
||||
return (
|
||||
target.rows.length === target.itemIds.length &&
|
||||
target.rows.every((row) => row.icon && row.primitiveCount >= 18) &&
|
||||
new Set(target.rows.map((row) => row.signature)).size === target.rows.length
|
||||
);
|
||||
}
|
||||
|
||||
function renderReport({ iconSourceSize, iconTextureSize, itemRows, groupedRows, recommendations, sceneUsage }) {
|
||||
const slotCounts = countBy(itemRows, (row) => row.slot);
|
||||
const rankCounts = countBy(itemRows, (row) => row.rank);
|
||||
@@ -403,13 +429,7 @@ function renderReport({ iconSourceSize, iconTextureSize, itemRows, groupedRows,
|
||||
`- Item ids: ${recommendations.firstTargetIds.map((itemId) => `\`${itemId}\``).join(', ')}`,
|
||||
`- Reason: ${recommendations.firstTargetReason}`,
|
||||
'',
|
||||
'## Follow-Up Targets',
|
||||
'',
|
||||
...recommendations.followUps.flatMap((target) => [
|
||||
`- ${target.title}: ${target.itemIds.map((itemId) => `\`${itemId}\``).join(', ')}`,
|
||||
` - ${target.reason}`
|
||||
]),
|
||||
'',
|
||||
...renderFollowUpTargets(recommendations.followUps),
|
||||
'## Highest-Risk Shared Silhouette Groups',
|
||||
'',
|
||||
'| score | signature | slots | ranks | items |',
|
||||
@@ -463,6 +483,22 @@ function renderCompletedTargets(completedTargets) {
|
||||
];
|
||||
}
|
||||
|
||||
function renderFollowUpTargets(followUps) {
|
||||
if (!followUps.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'## Follow-Up Targets',
|
||||
'',
|
||||
...followUps.flatMap((target) => [
|
||||
`- ${target.title}: ${target.itemIds.map((itemId) => `\`${itemId}\``).join(', ')}`,
|
||||
` - ${target.reason}`
|
||||
]),
|
||||
''
|
||||
];
|
||||
}
|
||||
|
||||
function countBy(rows, keySelector) {
|
||||
return rows.reduce((counts, row) => {
|
||||
const key = keySelector(row);
|
||||
|
||||
@@ -45,11 +45,11 @@ export class BootScene extends Phaser.Scene {
|
||||
this.createItemIcon('item-short-bow', (graphics) => this.drawBowIcon(graphics, 0xc58a4c, 0xe8dfca));
|
||||
this.createItemIcon('item-leader-axe', (graphics) => this.drawAxeIcon(graphics, 0xd8dfe6, 0x8d5a3a));
|
||||
|
||||
this.createItemIcon('item-cloth-armor', (graphics) => this.drawRobeIcon(graphics, 0x91a8bc, 0xe8dfca));
|
||||
this.createItemIcon('item-lamellar-armor', (graphics) => this.drawArmorIcon(graphics, 0x7d8792, 0xd8b15f));
|
||||
this.createItemIcon('item-oath-robe', (graphics) => this.drawRobeIcon(graphics, 0x4e7aa8, 0xf0c0a8));
|
||||
this.createItemIcon('item-reinforced-lamellar', (graphics) => this.drawArmorIcon(graphics, 0xb8c4ce, 0x59a6d6));
|
||||
this.createItemIcon('item-rebel-vest', (graphics) => this.drawVestIcon(graphics, 0xb88b4a, 0xd8b15f));
|
||||
this.createItemIcon('item-cloth-armor', (graphics) => this.drawClothArmorIcon(graphics));
|
||||
this.createItemIcon('item-lamellar-armor', (graphics) => this.drawLamellarArmorIcon(graphics));
|
||||
this.createItemIcon('item-oath-robe', (graphics) => this.drawOathRobeIcon(graphics));
|
||||
this.createItemIcon('item-reinforced-lamellar', (graphics) => this.drawReinforcedLamellarIcon(graphics));
|
||||
this.createItemIcon('item-rebel-vest', (graphics) => this.drawRebelVestIcon(graphics));
|
||||
|
||||
this.createItemIcon('item-peach-charm', (graphics) => this.drawCharmIcon(graphics, 0xf0a6a4, 0xd8b15f));
|
||||
this.createItemIcon('item-war-manual', (graphics) => this.drawBookIcon(graphics, 0x5b78a0, 0xe8dfca));
|
||||
@@ -325,41 +325,159 @@ export class BootScene extends Phaser.Scene {
|
||||
graphics.fillCircle(16, 25, 3);
|
||||
}
|
||||
|
||||
private drawArmorIcon(graphics: Phaser.GameObjects.Graphics, baseColor: number, accentColor: number) {
|
||||
graphics.fillStyle(baseColor, 1);
|
||||
graphics.fillTriangle(14, 4, 24, 11, 20, 24);
|
||||
graphics.fillTriangle(14, 4, 4, 11, 8, 24);
|
||||
graphics.fillRect(8, 10, 12, 14);
|
||||
graphics.lineStyle(2, accentColor, 0.9);
|
||||
graphics.strokeRect(9, 11, 10, 12);
|
||||
graphics.lineStyle(1, 0x05070a, 0.6);
|
||||
private drawClothArmorIcon(graphics: Phaser.GameObjects.Graphics) {
|
||||
graphics.fillStyle(0x6f889a, 1);
|
||||
graphics.fillTriangle(14, 4, 25, 10, 21, 23);
|
||||
graphics.fillTriangle(14, 4, 3, 10, 7, 23);
|
||||
graphics.fillRoundedRect(8, 8, 12, 16, 2);
|
||||
graphics.fillStyle(0x91a8bc, 1);
|
||||
graphics.fillTriangle(10, 8, 18, 8, 14, 15);
|
||||
graphics.fillRect(9, 14, 10, 9);
|
||||
graphics.fillStyle(0x34434d, 0.8);
|
||||
graphics.fillTriangle(14, 7, 18, 23, 10, 23);
|
||||
graphics.lineStyle(2, 0xe8dfca, 0.95);
|
||||
graphics.beginPath();
|
||||
graphics.moveTo(10, 16);
|
||||
graphics.lineTo(18, 16);
|
||||
graphics.moveTo(9, 11);
|
||||
graphics.lineTo(14, 15);
|
||||
graphics.lineTo(19, 11);
|
||||
graphics.moveTo(8, 18);
|
||||
graphics.lineTo(20, 18);
|
||||
graphics.strokePath();
|
||||
graphics.lineStyle(1, 0x26313a, 0.85);
|
||||
graphics.beginPath();
|
||||
graphics.moveTo(7, 13);
|
||||
graphics.lineTo(10, 22);
|
||||
graphics.moveTo(21, 13);
|
||||
graphics.lineTo(18, 22);
|
||||
graphics.moveTo(11, 20);
|
||||
graphics.lineTo(17, 20);
|
||||
graphics.strokePath();
|
||||
graphics.fillStyle(0xd8b15f, 1);
|
||||
graphics.fillCircle(14, 18, 1);
|
||||
}
|
||||
|
||||
private drawRobeIcon(graphics: Phaser.GameObjects.Graphics, baseColor: number, accentColor: number) {
|
||||
graphics.fillStyle(baseColor, 1);
|
||||
graphics.fillTriangle(14, 4, 24, 24, 4, 24);
|
||||
graphics.fillStyle(0x101820, 0.45);
|
||||
graphics.fillTriangle(14, 8, 18, 24, 10, 24);
|
||||
graphics.lineStyle(2, accentColor, 1);
|
||||
private drawLamellarArmorIcon(graphics: Phaser.GameObjects.Graphics) {
|
||||
graphics.fillStyle(0x4f5964, 1);
|
||||
graphics.fillTriangle(14, 4, 25, 11, 21, 24);
|
||||
graphics.fillTriangle(14, 4, 3, 11, 7, 24);
|
||||
graphics.fillRect(7, 8, 14, 16);
|
||||
graphics.fillStyle(0x7d8792, 1);
|
||||
graphics.fillRect(9, 9, 4, 5);
|
||||
graphics.fillRect(15, 9, 4, 5);
|
||||
graphics.fillRect(8, 15, 5, 4);
|
||||
graphics.fillRect(15, 15, 5, 4);
|
||||
graphics.fillRect(10, 20, 3, 4);
|
||||
graphics.fillRect(15, 20, 3, 4);
|
||||
graphics.lineStyle(2, 0xd8b15f, 0.9);
|
||||
graphics.strokeRect(8, 8, 12, 16);
|
||||
graphics.lineStyle(1, 0x101820, 0.75);
|
||||
graphics.beginPath();
|
||||
graphics.moveTo(14, 6);
|
||||
graphics.lineTo(14, 23);
|
||||
graphics.moveTo(14, 8);
|
||||
graphics.lineTo(14, 24);
|
||||
graphics.moveTo(8, 15);
|
||||
graphics.lineTo(20, 15);
|
||||
graphics.moveTo(9, 20);
|
||||
graphics.lineTo(19, 20);
|
||||
graphics.strokePath();
|
||||
graphics.fillStyle(0xd8b15f, 1);
|
||||
graphics.fillCircle(14, 6, 1);
|
||||
graphics.fillCircle(10, 13, 1);
|
||||
graphics.fillCircle(18, 13, 1);
|
||||
}
|
||||
|
||||
private drawOathRobeIcon(graphics: Phaser.GameObjects.Graphics) {
|
||||
graphics.fillStyle(0x304f7d, 1);
|
||||
graphics.fillTriangle(14, 3, 27, 14, 22, 25);
|
||||
graphics.fillTriangle(14, 3, 1, 14, 6, 25);
|
||||
graphics.fillRoundedRect(7, 7, 14, 18, 2);
|
||||
graphics.fillStyle(0x4e7aa8, 1);
|
||||
graphics.fillTriangle(9, 8, 19, 8, 15, 25);
|
||||
graphics.fillTriangle(7, 13, 2, 22, 9, 19);
|
||||
graphics.fillTriangle(21, 13, 26, 22, 19, 19);
|
||||
graphics.fillStyle(0xf0c0a8, 1);
|
||||
graphics.fillTriangle(10, 6, 18, 6, 14, 13);
|
||||
graphics.fillStyle(0x192840, 0.65);
|
||||
graphics.fillTriangle(14, 10, 18, 25, 11, 25);
|
||||
graphics.lineStyle(2, 0xd8b15f, 0.95);
|
||||
graphics.beginPath();
|
||||
graphics.moveTo(9, 9);
|
||||
graphics.lineTo(14, 14);
|
||||
graphics.lineTo(19, 9);
|
||||
graphics.moveTo(9, 18);
|
||||
graphics.lineTo(20, 18);
|
||||
graphics.strokePath();
|
||||
graphics.lineStyle(1, 0xe8dfca, 0.8);
|
||||
graphics.beginPath();
|
||||
graphics.moveTo(14, 14);
|
||||
graphics.lineTo(14, 24);
|
||||
graphics.moveTo(5, 21);
|
||||
graphics.lineTo(10, 18);
|
||||
graphics.moveTo(23, 21);
|
||||
graphics.lineTo(18, 18);
|
||||
graphics.strokePath();
|
||||
}
|
||||
|
||||
private drawVestIcon(graphics: Phaser.GameObjects.Graphics, baseColor: number, accentColor: number) {
|
||||
graphics.fillStyle(baseColor, 1);
|
||||
graphics.fillRect(7, 7, 14, 18);
|
||||
graphics.fillStyle(0x101820, 0.7);
|
||||
graphics.fillTriangle(11, 7, 17, 7, 14, 14);
|
||||
graphics.lineStyle(2, accentColor, 0.9);
|
||||
graphics.strokeRect(8, 8, 12, 16);
|
||||
private drawReinforcedLamellarIcon(graphics: Phaser.GameObjects.Graphics) {
|
||||
graphics.fillStyle(0x5f6d78, 1);
|
||||
graphics.fillTriangle(14, 3, 27, 10, 22, 24);
|
||||
graphics.fillTriangle(14, 3, 1, 10, 6, 24);
|
||||
graphics.fillRoundedRect(6, 8, 16, 16, 2);
|
||||
graphics.fillStyle(0xb8c4ce, 1);
|
||||
graphics.fillRect(8, 8, 5, 7);
|
||||
graphics.fillRect(15, 8, 5, 7);
|
||||
graphics.fillRect(8, 16, 5, 4);
|
||||
graphics.fillRect(15, 16, 5, 4);
|
||||
graphics.fillRect(10, 21, 8, 3);
|
||||
graphics.fillStyle(0x8fa2b2, 1);
|
||||
graphics.fillTriangle(6, 10, 1, 15, 7, 18);
|
||||
graphics.fillTriangle(22, 10, 27, 15, 21, 18);
|
||||
graphics.lineStyle(2, 0x59a6d6, 0.95);
|
||||
graphics.strokeRoundedRect(7, 8, 14, 16, 2);
|
||||
graphics.lineStyle(1, 0x101820, 0.8);
|
||||
graphics.beginPath();
|
||||
graphics.moveTo(14, 7);
|
||||
graphics.lineTo(14, 24);
|
||||
graphics.moveTo(8, 15);
|
||||
graphics.lineTo(20, 15);
|
||||
graphics.moveTo(8, 20);
|
||||
graphics.lineTo(20, 20);
|
||||
graphics.strokePath();
|
||||
graphics.fillStyle(0x59a6d6, 1);
|
||||
graphics.fillCircle(10, 12, 1);
|
||||
graphics.fillCircle(18, 12, 1);
|
||||
graphics.fillCircle(14, 18, 1);
|
||||
}
|
||||
|
||||
private drawRebelVestIcon(graphics: Phaser.GameObjects.Graphics) {
|
||||
graphics.fillStyle(0x8a5a32, 1);
|
||||
graphics.fillTriangle(8, 6, 20, 6, 22, 25);
|
||||
graphics.fillTriangle(8, 6, 5, 24, 14, 22);
|
||||
graphics.fillStyle(0xb88b4a, 1);
|
||||
graphics.fillRect(7, 8, 6, 15);
|
||||
graphics.fillRect(15, 8, 6, 16);
|
||||
graphics.fillStyle(0x5d3b27, 1);
|
||||
graphics.fillTriangle(12, 8, 16, 8, 14, 16);
|
||||
graphics.fillTriangle(6, 20, 12, 22, 8, 25);
|
||||
graphics.fillTriangle(16, 23, 22, 24, 19, 26);
|
||||
graphics.fillStyle(0xd8b15f, 1);
|
||||
graphics.fillTriangle(7, 6, 20, 6, 14, 10);
|
||||
graphics.fillRect(10, 16, 8, 2);
|
||||
graphics.lineStyle(2, 0x101820, 0.75);
|
||||
graphics.strokeRect(7, 8, 14, 16);
|
||||
graphics.lineStyle(1, 0xe8dfca, 0.8);
|
||||
graphics.beginPath();
|
||||
graphics.moveTo(9, 11);
|
||||
graphics.lineTo(12, 15);
|
||||
graphics.moveTo(18, 11);
|
||||
graphics.lineTo(15, 15);
|
||||
graphics.moveTo(9, 20);
|
||||
graphics.lineTo(13, 18);
|
||||
graphics.moveTo(16, 20);
|
||||
graphics.lineTo(20, 18);
|
||||
graphics.strokePath();
|
||||
graphics.fillStyle(0x9b4c3a, 1);
|
||||
graphics.fillCircle(10, 14, 1);
|
||||
graphics.fillCircle(18, 17, 1);
|
||||
}
|
||||
|
||||
private drawCharmIcon(graphics: Phaser.GameObjects.Graphics, baseColor: number, accentColor: number) {
|
||||
|
||||
Reference in New Issue
Block a user