Compare commits

...

2 Commits

Author SHA1 Message Date
Peter Stockings
f344213f55 Add temporary character outline in equipment overlay 2026-01-07 23:54:27 +11:00
Peter Stockings
a55661ccdf Start updating look of inventory overlay 2026-01-07 20:48:58 +11:00
3 changed files with 195 additions and 63 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

View File

@@ -142,7 +142,8 @@ export const GAME_CONFIG = {
{ key: "items", path: "assets/sprites/items/items.png", frameConfig: { frameWidth: 16, frameHeight: 16 } }, { key: "items", path: "assets/sprites/items/items.png", frameConfig: { frameWidth: 16, frameHeight: 16 } },
], ],
images: [ images: [
{ key: "splash_bg", path: "assets/ui/splash_bg.png" } { key: "splash_bg", path: "assets/ui/splash_bg.png" },
{ key: "character_outline", path: "assets/ui/character_outline.png" }
] ]
}, },

View File

@@ -7,72 +7,204 @@ export class InventoryOverlay extends OverlayComponent {
private backpackSlots: Phaser.GameObjects.Container[] = []; private backpackSlots: Phaser.GameObjects.Container[] = [];
protected setupContent() { protected setupContent() {
const panelH = 500; // Base overlay is 700x500, so we need to fit within those bounds
const panelW = 680;
const panelH = 480;
const title = this.scene.add.text(0, -panelH / 2 + 25, "INVENTORY", { // Main title
fontSize: "28px", const title = this.scene.add.text(0, -panelH / 2 + 25, "EQUIPMENT & INVENTORY", {
fontSize: "26px",
color: "#d4af37", color: "#d4af37",
fontStyle: "bold" fontStyle: "bold",
fontFamily: "serif"
}).setOrigin(0.5); }).setOrigin(0.5);
this.container.add(title); this.container.add(title);
this.createEquipmentSection(); // Draw ornate border around entire panel
this.createBackpackSection(); this.drawOrnateBorder(panelW, panelH);
// Create two distinct panels
this.createEquipmentPanel();
this.createBackpackPanel();
} }
private createEquipmentSection() { private drawOrnateBorder(w: number, h: number) {
const eqX = -180; const g = this.scene.add.graphics();
const eqY = 10;
const createSlot = (x: number, y: number, w: number, h: number, label: string, key: string) => { // Main outer border - golden
g.lineStyle(3, 0xd4af37, 1);
g.strokeRect(-w / 2 + 10, -h / 2 + 50, w - 20, h - 60);
// Inner accent line
g.lineStyle(2, 0x8b7355, 0.8);
g.strokeRect(-w / 2 + 14, -h / 2 + 54, w - 28, h - 68);
// Corner flourishes
const cornerSize = 20;
const corners = [
{ x: -w / 2 + 10, y: -h / 2 + 50 }, // top-left
{ x: w / 2 - 10, y: -h / 2 + 50 }, // top-right
{ x: -w / 2 + 10, y: h / 2 - 10 }, // bottom-left
{ x: w / 2 - 10, y: h / 2 - 10 }, // bottom-right
];
g.lineStyle(3, 0xd4af37, 1);
corners.forEach((corner, idx) => {
const flipX = idx % 2 === 1 ? -1 : 1;
const flipY = idx >= 2 ? -1 : 1;
// Outer corner lines
g.beginPath();
g.moveTo(corner.x, corner.y + flipY * cornerSize);
g.lineTo(corner.x, corner.y);
g.lineTo(corner.x + flipX * cornerSize, corner.y);
g.strokePath();
// Inner decorative corner accent
g.lineStyle(2, 0xffd700, 0.6);
g.beginPath();
g.moveTo(corner.x + flipX * 5, corner.y + flipY * 10);
g.lineTo(corner.x + flipX * 5, corner.y + flipY * 5);
g.lineTo(corner.x + flipX * 10, corner.y + flipY * 5);
g.strokePath();
g.lineStyle(3, 0xd4af37, 1);
});
this.container.add(g);
}
private createEquipmentPanel() {
const panelX = -165;
const panelY = 40;
const panelW = 260;
const panelH = 360;
// Panel background
const bg = this.scene.add.graphics();
bg.fillStyle(0x2a1f2a, 0.9);
bg.fillRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH);
// Panel border
bg.lineStyle(2, 0x8b7355, 1);
bg.strokeRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH);
this.container.add(bg);
// Draw character silhouette behind slots
this.drawCharacterSilhouette(panelX, panelY);
// Create equipment slots
this.createEquipmentSlots(panelX, panelY);
}
private drawCharacterSilhouette(centerX: number, centerY: number) {
// Load and display the character outline image
const outline = this.scene.add.image(centerX, centerY, "character_outline");
outline.setOrigin(0.5, 0.5);
outline.setAlpha(0.35); // Subtle transparency
outline.setScale(0.35); // Scale to fit nicely behind slots
this.container.add(outline);
}
private createEquipmentSlots(centerX: number, centerY: number) {
const slotBorder = 0xd4af37;
const slotBg = 0x3a2a2a;
const createSlot = (x: number, y: number, size: number, key: string) => {
const g = this.scene.add.graphics(); const g = this.scene.add.graphics();
g.lineStyle(2, 0x444444, 1);
g.strokeRect(-w / 2, -h / 2, w, h);
g.fillStyle(0x1a1a1a, 1);
g.fillRect(-w / 2 + 1, -h / 2 + 1, w - 2, h - 2);
const txt = this.scene.add.text(0, 0, label, { fontSize: "11px", color: "#666666", fontStyle: "bold" }).setOrigin(0.5); // Outer golden border
const container = this.scene.add.container(x, y, [g, txt]); g.lineStyle(2, slotBorder, 1);
g.strokeRect(-size / 2, -size / 2, size, size);
// Inner darker border
g.lineStyle(1, 0x8b7355, 1);
g.strokeRect(-size / 2 + 2, -size / 2 + 2, size - 4, size - 4);
// Background
g.fillStyle(slotBg, 1);
g.fillRect(-size / 2 + 3, -size / 2 + 3, size - 6, size - 6);
const container = this.scene.add.container(x, y, [g]);
this.equipmentSlots.set(key, container); this.equipmentSlots.set(key, container);
this.container.add(container); this.container.add(container);
}; };
createSlot(eqX, eqY - 140, 70, 70, "Head", "helmet"); // Helmet (top center)
createSlot(eqX, eqY - 20, 90, 130, "Body", "bodyArmour"); createSlot(centerX, centerY - 75, 46, "helmet");
createSlot(eqX, eqY + 80, 100, 36, "Belt", "belt");
createSlot(eqX - 140, eqY - 50, 90, 160, "Main Hand", "mainHand"); // Body armor (center)
createSlot(eqX + 140, eqY - 50, 90, 160, "Off Hand", "offHand"); createSlot(centerX, centerY - 10, 58, "bodyArmour");
createSlot(eqX - 80, eqY - 30, 54, 54, "Ring", "ringLeft");
createSlot(eqX + 80, eqY - 30, 54, 54, "Ring", "ringRight"); // Main hand (left)
createSlot(eqX - 100, eqY + 70, 70, 70, "Hands", "gloves"); createSlot(centerX - 92, centerY - 5, 46, "mainHand");
createSlot(eqX + 100, eqY + 70, 70, 70, "Boots", "boots");
// Off hand (right)
createSlot(centerX + 92, centerY - 5, 46, "offHand");
// Rings
createSlot(centerX - 46, centerY + 28, 38, "ringLeft");
createSlot(centerX + 46, centerY + 28, 38, "ringRight");
// Belt
createSlot(centerX, centerY + 52, 32, "belt");
// Boots (bottom)
createSlot(centerX, centerY + 125, 46, "boots");
} }
private createBackpackSection() { private createBackpackPanel() {
const bpX = 100; const panelX = 175;
const bpY = -150; const panelY = 40;
const rows = 8; const panelW = 240;
const cols = 5; const panelH = 360;
const bpSlotSize = 40;
const bpTitle = this.scene.add.text(bpX + (cols * 44) / 2 - 20, bpY - 40, "BACKPACK", { // Panel background
fontSize: "18px", const bg = this.scene.add.graphics();
color: "#d4af37", bg.fillStyle(0x2a1f2a, 0.9);
fontStyle: "bold" bg.fillRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH);
// Panel border
bg.lineStyle(2, 0x8b7355, 1);
bg.strokeRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH);
this.container.add(bg);
// Backpack title
const bpTitle = this.scene.add.text(panelX, panelY - panelH / 2 + 25, "BACKPACK", {
fontSize: "20px",
color: "#d4af37",
fontStyle: "bold",
fontFamily: "serif"
}).setOrigin(0.5); }).setOrigin(0.5);
this.container.add(bpTitle); this.container.add(bpTitle);
// Create backpack grid (4 columns x 6 rows)
const rows = 6;
const cols = 4;
const slotSize = 44;
const spacing = 6;
const gridW = cols * (slotSize + spacing) - spacing;
const startX = panelX - gridW / 2;
const startY = panelY - panelH / 2 + 55;
for (let r = 0; r < rows; r++) { for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) { for (let c = 0; c < cols; c++) {
const x = bpX + c * 44; const x = startX + c * (slotSize + spacing) + slotSize / 2;
const y = bpY + r * 44; const y = startY + r * (slotSize + spacing) + slotSize / 2;
const g = this.scene.add.graphics(); const g = this.scene.add.graphics();
g.lineStyle(1, 0x333333, 1);
g.strokeRect(-bpSlotSize / 2, -bpSlotSize / 2, bpSlotSize, bpSlotSize); // Golden border
g.fillStyle(0x0c0c0c, 1); g.lineStyle(2, 0xd4af37, 1);
g.fillRect(-bpSlotSize / 2 + 0.5, -bpSlotSize / 2 + 0.5, bpSlotSize - 1, bpSlotSize - 1); g.strokeRect(-slotSize / 2, -slotSize / 2, slotSize, slotSize);
// Inner border
g.lineStyle(1, 0x8b7355, 1);
g.strokeRect(-slotSize / 2 + 2, -slotSize / 2 + 2, slotSize - 4, slotSize - 4);
// Background
g.fillStyle(0x1a0f1a, 1);
g.fillRect(-slotSize / 2 + 3, -slotSize / 2 + 3, slotSize - 6, slotSize - 6);
const container = this.scene.add.container(x, y, [g]); const container = this.scene.add.container(x, y, [g]);
this.container.add(container); this.container.add(container);
@@ -86,31 +218,30 @@ export class InventoryOverlay extends OverlayComponent {
// Clear existing items from slots // Clear existing items from slots
this.backpackSlots.forEach(slot => { this.backpackSlots.forEach(slot => {
if (slot.list.length > 1) { // 0 is bg if (slot.list.length > 1) {
// Remove all children after bg slot.removeBetween(1, undefined, true);
slot.removeBetween(1, undefined, true); }
}
}); });
// Populate items // Populate items
player.inventory.items.forEach((item, index) => { player.inventory.items.forEach((item, index) => {
if (index >= this.backpackSlots.length) return; if (index >= this.backpackSlots.length) return;
const slot = this.backpackSlots[index]; const slot = this.backpackSlots[index];
const texture = item.textureKey; const texture = item.textureKey;
const frame = item.spriteIndex; const frame = item.spriteIndex;
const sprite = this.scene.add.sprite(0, 0, texture, frame); const sprite = this.scene.add.sprite(0, 0, texture, frame);
sprite.setScale(2); // 16x16 -> 32x32, fits in 40x40 slot sprite.setScale(2.2); // Scale to fit nicely in 44px slots
slot.add(sprite); slot.add(sprite);
// Add simple tooltip on hover (console log for now) or click // Add interactivity
slot.setInteractive(new Phaser.Geom.Rectangle(-20, -20, 40, 40), Phaser.Geom.Rectangle.Contains); slot.setInteractive(new Phaser.Geom.Rectangle(-22, -22, 44, 44), Phaser.Geom.Rectangle.Contains);
slot.on("pointerdown", () => { slot.on("pointerdown", () => {
console.log("Clicked item:", item); console.log("Clicked item:", item);
}); });
}); });
} }
} }