iPuzzle/js/scenes/MainMenuScene.js

170 lines
5.2 KiB
JavaScript

/* global Phaser */
class MainMenuScene extends Phaser.Scene {
constructor() {
super({ key: 'MainMenuScene' });
}
create() {
const { width, height } = this.sys.game.config;
// Background
const bg = this.add.graphics();
bg.fillStyle(0x1a1a2e, 1);
bg.fillRect(0, 0, width, height);
bg.fillStyle(0x16213e, 1);
bg.fillRect(0, height * 0.5, width, height * 0.5);
// Title
this.add.text(width / 2, height * 0.22, 'iPuzzle', {
fontFamily: 'Georgia, serif',
fontSize: Math.round(height * 0.083) + 'px',
color: '#e0e0ff',
stroke: '#4444aa',
strokeThickness: 6
}).setOrigin(0.5);
this.add.text(width / 2, height * 0.36, 'Put the pieces together', {
fontFamily: 'Georgia, serif',
fontSize: Math.round(height * 0.026) + 'px',
color: '#8888bb'
}).setOrigin(0.5);
this._buildDomUI();
}
// ─── DOM UI ──────────────────────────────────────────────────────────
_buildDomUI() {
this._uiLayer = document.createElement('div');
Object.assign(this._uiLayer.style, {
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '100vw',
height: '56.25vw',
maxHeight: '100vh',
maxWidth: '177.78vh',
pointerEvents: 'none',
zIndex: '10',
});
document.body.appendChild(this._uiLayer);
const newBtn = this._makeDomBtn('New Puzzle', '#1a3366', '#2255aa', '#66aaff', () => {
this.scene.start('NewPuzzleScene');
});
Object.assign(newBtn.style, {
top: '55%',
left: '50%',
transform: 'translateX(-50%)',
width: '18%',
});
this._uiLayer.appendChild(newBtn);
const joinBtn = this._makeDomBtn('Join Puzzle', '#1a3322', '#225533', '#44aa66', () => {
this._showComingSoon();
});
Object.assign(joinBtn.style, {
top: '70%',
left: '50%',
transform: 'translateX(-50%)',
width: '18%',
});
this._uiLayer.appendChild(joinBtn);
// Version credit — bottom right
const credit = document.createElement('div');
Object.assign(credit.style, {
position: 'absolute',
bottom: '1%',
right: '0.6%',
color: '#333355',
fontSize: '1.2vmin',
fontFamily: 'Arial, sans-serif',
});
credit.textContent = 'iPuzzle';
this._uiLayer.appendChild(credit);
this.events.once('shutdown', () => this._destroyDomUI());
}
_showComingSoon() {
if (this._comingSoonEl) return;
const overlay = document.createElement('div');
Object.assign(overlay.style, {
position: 'absolute',
inset: '0',
background: 'rgba(0,0,0,0.6)',
pointerEvents: 'auto',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
});
const panel = document.createElement('div');
Object.assign(panel.style, {
background: '#1a1a3e',
border: '2px solid #4444aa',
borderRadius: '6px',
padding: '3vmin 4vmin',
textAlign: 'center',
display: 'flex',
flexDirection:'column',
gap: '1.2vmin',
});
const msg = document.createElement('div');
Object.assign(msg.style, { color: '#aaccff', fontSize: '2.4vmin', fontFamily: 'Arial, sans-serif' });
msg.textContent = 'Multiplayer Coming Soon!';
const sub = document.createElement('div');
Object.assign(sub.style, { color: '#667799', fontSize: '1.5vmin', fontFamily: 'Arial, sans-serif' });
sub.textContent = 'Click anywhere to dismiss';
panel.appendChild(msg);
panel.appendChild(sub);
overlay.appendChild(panel);
this._uiLayer.appendChild(overlay);
this._comingSoonEl = overlay;
overlay.addEventListener('click', () => {
overlay.remove();
this._comingSoonEl = null;
});
}
_makeDomBtn(label, bgNormal, bgHover, borderColor, onClick) {
const btn = document.createElement('button');
btn.textContent = label;
Object.assign(btn.style, {
position: 'absolute',
padding: '1.2vmin 2vmin',
background: bgNormal,
color: '#ddeeff',
border: `2px solid ${borderColor}`,
borderRadius: '4px',
fontSize: '2vmin',
fontFamily: 'Arial, sans-serif',
cursor: 'pointer',
pointerEvents: 'auto',
whiteSpace: 'nowrap',
textAlign: 'center',
});
btn.addEventListener('mouseenter', () => { btn.style.background = bgHover; });
btn.addEventListener('mouseleave', () => { btn.style.background = bgNormal; });
btn.addEventListener('mousedown', () => { btn.style.transform = (btn.style.transform || '') + ' scale(0.97)'; });
btn.addEventListener('mouseup', () => { btn.style.transform = btn.style.transform.replace(' scale(0.97)', ''); });
btn.addEventListener('click', onClick);
return btn;
}
_destroyDomUI() {
if (this._uiLayer && this._uiLayer.parentNode) {
this._uiLayer.parentNode.removeChild(this._uiLayer);
}
this._uiLayer = null;
}
}