Initial commit: Naddie Jump — Monad Edition
This commit is contained in:
164
src/scenes/MenuScene.js
Normal file
164
src/scenes/MenuScene.js
Normal file
@@ -0,0 +1,164 @@
|
||||
import { Scene } from 'phaser';
|
||||
|
||||
export class MenuScene extends Scene {
|
||||
constructor() {
|
||||
super({ key: 'MenuScene' });
|
||||
}
|
||||
|
||||
create() {
|
||||
const { width, height } = this.scale;
|
||||
|
||||
// Background
|
||||
this.add.tileSprite(width / 2, height / 2, width, height, 'gridBg');
|
||||
|
||||
// Title
|
||||
this.add.text(width / 2, height * 0.18, 'NADDIE JUMP', {
|
||||
fontFamily: '"Press Start 2P", monospace',
|
||||
fontSize: '38px',
|
||||
color: '#d8b4fe',
|
||||
align: 'center',
|
||||
}).setOrigin(0.5).setShadow(4, 4, '#581c87', 0, false, true);
|
||||
|
||||
this.add.text(width / 2, height * 0.27, 'MONAD EDITION', {
|
||||
fontFamily: '"Press Start 2P", monospace',
|
||||
fontSize: '14px',
|
||||
color: '#a855f7',
|
||||
align: 'center',
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Floating Naddie preview
|
||||
const preview = this.add.image(width / 2, height * 0.48, 'player_idle')
|
||||
.setScale(0.55);
|
||||
this.tweens.add({
|
||||
targets: preview,
|
||||
y: height * 0.48 - 15,
|
||||
duration: 1400,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut',
|
||||
});
|
||||
this.tweens.add({
|
||||
targets: preview,
|
||||
angle: 5,
|
||||
duration: 2000,
|
||||
yoyo: true,
|
||||
repeat: -1,
|
||||
ease: 'Sine.easeInOut',
|
||||
});
|
||||
|
||||
// Start button
|
||||
this.createButton(width / 2, height * 0.68, 'START GAME', () => {
|
||||
this.scene.start('GameScene');
|
||||
});
|
||||
|
||||
this.add.text(width / 2, height * 0.74, 'Press ENTER or SPACE to start', {
|
||||
fontFamily: '"Press Start 2P", monospace',
|
||||
fontSize: '10px',
|
||||
color: '#888',
|
||||
align: 'center',
|
||||
}).setOrigin(0.5);
|
||||
|
||||
this.input.keyboard.on('keydown-ENTER', () => {
|
||||
this.scene.start('GameScene');
|
||||
});
|
||||
this.input.keyboard.on('keydown-SPACE', () => {
|
||||
this.scene.start('GameScene');
|
||||
});
|
||||
|
||||
// Leaderboard button
|
||||
this.createButton(width / 2, height * 0.78, 'LEADERBOARD', () => {
|
||||
this.showLeaderboard();
|
||||
});
|
||||
|
||||
this.add.text(width / 2, height * 0.92, 'Web3 integration coming soon', {
|
||||
fontFamily: '"Press Start 2P", monospace',
|
||||
fontSize: '9px',
|
||||
color: '#444',
|
||||
align: 'center',
|
||||
}).setOrigin(0.5);
|
||||
|
||||
this.createAmbientParticles();
|
||||
}
|
||||
|
||||
createButton(x, y, text, callback) {
|
||||
const bg = this.add.rectangle(x, y, 280, 56, 0x581c87)
|
||||
.setStrokeStyle(3, 0xa855f7)
|
||||
.setInteractive({ useHandCursor: true });
|
||||
|
||||
const label = this.add.text(x, y, text, {
|
||||
fontFamily: '"Press Start 2P", monospace',
|
||||
fontSize: '15px',
|
||||
color: '#ffffff',
|
||||
}).setOrigin(0.5);
|
||||
|
||||
bg.on('pointerover', () => {
|
||||
bg.setFillStyle(0x7e22ce);
|
||||
this.tweens.add({ targets: [bg, label], scaleX: 1.05, scaleY: 1.05, duration: 100 });
|
||||
});
|
||||
bg.on('pointerout', () => {
|
||||
bg.setFillStyle(0x581c87);
|
||||
this.tweens.add({ targets: [bg, label], scaleX: 1, scaleY: 1, duration: 100 });
|
||||
});
|
||||
bg.on('pointerdown', callback);
|
||||
|
||||
return { bg, label };
|
||||
}
|
||||
|
||||
showLeaderboard() {
|
||||
const { width, height } = this.scale;
|
||||
const overlay = this.add.rectangle(width / 2, height / 2, width, height, 0x000000, 0.7).setDepth(100);
|
||||
const panel = this.add.rectangle(width / 2, height / 2, 400, 440, 0x1a0533).setStrokeStyle(3, 0xa855f7).setDepth(101);
|
||||
|
||||
const title = this.add.text(width / 2, height * 0.22, 'LEADERBOARD', {
|
||||
fontFamily: '"Press Start 2P", monospace',
|
||||
fontSize: '18px',
|
||||
color: '#d8b4fe',
|
||||
}).setOrigin(0.5).setDepth(102);
|
||||
|
||||
const close = this.add.text(width / 2 + 170, height * 0.22 - 80, 'X', {
|
||||
fontFamily: '"Press Start 2P", monospace',
|
||||
fontSize: '18px',
|
||||
color: '#fff',
|
||||
}).setOrigin(0.5).setDepth(102).setInteractive({ useHandCursor: true });
|
||||
|
||||
const rows = [];
|
||||
const mock = [
|
||||
{ rank: 1, addr: '0xMonad...Dev', score: 99999 },
|
||||
{ rank: 2, addr: '0xAlice...xyz', score: 87500 },
|
||||
{ rank: 3, addr: '0xBob...abc', score: 74200 },
|
||||
{ rank: 4, addr: '0xYou', score: parseInt(localStorage.getItem('naddie_best_score') || '0', 10) },
|
||||
];
|
||||
mock.forEach((entry, i) => {
|
||||
const y = height * 0.32 + i * 55;
|
||||
rows.push({
|
||||
rank: this.add.text(width / 2 - 160, y, `#${entry.rank}`, { fontFamily: '"Press Start 2P", monospace', fontSize: '12px', color: '#a855f7' }).setOrigin(0.5).setDepth(102),
|
||||
addr: this.add.text(width / 2, y, entry.addr, { fontFamily: '"Press Start 2P", monospace', fontSize: '10px', color: '#fff' }).setOrigin(0.5).setDepth(102),
|
||||
score: this.add.text(width / 2 + 150, y, String(entry.score), { fontFamily: '"Press Start 2P", monospace', fontSize: '12px', color: '#d8b4fe' }).setOrigin(0.5).setDepth(102),
|
||||
});
|
||||
});
|
||||
|
||||
close.on('pointerdown', () => {
|
||||
overlay.destroy();
|
||||
panel.destroy();
|
||||
title.destroy();
|
||||
close.destroy();
|
||||
rows.forEach(r => { r.rank.destroy(); r.addr.destroy(); r.score.destroy(); });
|
||||
});
|
||||
}
|
||||
|
||||
createAmbientParticles() {
|
||||
const { width, height } = this.scale;
|
||||
for (let i = 0; i < 40; i++) {
|
||||
const s = this.add.image(Phaser.Math.Between(0, width), Phaser.Math.Between(0, height), 'star');
|
||||
s.setAlpha(Phaser.Math.FloatBetween(0.15, 0.7));
|
||||
this.tweens.add({
|
||||
targets: s,
|
||||
y: s.y - Phaser.Math.Between(50, 250),
|
||||
alpha: 0,
|
||||
duration: Phaser.Math.Between(2000, 6000),
|
||||
repeat: -1,
|
||||
delay: Phaser.Math.Between(0, 3000),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user