tuturiol
This commit is contained in:
293
src/systems/TutorialSystem.js
Normal file
293
src/systems/TutorialSystem.js
Normal file
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
* TUTORIAL SYSTEM
|
||||
* Shows helpful tips and keyboard shortcuts to new players
|
||||
*/
|
||||
class TutorialSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.enabled = true;
|
||||
this.currentStep = 0;
|
||||
this.completed = false;
|
||||
|
||||
// Tutorial steps
|
||||
this.steps = [
|
||||
{
|
||||
title: '🎮 Welcome to NovaFarma!',
|
||||
message: 'Use W/A/S/D to move around\nPress SPACE to attack\nPress E to interact with objects',
|
||||
icon: '👋',
|
||||
duration: 5000
|
||||
},
|
||||
{
|
||||
title: '🏗️ Building',
|
||||
message: 'Press B to enter Build Mode\nSelect buildings with 1-5\nClick to place buildings',
|
||||
icon: '🏗️',
|
||||
duration: 5000
|
||||
},
|
||||
{
|
||||
title: '🔨 Crafting',
|
||||
message: 'Press C to open Crafting Menu\nCraft tools and items\nUse resources from your inventory',
|
||||
icon: '🔨',
|
||||
duration: 5000
|
||||
},
|
||||
{
|
||||
title: '🎣 Fishing',
|
||||
message: 'Press R to cast fishing rod\nPress SPACE to catch fish\nUse LEFT/RIGHT to move bobber',
|
||||
icon: '🎣',
|
||||
duration: 5000
|
||||
},
|
||||
{
|
||||
title: '💾 Save & Load',
|
||||
message: 'Press F5 to Quick Save\nPress F9 to Load Game\nYour progress is saved automatically',
|
||||
icon: '💾',
|
||||
duration: 5000
|
||||
},
|
||||
{
|
||||
title: '📋 More Controls',
|
||||
message: 'Press TAB for Stats Panel\nPress M for Map\nPress ESC for Pause Menu\n\nPress H anytime for help!',
|
||||
icon: '⌨️',
|
||||
duration: 6000
|
||||
}
|
||||
];
|
||||
|
||||
// Load progress
|
||||
this.loadProgress();
|
||||
|
||||
// Show tutorial if not completed
|
||||
if (!this.completed && this.enabled) {
|
||||
this.scene.time.delayedCall(2000, () => {
|
||||
this.showNextStep();
|
||||
});
|
||||
}
|
||||
|
||||
console.log('📚 Tutorial System initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show next tutorial step
|
||||
*/
|
||||
showNextStep() {
|
||||
if (this.currentStep >= this.steps.length) {
|
||||
this.completeTutorial();
|
||||
return;
|
||||
}
|
||||
|
||||
const step = this.steps[this.currentStep];
|
||||
this.showTutorialPopup(step);
|
||||
this.currentStep++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show tutorial popup
|
||||
*/
|
||||
showTutorialPopup(step) {
|
||||
const uiScene = this.scene.scene.get('UIScene');
|
||||
if (!uiScene) return;
|
||||
|
||||
// Create container
|
||||
const container = uiScene.add.container(
|
||||
uiScene.scale.width / 2,
|
||||
uiScene.scale.height / 2
|
||||
);
|
||||
container.setDepth(99998); // Below epilepsy warning
|
||||
container.setScrollFactor(0);
|
||||
|
||||
// Semi-transparent background
|
||||
const overlay = uiScene.add.rectangle(
|
||||
0, 0,
|
||||
uiScene.scale.width * 2,
|
||||
uiScene.scale.height * 2,
|
||||
0x000000, 0.5
|
||||
);
|
||||
container.add(overlay);
|
||||
|
||||
// Popup background
|
||||
const bg = uiScene.add.graphics();
|
||||
bg.fillStyle(0x2a4a2a, 0.95); // Dark green
|
||||
bg.fillRoundedRect(-300, -150, 600, 300, 16);
|
||||
bg.lineStyle(4, 0x90EE90, 1); // Light green border
|
||||
bg.strokeRoundedRect(-300, -150, 600, 300, 16);
|
||||
container.add(bg);
|
||||
|
||||
// Icon
|
||||
const icon = uiScene.add.text(-280, -130, step.icon, {
|
||||
fontSize: '48px'
|
||||
});
|
||||
container.add(icon);
|
||||
|
||||
// Title
|
||||
const title = uiScene.add.text(0, -100, step.title, {
|
||||
fontSize: '28px',
|
||||
fontFamily: 'Arial',
|
||||
fill: '#FFD700',
|
||||
fontStyle: 'bold',
|
||||
align: 'center'
|
||||
}).setOrigin(0.5);
|
||||
container.add(title);
|
||||
|
||||
// Message
|
||||
const message = uiScene.add.text(0, 0, step.message, {
|
||||
fontSize: '20px',
|
||||
fontFamily: 'Arial',
|
||||
fill: '#ffffff',
|
||||
align: 'center',
|
||||
lineSpacing: 8,
|
||||
wordWrap: { width: 550 }
|
||||
}).setOrigin(0.5);
|
||||
container.add(message);
|
||||
|
||||
// Progress indicator
|
||||
const progress = uiScene.add.text(
|
||||
0, 100,
|
||||
`Step ${this.currentStep + 1} of ${this.steps.length}`,
|
||||
{
|
||||
fontSize: '14px',
|
||||
fill: '#aaaaaa'
|
||||
}
|
||||
).setOrigin(0.5);
|
||||
container.add(progress);
|
||||
|
||||
// Next button
|
||||
const nextBtn = uiScene.add.text(0, 130, '[ NEXT ]', {
|
||||
fontSize: '20px',
|
||||
color: '#00ff00',
|
||||
backgroundColor: '#003300',
|
||||
padding: { x: 30, y: 10 },
|
||||
fontStyle: 'bold'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
nextBtn.setInteractive({ useHandCursor: true });
|
||||
nextBtn.on('pointerover', () => nextBtn.setScale(1.1));
|
||||
nextBtn.on('pointerout', () => nextBtn.setScale(1.0));
|
||||
nextBtn.on('pointerdown', () => {
|
||||
container.destroy();
|
||||
this.showNextStep();
|
||||
});
|
||||
container.add(nextBtn);
|
||||
|
||||
// Skip button
|
||||
const skipBtn = uiScene.add.text(250, -130, 'Skip Tutorial', {
|
||||
fontSize: '14px',
|
||||
color: '#888888'
|
||||
}).setOrigin(1, 0);
|
||||
|
||||
skipBtn.setInteractive({ useHandCursor: true });
|
||||
skipBtn.on('pointerover', () => skipBtn.setColor('#ffffff'));
|
||||
skipBtn.on('pointerout', () => skipBtn.setColor('#888888'));
|
||||
skipBtn.on('pointerdown', () => {
|
||||
container.destroy();
|
||||
this.completeTutorial();
|
||||
});
|
||||
container.add(skipBtn);
|
||||
|
||||
// Animate in
|
||||
container.setScale(0.8);
|
||||
container.setAlpha(0);
|
||||
uiScene.tweens.add({
|
||||
targets: container,
|
||||
scale: 1,
|
||||
alpha: 1,
|
||||
duration: 300,
|
||||
ease: 'Back.easeOut'
|
||||
});
|
||||
|
||||
// Auto-advance after duration
|
||||
uiScene.time.delayedCall(step.duration, () => {
|
||||
if (container.active) {
|
||||
uiScene.tweens.add({
|
||||
targets: container,
|
||||
scale: 0.8,
|
||||
alpha: 0,
|
||||
duration: 200,
|
||||
onComplete: () => {
|
||||
container.destroy();
|
||||
this.showNextStep();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete tutorial
|
||||
*/
|
||||
completeTutorial() {
|
||||
this.completed = true;
|
||||
this.saveProgress();
|
||||
console.log('✅ Tutorial completed!');
|
||||
|
||||
// Show completion message
|
||||
const uiScene = this.scene.scene.get('UIScene');
|
||||
if (uiScene && uiScene.centralPopup) {
|
||||
uiScene.centralPopup.showNotification(
|
||||
'Tutorial completed! Press H anytime for help.',
|
||||
'success'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show help popup (H key)
|
||||
*/
|
||||
showHelp() {
|
||||
const uiScene = this.scene.scene.get('UIScene');
|
||||
if (!uiScene || !uiScene.centralPopup) return;
|
||||
|
||||
uiScene.centralPopup.showPopup({
|
||||
title: '⌨️ Keyboard Shortcuts',
|
||||
message:
|
||||
'🎮 MOVEMENT:\n' +
|
||||
'W/A/S/D - Move\n' +
|
||||
'SPACE - Attack\n' +
|
||||
'E - Interact\n\n' +
|
||||
'🏗️ BUILD & CRAFT:\n' +
|
||||
'B - Build Mode\n' +
|
||||
'C - Crafting Menu\n\n' +
|
||||
'🎣 FISHING:\n' +
|
||||
'R - Cast Rod\n' +
|
||||
'SPACE - Catch Fish\n\n' +
|
||||
'💾 SAVE/LOAD:\n' +
|
||||
'F5 - Quick Save\n' +
|
||||
'F9 - Load Game\n\n' +
|
||||
'📋 OTHER:\n' +
|
||||
'TAB - Stats Panel\n' +
|
||||
'M - Map\n' +
|
||||
'ESC - Pause',
|
||||
type: 'info',
|
||||
icon: '📋',
|
||||
buttons: [{ text: 'OK', action: 'close' }],
|
||||
autoClose: false
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset tutorial
|
||||
*/
|
||||
reset() {
|
||||
this.currentStep = 0;
|
||||
this.completed = false;
|
||||
this.saveProgress();
|
||||
console.log('🔄 Tutorial reset');
|
||||
}
|
||||
|
||||
/**
|
||||
* Save progress
|
||||
*/
|
||||
saveProgress() {
|
||||
localStorage.setItem('novafarma_tutorial', JSON.stringify({
|
||||
completed: this.completed,
|
||||
currentStep: this.currentStep
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load progress
|
||||
*/
|
||||
loadProgress() {
|
||||
const saved = localStorage.getItem('novafarma_tutorial');
|
||||
if (saved) {
|
||||
const data = JSON.parse(saved);
|
||||
this.completed = data.completed || false;
|
||||
this.currentStep = data.currentStep || 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user