Virtue-Slots/objects/MatchBanner.js

186 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export class MatchBanner {
play(scene, label, onComplete) {
const cx = 800;
const cy = 450;
// Dark overlay behind everything
const overlay = scene.add.graphics();
overlay.fillStyle(0x000000, 0.65);
overlay.fillRect(0, 0, 1600, 900);
overlay.setAlpha(0).setDepth(10);
// Expanding burst ring from center
const burst = scene.add.graphics();
burst.lineStyle(10, 0xffd700, 1);
burst.strokeCircle(0, 0, 50);
burst.setPosition(cx, cy).setDepth(11);
scene.tweens.add({
targets: burst,
scaleX: 18, scaleY: 18,
alpha: 0,
duration: 650,
ease: 'Cubic.easeOut',
onComplete: () => burst.destroy()
});
// Main banner container — starts tiny, punches in
const container = scene.add.container(cx, cy).setScale(0.01).setDepth(12);
const PW = 1060, PH = 260, PR = 22;
// Panel background
const panel = scene.add.graphics();
panel.fillStyle(0x0d0520, 0.97);
panel.fillRoundedRect(-PW / 2, -PH / 2, PW, PH, PR);
// Sharp gold inner border
panel.lineStyle(5, 0xffd700, 1);
panel.strokeRoundedRect(-PW / 2, -PH / 2, PW, PH, PR);
// Soft outer glow border
panel.lineStyle(16, 0xffd700, 0.18);
panel.strokeRoundedRect(-PW / 2 - 9, -PH / 2 - 9, PW + 18, PH + 18, PR + 9);
// Horizontal copper divider
const divider = scene.add.graphics();
divider.lineStyle(2, 0xc8a87e, 0.55);
divider.beginPath();
divider.moveTo(-430, -8);
divider.lineTo(430, -8);
divider.strokePath();
// Corner cross ornaments
const cornerPositions = [
[-PW / 2 + 30, -PH / 2 + 24],
[ PW / 2 - 30, -PH / 2 + 24],
[-PW / 2 + 30, PH / 2 - 24],
[ PW / 2 - 30, PH / 2 - 24],
];
const cornerCrosses = cornerPositions.map(([ox, oy]) =>
scene.add.text(ox, oy, '✝', {
fontSize: '22px',
fontFamily: 'Georgia, serif',
color: '#c8a87e',
}).setOrigin(0.5, 0.5).setAlpha(0.65)
);
// "M A T C H" header
const matchTxt = scene.add.text(0, -72, 'M A T C H', {
fontSize: '36px',
fontFamily: 'Georgia, serif',
color: '#c8a87e',
stroke: '#2a0a00',
strokeThickness: 2,
}).setOrigin(0.5, 0.5);
// "3× {LABEL}" main text
const mainTxt = scene.add.text(0, 58, `3\u00D7 ${label.toUpperCase()}`, {
fontSize: '88px',
fontFamily: 'Georgia, serif',
color: '#ffd700',
stroke: '#2a0a00',
strokeThickness: 7,
shadow: { offsetX: 0, offsetY: 0, color: '#ffd700', blur: 28, fill: true },
}).setOrigin(0.5, 0.5);
container.add([panel, divider, ...cornerCrosses, matchTxt, mainTxt]);
// Sparkle particles burst outward
for (let i = 0; i < 30; i++) {
const angle = (i / 30) * Math.PI * 2 + Phaser.Math.FloatBetween(-0.15, 0.15);
const dist = Phaser.Math.Between(100, 420);
const size = Phaser.Math.Between(16, 48);
const glyph = ['✦', '★', '✝', '✦', '★'][Math.floor(Math.random() * 5)];
const sparkle = scene.add.text(
cx + Math.cos(angle) * 15,
cy + Math.sin(angle) * 15,
glyph,
{ fontSize: `${size}px`, fontFamily: 'Georgia, serif', color: '#ffd700' }
).setOrigin(0.5, 0.5).setAlpha(0).setDepth(13);
scene.tweens.add({
targets: sparkle,
x: cx + Math.cos(angle) * dist,
y: cy + Math.sin(angle) * dist,
alpha: { from: 0, to: 1 },
scale: { from: 0.1, to: 1 },
duration: Phaser.Math.Between(280, 650),
delay: Phaser.Math.Between(40, 320),
ease: 'Cubic.easeOut',
onComplete: () => {
scene.tweens.add({
targets: sparkle,
alpha: 0,
scale: 0.4,
duration: Phaser.Math.Between(350, 800),
delay: Phaser.Math.Between(150, 500),
ease: 'Cubic.easeIn',
onComplete: () => sparkle.destroy(),
});
},
});
}
// Fade in overlay
scene.tweens.add({
targets: overlay,
alpha: 1,
duration: 140,
});
// Punch in the banner with elastic overshoot
scene.tweens.add({
targets: container,
scale: 1,
duration: 520,
ease: 'Back.easeOut',
easeParams: [4],
onComplete: () => {
// Scale pulse ×3
scene.tweens.add({
targets: container,
scale: 1.035,
duration: 200,
yoyo: true,
repeat: 2,
ease: 'Sine.easeInOut',
onComplete: () => {
// Gold shimmer flicker on main text
scene.tweens.add({
targets: mainTxt,
alpha: 0.55,
duration: 90,
yoyo: true,
repeat: 4,
ease: 'Linear',
onComplete: () => {
// Hold, then zoom-fade out
scene.time.delayedCall(650, () => {
scene.tweens.add({
targets: container,
scale: 1.14,
alpha: 0,
duration: 420,
ease: 'Cubic.easeIn',
onComplete: () => container.destroy(),
});
scene.tweens.add({
targets: overlay,
alpha: 0,
duration: 420,
ease: 'Cubic.easeIn',
onComplete: () => {
overlay.destroy();
if (onComplete) onComplete();
},
});
});
},
});
},
});
},
});
}
}