This commit is contained in:
2025-12-07 21:31:44 +01:00
parent 4a0ca267ea
commit 974141c08c
52 changed files with 2485 additions and 397 deletions

View File

@@ -18,6 +18,7 @@ class UIScene extends Phaser.Scene {
this.createStatusBars();
this.createInventoryBar();
this.createGoldDisplay();
this.createVirtualJoystick();
this.createClock();
// this.createDebugInfo();
this.createSettingsButton();
@@ -471,7 +472,20 @@ class UIScene extends Phaser.Scene {
if (!this.buildMenuContainer) {
this.createBuildMenuInfo();
}
this.buildMenuContainer.setVisible(isVisible);
if (isVisible) {
this.buildMenuContainer.setVisible(true);
this.buildMenuContainer.y = -100; // Start off-screen
this.tweens.add({
targets: this.buildMenuContainer,
y: 100, // Target pos
duration: 300,
ease: 'Back.easeOut'
});
} else {
// Slide out (optional) or just hide
this.buildMenuContainer.setVisible(false);
}
}
createBuildMenuInfo() {
@@ -778,4 +792,168 @@ class UIScene extends Phaser.Scene {
});
this.settingsContainer.add(hitArea);
}
updateQuestTracker(quest) {
if (!this.questContainer) {
this.createQuestTracker();
}
if (!quest) {
this.questContainer.setVisible(false);
return;
}
this.questContainer.setVisible(true);
this.questTitle.setText(quest.title.toUpperCase());
let objText = '';
quest.objectives.forEach(obj => {
const status = obj.done ? '✅' : '⬜';
let desc = '';
if (obj.type === 'collect') desc = `${obj.item}: ${obj.current}/${obj.amount}`;
else if (obj.type === 'action') desc = `${obj.action}: ${obj.current}/${obj.amount}`;
else if (obj.type === 'kill') desc = `Slay ${obj.target}: ${obj.current}/${obj.amount}`;
objText += `${status} ${desc}\n`;
});
this.questObjectives.setText(objText);
}
createQuestTracker() {
const x = this.width - 240;
const y = 20;
this.questContainer = this.add.container(x, y);
// BG
const bg = this.add.graphics();
bg.fillStyle(0x000000, 0.6);
bg.fillRect(0, 0, 220, 100);
bg.lineStyle(2, 0xffaa00, 0.8);
bg.strokeRect(0, 0, 220, 100);
this.questContainer.add(bg);
this.questTrackerBg = bg; // ref to resize later if needed
// Title Header
const header = this.add.text(10, 5, 'CURRENT QUEST', { fontSize: '10px', fill: '#aaaaaa' });
this.questContainer.add(header);
// Title
this.questTitle = this.add.text(10, 20, 'Quest Title', {
fontSize: '16px', fill: '#ffaa00', fontStyle: 'bold'
});
this.questContainer.add(this.questTitle);
// Objectives
this.questObjectives = this.add.text(10, 45, 'Objectives...', {
fontSize: '14px', fill: '#ffffff', lineSpacing: 5
});
this.questContainer.add(this.questObjectives);
}
createVirtualJoystick() {
const x = 120;
const y = this.height - 120;
// Warning: this.height might not be updated on resize? Use this.scale.height or just initial.
// UIScene is usually overlay, so simple coords ok. But resize needs handling.
const r = 60;
// Visuals
this.joyBase = this.add.circle(x, y, r, 0xffffff, 0.1).setScrollFactor(0).setDepth(2000).setInteractive();
this.joyStick = this.add.circle(x, y, r / 2, 0xffffff, 0.5).setScrollFactor(0).setDepth(2001);
this.virtualJoystick = { up: false, down: false, left: false, right: false };
this.joyDragging = false;
// Events
this.input.on('pointermove', (pointer) => {
if (!this.joyDragging) return;
this.updateJoystick(pointer.x, pointer.y, x, y, r);
});
this.input.on('pointerup', () => {
if (this.joyDragging) {
this.joyDragging = false;
this.joyStick.setPosition(x, y);
this.virtualJoystick = { up: false, down: false, left: false, right: false };
}
});
this.joyBase.on('pointerdown', (pointer) => {
this.joyDragging = true;
this.updateJoystick(pointer.x, pointer.y, x, y, r);
});
}
updateJoystick(px, py, cx, cy, r) {
const angle = Phaser.Math.Angle.Between(cx, cy, px, py);
const dist = Math.min(r, Phaser.Math.Distance.Between(cx, cy, px, py));
const sx = cx + Math.cos(angle) * dist;
const sy = cy + Math.sin(angle) * dist;
this.joyStick.setPosition(sx, sy);
// Normalize angle to degrees
let deg = Phaser.Math.RadToDeg(angle);
this.virtualJoystick = { up: false, down: false, left: false, right: false };
// Mapping to Isometric direction keys
// UP Key (Top-Left on screen) -> Angle -135 (-180 to -90)
// RIGHT Key (Top-Right on screen) -> Angle -45 (-90 to 0)
// DOWN Key (Bottom-Right on screen) -> Angle 45 (0 to 90)
// LEFT Key (Bottom-Left on screen) -> Angle 135 (90 to 180)
if (deg > -170 && deg <= -80) this.virtualJoystick.up = true; // Tuned slightly
else if (deg > -80 && deg <= 10) this.virtualJoystick.right = true;
else if (deg > 10 && deg <= 100) this.virtualJoystick.down = true;
else this.virtualJoystick.left = true;
}
showQuestDialog(quest, onAccept) {
const width = 400;
const height = 250;
const x = this.cameras.main.centerX;
const y = this.cameras.main.centerY;
const container = this.add.container(x, y);
container.setDepth(5000);
const bg = this.add.rectangle(0, 0, width, height, 0x222222, 0.95);
bg.setStrokeStyle(4, 0x444444);
const title = this.add.text(0, -90, quest.title.toUpperCase(), { fontSize: '24px', fontStyle: 'bold', color: '#ffcc00' }).setOrigin(0.5);
const desc = this.add.text(0, -30, quest.description, { fontSize: '16px', color: '#dddddd', align: 'center', wordWrap: { width: width - 60 } }).setOrigin(0.5);
let rText = "Reward: ";
if (quest.reward.gold) rText += `${quest.reward.gold} G `;
if (quest.reward.item) rText += `+ ${quest.reward.amount || 1} ${quest.reward.item}`;
const reward = this.add.text(0, 40, rText, { fontSize: '16px', color: '#00ff00', fontStyle: 'italic' }).setOrigin(0.5);
// Buttons
const btnAccept = this.add.rectangle(-70, 90, 120, 40, 0x228B22).setInteractive({ useHandCursor: true });
const txtAccept = this.add.text(-70, 90, 'ACCEPT', { fontSize: '18px', fontStyle: 'bold' }).setOrigin(0.5);
const btnClose = this.add.rectangle(70, 90, 120, 40, 0x8B0000).setInteractive({ useHandCursor: true });
const txtClose = this.add.text(70, 90, 'DECLINE', { fontSize: '18px', fontStyle: 'bold' }).setOrigin(0.5);
btnAccept.on('pointerdown', () => {
onAccept();
container.destroy();
});
btnClose.on('pointerdown', () => {
container.destroy();
});
container.add([bg, title, desc, reward, btnAccept, txtAccept, btnClose, txtClose]);
// Appear anim
container.setScale(0);
this.tweens.add({ targets: container, scale: 1, duration: 200, ease: 'Back.out' });
}
}