feat: implement Deck Builder and Collection tutorial phases
- Added DECK_BUILDER_INTRO (7) and COLLECTION_INTRO (8) stages to TutorialManager.STAGES - Implemented 3-phase Deck Builder tutorial in DeckBuilderScene with dimming overlays, pulsing arrows, and step-by-step guidance for deck management - Added full-screen tutorial flow in MainMenuScene for both Deck Builder intro (with interactive button override) and Collection intro (highlighting save/restore buttons) - Integrated tutorial progression logic to advance users through remaining stages after Fusion Intro
This commit is contained in:
parent
0ea053dc44
commit
307704b90d
|
|
@ -1,7 +1,7 @@
|
|||
import { SaveManager } from './SaveManager.js';
|
||||
|
||||
export class TutorialManager {
|
||||
static STAGES = { CAMPAIGN_INTRO: 1, CAMPAIGN_SELECT: 2, BATTLE_INTRO: 3, BATTLEFIELD_GUIDE: 4, STORE_INTRO: 5, FUSION_INTRO: 6 };
|
||||
static STAGES = { CAMPAIGN_INTRO: 1, CAMPAIGN_SELECT: 2, BATTLE_INTRO: 3, BATTLEFIELD_GUIDE: 4, STORE_INTRO: 5, FUSION_INTRO: 6, DECK_BUILDER_INTRO: 7, COLLECTION_INTRO: 8 };
|
||||
|
||||
static isStageComplete(save, stageNum) {
|
||||
return save.tutorialProgress?.completedStages?.includes(stageNum) ?? false;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { DeckManager } from '../managers/DeckManager.js';
|
||||
import { SaveManager } from '../managers/SaveManager.js';
|
||||
import { CardObject } from '../objects/CardObject.js';
|
||||
import { TutorialManager } from '../managers/TutorialManager.js';
|
||||
|
||||
export class DeckBuilderScene extends Phaser.Scene {
|
||||
constructor() { super('DeckBuilderScene'); }
|
||||
|
|
@ -77,6 +78,9 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
this._renderDeckPanel();
|
||||
this._makeButtons();
|
||||
this._setupScrolling();
|
||||
|
||||
this._tutorialElements = [];
|
||||
this._showTutorial();
|
||||
}
|
||||
|
||||
_rebuildUsedCounts() {
|
||||
|
|
@ -627,4 +631,222 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
}).setOrigin(0.5);
|
||||
this.time.delayedCall(2000, () => { if (t.scene) t.destroy(); });
|
||||
}
|
||||
|
||||
_showTutorial() {
|
||||
const save = this.registry.get('save');
|
||||
if (
|
||||
TutorialManager.isStageComplete(save, TutorialManager.STAGES.FUSION_INTRO) &&
|
||||
!TutorialManager.isStageComplete(save, TutorialManager.STAGES.DECK_BUILDER_INTRO)
|
||||
) {
|
||||
this._showDeckBuilderPhase1();
|
||||
}
|
||||
}
|
||||
|
||||
_clearTutorialElements() {
|
||||
for (const el of this._tutorialElements) {
|
||||
if (el && el.scene) el.destroy();
|
||||
}
|
||||
this._tutorialElements = [];
|
||||
}
|
||||
|
||||
_showDeckBuilderPhase1() {
|
||||
this._clearTutorialElements();
|
||||
const { width, height } = this.scale;
|
||||
const DEPTH = 500;
|
||||
const PANEL_X = 1340;
|
||||
const panelCX = PANEL_X + 540 / 2; // 1610
|
||||
|
||||
const gridCX = PANEL_X / 2; // ~670 — center of the dimmed left area
|
||||
|
||||
// Dim the left card grid area
|
||||
const dimLeft = this.add.rectangle(gridCX, height / 2, PANEL_X, height, 0x000000, 0.78)
|
||||
.setDepth(DEPTH);
|
||||
|
||||
// Instructional text overlaid on the dimmed left area
|
||||
const text = this.add.text(gridCX, 490, [
|
||||
'This is your Current Deck panel.',
|
||||
'Here you can see your commander and',
|
||||
'all assault cards in your deck.',
|
||||
'Use the ( \u2212 ) buttons to remove cards.'
|
||||
].join('\n'), {
|
||||
fontSize: '22px',
|
||||
color: '#ffffff',
|
||||
fontFamily: 'Audiowide',
|
||||
align: 'center',
|
||||
lineSpacing: 8,
|
||||
wordWrap: { width: 600 }
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
// Continue button
|
||||
const contBg = this.add.rectangle(gridCX, 640, 200, 46, 0x1a3a5c)
|
||||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(2, 0x4488ff)
|
||||
.setDepth(DEPTH + 1);
|
||||
const contTxt = this.add.text(gridCX, 640, 'Continue', {
|
||||
fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: contBg,
|
||||
alpha: { from: 0.7, to: 1 },
|
||||
duration: 800,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
// Pulsing arrow just left of the Current Deck panel, pointing right
|
||||
const arrow = this.add.text(PANEL_X - 28, height / 2, '\u25BA', {
|
||||
fontSize: '42px', color: '#ffd700'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: arrow,
|
||||
x: PANEL_X - 14,
|
||||
duration: 600,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
contBg.on('pointerdown', () => this._showDeckBuilderPhase2());
|
||||
|
||||
this._tutorialElements = [dimLeft, text, contBg, contTxt, arrow];
|
||||
}
|
||||
|
||||
_showDeckBuilderPhase2() {
|
||||
this._clearTutorialElements();
|
||||
const { width, height } = this.scale;
|
||||
const DEPTH = 500;
|
||||
const PANEL_X = 1340;
|
||||
const panelCX = PANEL_X + 540 / 2; // 1610 — center of the dimmed right area
|
||||
const gridCX = PANEL_X / 2; // ~670
|
||||
|
||||
// Dim the right deck panel area
|
||||
const rightW = width - PANEL_X;
|
||||
const dimRight = this.add.rectangle(PANEL_X + rightW / 2, height / 2, rightW, height, 0x000000, 0.78)
|
||||
.setDepth(DEPTH);
|
||||
// Dim the top header
|
||||
const dimTop = this.add.rectangle(gridCX, this.SCROLL_TOP / 2, PANEL_X, this.SCROLL_TOP, 0x000000, 0.78)
|
||||
.setDepth(DEPTH);
|
||||
|
||||
// Instructional text overlaid on the dimmed right area
|
||||
const text = this.add.text(panelCX, 490, [
|
||||
'This is your card collection.',
|
||||
'Cards you don\'t own are grayed out.',
|
||||
'Use the ( + ADD ) button to add',
|
||||
'a card to your deck.'
|
||||
].join('\n'), {
|
||||
fontSize: '22px',
|
||||
color: '#ffffff',
|
||||
fontFamily: 'Audiowide',
|
||||
align: 'center',
|
||||
lineSpacing: 8,
|
||||
wordWrap: { width: 500 }
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
// Continue button
|
||||
const contBg = this.add.rectangle(panelCX, 640, 200, 46, 0x1a3a5c)
|
||||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(2, 0x4488ff)
|
||||
.setDepth(DEPTH + 1);
|
||||
const contTxt = this.add.text(panelCX, 640, 'Continue', {
|
||||
fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: contBg,
|
||||
alpha: { from: 0.7, to: 1 },
|
||||
duration: 800,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
// Pulsing arrow just right of the card collection boundary, pointing left
|
||||
const arrow = this.add.text(PANEL_X + 28, height / 2, '\u25C4', {
|
||||
fontSize: '42px', color: '#ffd700'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: arrow,
|
||||
x: PANEL_X + 14,
|
||||
duration: 600,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
contBg.on('pointerdown', () => this._showDeckBuilderPhase3());
|
||||
|
||||
this._tutorialElements = [dimRight, dimTop, text, contBg, contTxt, arrow];
|
||||
}
|
||||
|
||||
_showDeckBuilderPhase3() {
|
||||
this._clearTutorialElements();
|
||||
const { width, height } = this.scale;
|
||||
const DEPTH = 500;
|
||||
const PANEL_X = 1340;
|
||||
const PANEL_W = 540;
|
||||
const panelCX = PANEL_X + PANEL_W / 2; // 1610
|
||||
const saveBtnY = height - 60; // 1020
|
||||
|
||||
// Button highlight area: Save (cx=1500, w=190) to Clear (cx=1720, w=190)
|
||||
const btnAreaLeft = 1500 - 95 - 10; // 1395
|
||||
const btnAreaRight = 1720 + 95 + 10; // 1825
|
||||
const btnAreaTop = saveBtnY - 28; // 992
|
||||
const btnAreaBottom = saveBtnY + 28; // 1048
|
||||
|
||||
// Targeted dimming — four rects around the highlight area
|
||||
const dimTop = this.add.rectangle(width / 2, btnAreaTop / 2, width, btnAreaTop, 0x000000, 0.78)
|
||||
.setDepth(DEPTH);
|
||||
const dimBottom = this.add.rectangle(width / 2, (btnAreaBottom + height) / 2, width, height - btnAreaBottom, 0x000000, 0.78)
|
||||
.setDepth(DEPTH);
|
||||
const dimLeft = this.add.rectangle(btnAreaLeft / 2, saveBtnY, btnAreaLeft, btnAreaBottom - btnAreaTop, 0x000000, 0.78)
|
||||
.setDepth(DEPTH);
|
||||
const rightW = width - btnAreaRight;
|
||||
const dimRight = this.add.rectangle(btnAreaRight + rightW / 2, saveBtnY, rightW, btnAreaBottom - btnAreaTop, 0x000000, 0.78)
|
||||
.setDepth(DEPTH);
|
||||
|
||||
// Instructional text above the button area (rendered above the dim due to higher depth)
|
||||
const text = this.add.text(panelCX, 860, [
|
||||
'Use Save Deck to keep your changes,',
|
||||
'and Clear Deck to start over.',
|
||||
'Make sure to save before leaving!'
|
||||
].join('\n'), {
|
||||
fontSize: '22px',
|
||||
color: '#ffffff',
|
||||
fontFamily: 'Audiowide',
|
||||
align: 'center',
|
||||
lineSpacing: 8,
|
||||
wordWrap: { width: 520 }
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
// Continue button — completes the tutorial
|
||||
const contBg = this.add.rectangle(panelCX, 960, 200, 46, 0x1a3a5c)
|
||||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(2, 0x4488ff)
|
||||
.setDepth(DEPTH + 1);
|
||||
const contTxt = this.add.text(panelCX, 960, 'Continue', {
|
||||
fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: contBg,
|
||||
alpha: { from: 0.7, to: 1 },
|
||||
duration: 800,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
contBg.on('pointerdown', () => {
|
||||
const save = this.registry.get('save');
|
||||
TutorialManager.completeStage(save, TutorialManager.STAGES.DECK_BUILDER_INTRO);
|
||||
this.registry.set('save', save);
|
||||
this._clearTutorialElements();
|
||||
});
|
||||
|
||||
this._tutorialElements = [dimTop, dimBottom, dimLeft, dimRight, text, contBg, contTxt];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,16 @@ export class MainMenuScene extends Phaser.Scene {
|
|||
TutorialManager.hasFusibleCards(save)
|
||||
) {
|
||||
this._showFusionIntroTutorial(save);
|
||||
} else if (
|
||||
TutorialManager.isStageComplete(save, TutorialManager.STAGES.FUSION_INTRO) &&
|
||||
!TutorialManager.isStageComplete(save, TutorialManager.STAGES.DECK_BUILDER_INTRO)
|
||||
) {
|
||||
this._showDeckBuilderIntroTutorial(save);
|
||||
} else if (
|
||||
TutorialManager.isStageComplete(save, TutorialManager.STAGES.DECK_BUILDER_INTRO) &&
|
||||
!TutorialManager.isStageComplete(save, TutorialManager.STAGES.COLLECTION_INTRO)
|
||||
) {
|
||||
this._showCollectionIntroTutorial(save);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -470,6 +480,231 @@ export class MainMenuScene extends Phaser.Scene {
|
|||
});
|
||||
}
|
||||
|
||||
_showCollectionIntroTutorial(save) {
|
||||
this._showCollectionPhase1();
|
||||
}
|
||||
|
||||
_showCollectionPhase1() {
|
||||
const { width, height } = this.scale;
|
||||
const DEPTH = 1000;
|
||||
|
||||
// Collection is index 3 (startY=310, spacing=90 → y=580)
|
||||
const btnX = width / 2;
|
||||
const btnY = 310 + 3 * 90; // 580
|
||||
const btnHalfW = 200;
|
||||
|
||||
// Full-screen overlay — blocks all clicks including the Collection button
|
||||
const overlay = this.add.rectangle(width / 2, height / 2, width, height, 0x000000, 0.78)
|
||||
.setDepth(DEPTH).setInteractive();
|
||||
|
||||
// Duplicate Collection button — visual only, NOT interactive
|
||||
const btnBg = this.add.rectangle(btnX, btnY, btnHalfW * 2, 65, 0x1a3a5c)
|
||||
.setDepth(DEPTH + 1).setStrokeStyle(2, 0x4488ff);
|
||||
const btnText = this.add.text(btnX, btnY, 'Collection', {
|
||||
fontSize: '28px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
// Arrow to the right of the button, pointing left at it (◄)
|
||||
const arrowX = btnX + btnHalfW + 70; // ~1230
|
||||
const arrow = this.add.text(arrowX, btnY, '\u25C4', {
|
||||
fontSize: '42px', color: '#ffd700'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: arrow,
|
||||
x: arrowX - 14,
|
||||
duration: 600,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
// Descriptive text to the right of the arrow
|
||||
const textX = arrowX + 180; // ~1410
|
||||
const text = this.add.text(textX, btnY - 70, [
|
||||
'The Collection shows every card',
|
||||
'you have ever acquired.',
|
||||
'Browse by faction, rarity, or type',
|
||||
'to review what you\'ve unlocked.'
|
||||
].join('\n'), {
|
||||
fontSize: '22px',
|
||||
color: '#ffffff',
|
||||
fontFamily: 'Audiowide',
|
||||
align: 'center',
|
||||
lineSpacing: 8,
|
||||
wordWrap: { width: 460 }
|
||||
}).setOrigin(0.5, 0).setDepth(DEPTH + 1);
|
||||
|
||||
// Continue button below text
|
||||
const contBg = this.add.rectangle(textX, btnY + 130, 200, 46, 0x1a3a5c)
|
||||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(2, 0x4488ff)
|
||||
.setDepth(DEPTH + 1);
|
||||
const contTxt = this.add.text(textX, btnY + 130, 'Continue', {
|
||||
fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: contBg,
|
||||
alpha: { from: 0.7, to: 1 },
|
||||
duration: 800,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
const els = [overlay, btnBg, btnText, arrow, text, contBg, contTxt];
|
||||
contBg.on('pointerdown', () => {
|
||||
this.sound.play('sfx_menu_select', { volume: 0.7 });
|
||||
els.forEach(el => { if (el.scene) el.destroy(); });
|
||||
this._showCollectionPhase2();
|
||||
});
|
||||
}
|
||||
|
||||
_showCollectionPhase2() {
|
||||
const { width, height } = this.scale;
|
||||
const DEPTH = 1000;
|
||||
|
||||
// Save/Restore buttons: BW=250, x=20+125=145, y=25 and y=65
|
||||
// Area bounds: left=20, right=270, top=8, bottom=82
|
||||
const areaLeft = 20;
|
||||
const areaRight = 270;
|
||||
const areaBottom = 90; // slightly generous
|
||||
const areaCX = (areaLeft + areaRight) / 2; // 145
|
||||
|
||||
// Targeted dimming — leave top-left corner visible
|
||||
const dimTopRight = this.add.rectangle(
|
||||
(areaRight + width) / 2, areaBottom / 2,
|
||||
width - areaRight, areaBottom,
|
||||
0x000000, 0.78
|
||||
).setDepth(DEPTH);
|
||||
const dimBelow = this.add.rectangle(
|
||||
width / 2, (areaBottom + height) / 2,
|
||||
width, height - areaBottom,
|
||||
0x000000, 0.78
|
||||
).setDepth(DEPTH);
|
||||
|
||||
// Arrow just below the save/restore area, pointing up
|
||||
const arrowY = areaBottom + 30; // 120
|
||||
const arrow = this.add.text(areaCX, arrowY, '\u25B2', {
|
||||
fontSize: '36px', color: '#ffd700'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: arrow,
|
||||
y: arrowY - 12,
|
||||
duration: 600,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
// Explanatory text below arrow
|
||||
const text = this.add.text(areaCX, arrowY + 50, [
|
||||
'Your game saves automatically in',
|
||||
'your browser\'s local storage.',
|
||||
'Use these buttons to save a backup',
|
||||
'to your hard drive, or restore',
|
||||
'a previously saved file.'
|
||||
].join('\n'), {
|
||||
fontSize: '18px',
|
||||
color: '#ffffff',
|
||||
fontFamily: 'Audiowide',
|
||||
align: 'center',
|
||||
lineSpacing: 6,
|
||||
wordWrap: { width: 300 }
|
||||
}).setOrigin(0.5, 0).setDepth(DEPTH + 1);
|
||||
|
||||
// Continue button — completes Stage 8
|
||||
const contY = arrowY + 260;
|
||||
const contBg = this.add.rectangle(areaCX, contY, 200, 46, 0x1a3a5c)
|
||||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(2, 0x4488ff)
|
||||
.setDepth(DEPTH + 1);
|
||||
const contTxt = this.add.text(areaCX, contY, 'Continue', {
|
||||
fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: contBg,
|
||||
alpha: { from: 0.7, to: 1 },
|
||||
duration: 800,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
const els = [dimTopRight, dimBelow, arrow, text, contBg, contTxt];
|
||||
contBg.on('pointerdown', () => {
|
||||
this.sound.play('sfx_menu_select', { volume: 0.7 });
|
||||
const save = this.registry.get('save');
|
||||
TutorialManager.completeStage(save, TutorialManager.STAGES.COLLECTION_INTRO);
|
||||
this.registry.set('save', save);
|
||||
els.forEach(el => { if (el.scene) el.destroy(); });
|
||||
});
|
||||
}
|
||||
|
||||
_showDeckBuilderIntroTutorial(save) {
|
||||
const { width, height } = this.scale;
|
||||
const DEPTH = 1000;
|
||||
|
||||
// Deck Builder is index 2 in the button list (startY=310, spacing=90)
|
||||
const btnX = width / 2;
|
||||
const btnY = 310 + 2 * 90; // 490
|
||||
|
||||
// Dark overlay — blocks all clicks beneath
|
||||
const overlay = this.add.rectangle(width / 2, height / 2, width, height, 0x000000, 0.78)
|
||||
.setDepth(DEPTH)
|
||||
.setInteractive();
|
||||
|
||||
// Duplicate Deck Builder button on top of overlay
|
||||
const btnBg = this.add.rectangle(btnX, btnY, 400, 65, 0x1a3a5c)
|
||||
.setDepth(DEPTH + 1)
|
||||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(2, 0x4488ff);
|
||||
const btnText = this.add.text(btnX, btnY, 'Deck Builder', {
|
||||
fontSize: '28px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
btnBg.on('pointerover', () => { this.sound.play('sfx_menu_hover', { volume: 0.5 }); btnBg.setFillStyle(0x2a5a8c); });
|
||||
btnBg.on('pointerout', () => btnBg.setFillStyle(0x1a3a5c));
|
||||
|
||||
// Pulsing arrow above button
|
||||
const arrow = this.add.text(btnX, btnY - 60, '\u25BC', {
|
||||
fontSize: '48px', color: '#ffd700'
|
||||
}).setOrigin(0.5).setDepth(DEPTH + 1);
|
||||
|
||||
this.tweens.add({
|
||||
targets: arrow,
|
||||
y: btnY - 45,
|
||||
duration: 600,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
// Instructional text
|
||||
const infoText = this.add.text(btnX, btnY + 55, [
|
||||
'The Deck Builder lets you customize your deck.',
|
||||
'Add or remove cards from your collection,',
|
||||
'choose your commander, and save your changes.',
|
||||
'Click Deck Builder to explore it!'
|
||||
].join('\n'), {
|
||||
fontSize: '22px',
|
||||
color: '#ffffff',
|
||||
fontFamily: 'Audiowide',
|
||||
align: 'center',
|
||||
lineSpacing: 8
|
||||
}).setOrigin(0.5, 0).setDepth(DEPTH + 1);
|
||||
|
||||
const tutorialElements = [overlay, btnBg, btnText, arrow, infoText];
|
||||
btnBg.on('pointerdown', () => {
|
||||
this.sound.play('sfx_menu_select', { volume: 0.7 });
|
||||
tutorialElements.forEach(el => el.destroy());
|
||||
this.scene.start('DeckBuilderScene');
|
||||
});
|
||||
}
|
||||
|
||||
_makeFullscreenButton(x, y) {
|
||||
const getLabel = () => this.scale.isFullscreen ? '⛶ Exit Fullscreen' : '⛶ Toggle Fullscreen';
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue