This commit is contained in:
2025-12-13 01:29:24 +01:00
parent f6450cd3b8
commit c618f3d7fa
13 changed files with 1195 additions and 72 deletions

View File

@@ -283,42 +283,53 @@ class AccessibilitySystem {
// EPILEPSY WARNING
showEpilepsyWarning(onContinue) {
const warning = this.scene.add.container(
this.scene.cameras.main.centerX,
this.scene.cameras.main.centerY
// Get UIScene for proper positioning
const uiScene = this.scene.scene.get('UIScene') || this.scene;
const warning = uiScene.add.container(
uiScene.scale.width / 2,
uiScene.scale.height / 2
);
warning.setDepth(10000);
warning.setDepth(99999); // ALWAYS ON TOP
warning.setScrollFactor(0);
const bg = this.scene.add.rectangle(0, 0, 600, 400, 0x000000, 0.95);
// Dark background overlay
const bg = uiScene.add.rectangle(0, 0, 700, 500, 0x000000, 0.98);
bg.setStrokeStyle(4, 0xff0000);
const title = this.scene.add.text(0, -150, '⚠️ EPILEPSY WARNING', {
fontSize: '32px',
const title = uiScene.add.text(0, -180, '⚠️ EPILEPSY WARNING', {
fontSize: '36px',
color: '#ff0000',
fontStyle: 'bold'
fontStyle: 'bold',
stroke: '#000000',
strokeThickness: 4
}).setOrigin(0.5);
const text = this.scene.add.text(0, -50,
const text = uiScene.add.text(0, -60,
'This game contains flashing lights\n' +
'that may trigger seizures in people with\n' +
'photosensitive epilepsy.\n\n' +
'Player discretion is advised.',
{
fontSize: '18px',
fontSize: '20px',
color: '#ffffff',
align: 'center',
wordWrap: { width: 500 }
wordWrap: { width: 600 },
lineSpacing: 8
}
).setOrigin(0.5);
const enableBtn = this.scene.add.text(0, 100, '[ ENABLE PROTECTION ]', {
fontSize: '20px',
const enableBtn = uiScene.add.text(0, 120, '[ ENABLE PROTECTION ]', {
fontSize: '24px',
color: '#00ff00',
backgroundColor: '#003300',
padding: { x: 20, y: 10 }
padding: { x: 30, y: 15 },
fontStyle: 'bold'
}).setOrigin(0.5);
enableBtn.setInteractive({ useHandCursor: true });
enableBtn.on('pointerover', () => enableBtn.setScale(1.1));
enableBtn.on('pointerout', () => enableBtn.setScale(1.0));
enableBtn.on('pointerdown', () => {
this.settings.photosensitivity = true;
this.applySettings();
@@ -327,12 +338,16 @@ class AccessibilitySystem {
if (onContinue) onContinue();
});
const continueBtn = this.scene.add.text(0, 150, '[ CONTINUE WITHOUT ]', {
fontSize: '16px',
color: '#888888'
const continueBtn = uiScene.add.text(0, 180, '[ CONTINUE WITHOUT ]', {
fontSize: '18px',
color: '#888888',
backgroundColor: '#222222',
padding: { x: 20, y: 10 }
}).setOrigin(0.5);
continueBtn.setInteractive({ useHandCursor: true });
continueBtn.on('pointerover', () => continueBtn.setScale(1.1));
continueBtn.on('pointerout', () => continueBtn.setScale(1.0));
continueBtn.on('pointerdown', () => {
warning.destroy();
if (onContinue) onContinue();

View File

@@ -0,0 +1,359 @@
/**
* CENTRAL POPUP SYSTEM
* Displays important messages, quests, and dialogs in center of screen
* Always appears in front of player for easy reading
*/
class CentralPopupSystem {
constructor(scene) {
this.scene = scene;
this.enabled = true;
// Current popup
this.currentPopup = null;
this.popupQueue = [];
this.isShowing = false;
// Settings
this.settings = {
enabled: true,
autoClose: true,
autoCloseDelay: 5000, // 5 seconds
pauseGameOnPopup: true,
soundOnPopup: true
};
this.loadSettings();
console.log('✅ Central Popup System initialized');
}
/**
* Show popup in center of screen
*/
showPopup(config) {
const popup = {
title: config.title || 'Notification',
message: config.message || '',
type: config.type || 'info', // info, quest, warning, success, story
icon: config.icon || '📋',
buttons: config.buttons || [{ text: 'OK', action: 'close' }],
image: config.image || null,
autoClose: config.autoClose !== undefined ? config.autoClose : this.settings.autoClose,
onClose: config.onClose || null,
priority: config.priority || 'normal' // low, normal, high, critical
};
// Add to queue
this.popupQueue.push(popup);
// Show if not already showing
if (!this.isShowing) {
this.displayNextPopup();
}
}
/**
* Display next popup from queue
*/
displayNextPopup() {
if (this.popupQueue.length === 0) {
this.isShowing = false;
return;
}
this.isShowing = true;
const popup = this.popupQueue.shift();
// Get UIScene
const uiScene = this.scene.scene.get('UIScene');
if (!uiScene) return;
// Pause game if needed
if (this.settings.pauseGameOnPopup) {
this.scene.physics.pause();
}
// Create popup container
const centerX = uiScene.scale.width / 2;
const centerY = uiScene.scale.height / 2;
this.currentPopup = uiScene.add.container(centerX, centerY);
this.currentPopup.setDepth(10000); // Always on top
this.currentPopup.setScrollFactor(0);
// Popup size based on type
const width = popup.type === 'story' ? 600 : 500;
const height = popup.type === 'story' ? 400 : 300;
// Background overlay (darken screen)
const overlay = uiScene.add.rectangle(0, 0, uiScene.scale.width * 2, uiScene.scale.height * 2, 0x000000, 0.7);
overlay.setOrigin(0.5);
this.currentPopup.add(overlay);
// Main popup background
const bg = uiScene.add.graphics();
// Color based on type
let bgColor = 0x2a2a3e;
let borderColor = 0x4e4e6e;
if (popup.type === 'quest') {
bgColor = 0x3a2a1e;
borderColor = 0xFFD700;
} else if (popup.type === 'warning') {
bgColor = 0x3e2a2a;
borderColor = 0xff4444;
} else if (popup.type === 'success') {
bgColor = 0x2a3e2a;
borderColor = 0x44ff44;
} else if (popup.type === 'story') {
bgColor = 0x1a1a2e;
borderColor = 0x8888ff;
}
// Draw background with rounded corners
bg.fillStyle(bgColor, 0.95);
bg.fillRoundedRect(-width / 2, -height / 2, width, height, 16);
bg.lineStyle(4, borderColor, 1);
bg.strokeRoundedRect(-width / 2, -height / 2, width, height, 16);
this.currentPopup.add(bg);
// Icon
const iconText = uiScene.add.text(-width / 2 + 30, -height / 2 + 30, popup.icon, {
fontSize: '48px'
});
this.currentPopup.add(iconText);
// Title
const title = uiScene.add.text(0, -height / 2 + 50, popup.title, {
fontSize: '28px',
fontFamily: 'Arial',
fill: '#ffffff',
fontStyle: 'bold',
align: 'center'
}).setOrigin(0.5);
this.currentPopup.add(title);
// Separator line
const separator = uiScene.add.graphics();
separator.lineStyle(2, borderColor, 0.5);
separator.lineBetween(-width / 2 + 20, -height / 2 + 90, width / 2 - 20, -height / 2 + 90);
this.currentPopup.add(separator);
// Message
const message = uiScene.add.text(0, -height / 2 + 150, popup.message, {
fontSize: '18px',
fontFamily: 'Arial',
fill: '#dddddd',
align: 'center',
wordWrap: { width: width - 80 }
}).setOrigin(0.5, 0);
this.currentPopup.add(message);
// Image (if provided)
if (popup.image) {
const img = uiScene.add.image(0, -height / 2 + 120, popup.image);
img.setScale(0.5);
this.currentPopup.add(img);
}
// Buttons
const buttonY = height / 2 - 50;
const buttonSpacing = 150;
const buttonStartX = -(popup.buttons.length - 1) * buttonSpacing / 2;
popup.buttons.forEach((btn, index) => {
const btnX = buttonStartX + index * buttonSpacing;
// Button background
const btnBg = uiScene.add.graphics();
btnBg.fillStyle(0x4a4a6e, 1);
btnBg.fillRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
btnBg.lineStyle(2, borderColor, 1);
btnBg.strokeRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
btnBg.setInteractive(
new Phaser.Geom.Rectangle(btnX - 60, buttonY - 20, 120, 40),
Phaser.Geom.Rectangle.Contains
);
// Hover effect
btnBg.on('pointerover', () => {
btnBg.clear();
btnBg.fillStyle(0x6a6a8e, 1);
btnBg.fillRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
btnBg.lineStyle(2, borderColor, 1);
btnBg.strokeRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
});
btnBg.on('pointerout', () => {
btnBg.clear();
btnBg.fillStyle(0x4a4a6e, 1);
btnBg.fillRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
btnBg.lineStyle(2, borderColor, 1);
btnBg.strokeRoundedRect(btnX - 60, buttonY - 20, 120, 40, 8);
});
// Click handler
btnBg.on('pointerdown', () => {
if (btn.action === 'close') {
this.closePopup(popup);
} else if (btn.callback) {
btn.callback();
this.closePopup(popup);
}
});
this.currentPopup.add(btnBg);
// Button text
const btnText = uiScene.add.text(btnX, buttonY, btn.text, {
fontSize: '18px',
fontFamily: 'Arial',
fill: '#ffffff',
fontStyle: 'bold'
}).setOrigin(0.5);
this.currentPopup.add(btnText);
});
// Auto-close timer
if (popup.autoClose && this.settings.autoClose) {
uiScene.time.delayedCall(this.settings.autoCloseDelay, () => {
this.closePopup(popup);
});
}
// Play sound
if (this.settings.soundOnPopup && this.scene.soundManager) {
this.scene.soundManager.beepPickup();
}
// Animate in
this.currentPopup.setScale(0.8);
this.currentPopup.setAlpha(0);
uiScene.tweens.add({
targets: this.currentPopup,
scale: 1,
alpha: 1,
duration: 300,
ease: 'Back.easeOut'
});
console.log(`📋 Popup shown: ${popup.title}`);
}
/**
* Close current popup
*/
closePopup(popup) {
if (!this.currentPopup) return;
const uiScene = this.scene.scene.get('UIScene');
if (!uiScene) return;
// Animate out
uiScene.tweens.add({
targets: this.currentPopup,
scale: 0.8,
alpha: 0,
duration: 200,
ease: 'Power2',
onComplete: () => {
this.currentPopup.destroy();
this.currentPopup = null;
// Resume game
if (this.settings.pauseGameOnPopup) {
this.scene.physics.resume();
}
// Call onClose callback
if (popup.onClose) {
popup.onClose();
}
// Show next popup
this.displayNextPopup();
}
});
}
/**
* Show quest popup
*/
showQuest(title, description, objectives) {
this.showPopup({
title: title,
message: description + '\n\nObjectives:\n' + objectives.map((obj, i) => `${i + 1}. ${obj}`).join('\n'),
type: 'quest',
icon: '📜',
buttons: [
{ text: 'Accept', action: 'close' },
{ text: 'Decline', action: 'close' }
],
autoClose: false
});
}
/**
* Show story popup
*/
showStory(title, text, image = null) {
this.showPopup({
title: title,
message: text,
type: 'story',
icon: '📖',
image: image,
buttons: [{ text: 'Continue', action: 'close' }],
autoClose: false
});
}
/**
* Show notification
*/
showNotification(message, type = 'info') {
const icons = {
'info': '',
'success': '✅',
'warning': '⚠️',
'error': '❌'
};
this.showPopup({
title: type.charAt(0).toUpperCase() + type.slice(1),
message: message,
type: type,
icon: icons[type] || '',
buttons: [{ text: 'OK', action: 'close' }],
autoClose: true
});
}
/**
* Save settings
*/
saveSettings() {
localStorage.setItem('novafarma_popup_settings', JSON.stringify(this.settings));
}
/**
* Load settings
*/
loadSettings() {
const saved = localStorage.getItem('novafarma_popup_settings');
if (saved) {
this.settings = { ...this.settings, ...JSON.parse(saved) };
}
}
/**
* Destroy system
*/
destroy() {
if (this.currentPopup) {
this.currentPopup.destroy();
}
this.popupQueue = [];
console.log('📋 Central Popup System destroyed');
}
}