/** * MenuScene.js * Main menu scene — military-tech themed UI with game title and mode selection. * Rendered entirely with Canvas API (no DOM). */ const { SCREEN_WIDTH, SCREEN_HEIGHT, COLORS, SCENE, GAME_MODE, } = require('../base/GameGlobal'); const { t } = require('../i18n/I18n'); // ============================================================ // Style // ============================================================ const MC = { BG_TOP: '#0b0e17', BG_BOT: '#141b2d', ACCENT: '#e94560', GOLD: '#FFD700', GOLD_DIM: '#B8860B', BTN_BG: '#16213e', BTN_BORDER: '#1e3054', BTN_HOVER: '#0f3460', BTN_TEXT: '#E8E8E8', TITLE: '#FFD700', SUBTITLE: '#8899AA', FOOTER: '#445566', TANK_BODY: '#FFD700', TANK_TRACK: '#B8860B', }; // ============================================================ // Button Layout // ============================================================ const BTN_WIDTH = Math.min(SCREEN_WIDTH * 0.55, 280); const BTN_HEIGHT = Math.min(36, SCREEN_HEIGHT * 0.07); const BTN_GAP = Math.min(8, SCREEN_HEIGHT * 0.015); const BTN_START_Y = SCREEN_HEIGHT * 0.38; const BTN_X = (SCREEN_WIDTH - BTN_WIDTH) / 2; const HALF_BTN_WIDTH = (BTN_WIDTH - BTN_GAP) / 2; const THIRD_BTN_WIDTH = (BTN_WIDTH - BTN_GAP * 2) / 3; // Main game mode buttons (full width, vertical) const MAIN_BUTTONS = [ { labelKey: 'menu.classic', mode: GAME_MODE.CLASSIC, scene: SCENE.GAME }, { labelKey: 'menu.endless', mode: GAME_MODE.ENDLESS, scene: SCENE.GAME }, { labelKey: 'menu.pvp', mode: GAME_MODE.PVP, scene: SCENE.PVP_ROOM }, { labelKey: 'menu.team3v3', mode: GAME_MODE.TEAM_3V3, scene: SCENE.TEAM_ROOM }, ]; // Utility buttons: daily gold, skin, ranking, settings (grid) // NOTE: Shop button is temporarily disabled const UTIL_BUTTONS = [ { labelKey: 'dailyGold.btn', mode: null, scene: 'DAILY_GOLD' }, { labelKey: 'menu.skin', mode: null, scene: SCENE.SKIN }, { labelKey: 'menu.ranking', mode: null, scene: SCENE.RANKING }, { labelKey: 'menu.settings', mode: null, scene: SCENE.SETTINGS }, ]; // Pre-calculate button rects for main buttons const mainBtnRects = MAIN_BUTTONS.map((btn, i) => ({ x: BTN_X, y: BTN_START_Y + i * (BTN_HEIGHT + BTN_GAP), w: BTN_WIDTH, h: BTN_HEIGHT, ...btn, })); // Pre-calculate button rects for utility buttons (2 rows x 2 cols) const utilStartY = BTN_START_Y + MAIN_BUTTONS.length * (BTN_HEIGHT + BTN_GAP) + BTN_GAP; const utilBtnRects = UTIL_BUTTONS.map((btn, i) => { const row = Math.floor(i / 2); const col = i % 2; return { x: BTN_X + col * (HALF_BTN_WIDTH + BTN_GAP), y: utilStartY + row * (BTN_HEIGHT + BTN_GAP), w: HALF_BTN_WIDTH, h: BTN_HEIGHT, ...btn, }; }); const buttonRects = [...mainBtnRects, ...utilBtnRects]; // ============================================================ // Menu Scene // ============================================================ const MenuScene = { _pressedIndex: -1, _tankAnim: 0, enter() { this._pressedIndex = -1; this._tankAnim = 0; this._avatarImg = null; // Load avatar image if profile has one const profile = GameGlobal.playerProfile; if (profile && profile.avatarUrl) { this._loadAvatarImage(profile.avatarUrl); } // Listen for profile updates (avatar may arrive after initial render) this._profileHandler = (data) => { if (data && data.avatarUrl && !this._avatarImg) { this._loadAvatarImage(data.avatarUrl); } }; const bus = GameGlobal.eventBus; if (bus && typeof bus.on === 'function') { bus.on('profile:updated', this._profileHandler); } // Kick off nickname acquisition as early as possible so that later // network messages (CREATE_TEAM, SOLO_MATCH, ...) can carry it. this._initPlayerProfile(); if (GameGlobal._pendingTeamId) { const teamId = GameGlobal._pendingTeamId; GameGlobal._pendingTeamId = null; console.log(`[MenuScene] Found pendingTeamId: ${teamId}, will auto-navigate to TeamRoomScene`); setTimeout(() => { console.log(`[MenuScene] Auto-navigating to TeamRoomScene with teamId: ${teamId}`); const sm = GameGlobal.sceneManager; if (!sm._scenes.has(SCENE.TEAM_ROOM)) { const TeamRoomScene = require('./TeamRoomScene'); sm.register(SCENE.TEAM_ROOM, TeamRoomScene); } sm.switchTo(SCENE.TEAM_ROOM, { teamId }); }, 100); } if (GameGlobal._pendingRoomId) { const roomId = GameGlobal._pendingRoomId; GameGlobal._pendingRoomId = null; console.log(`[MenuScene] Found pendingRoomId: ${roomId}, will auto-navigate to RoomScene`); setTimeout(() => { console.log(`[MenuScene] Auto-navigating to RoomScene with roomId: ${roomId}`); const sm = GameGlobal.sceneManager; if (!sm._scenes.has(SCENE.PVP_ROOM)) { const RoomScene = require('./RoomScene'); sm.register(SCENE.PVP_ROOM, RoomScene); } sm.switchTo(SCENE.PVP_ROOM, { roomId }); }, 100); } }, exit() { this._pressedIndex = -1; // Destroy UserInfoButton overlay when leaving the menu const profile = GameGlobal.playerProfile; if (profile && typeof profile.destroyUserInfoButton === 'function') { profile.destroyUserInfoButton(); } // Remove profile update listener const bus = GameGlobal.eventBus; if (bus && typeof bus.off === 'function' && this._profileHandler) { bus.off('profile:updated', this._profileHandler); } this._profileHandler = null; this._avatarImg = null; }, update(dt) { this._tankAnim += dt; }, render(ctx) { // ---- Background ---- const bgGrad = ctx.createLinearGradient(0, 0, 0, SCREEN_HEIGHT); bgGrad.addColorStop(0, MC.BG_TOP); bgGrad.addColorStop(1, MC.BG_BOT); ctx.fillStyle = bgGrad; ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); // Scan-lines ctx.globalAlpha = 0.025; ctx.fillStyle = '#FFFFFF'; for (let sy = 0; sy < SCREEN_HEIGHT; sy += 4) { ctx.fillRect(0, sy, SCREEN_WIDTH, 1); } ctx.globalAlpha = 1; // Top accent bar const accentGrad = ctx.createLinearGradient(0, 0, SCREEN_WIDTH, 0); accentGrad.addColorStop(0, 'transparent'); accentGrad.addColorStop(0.3, MC.ACCENT); accentGrad.addColorStop(0.7, MC.ACCENT); accentGrad.addColorStop(1, 'transparent'); ctx.fillStyle = accentGrad; ctx.fillRect(0, 0, SCREEN_WIDTH, 3); // ---- Player Avatar & Nickname (top-left) ---- const profile = GameGlobal.playerProfile; const avatarSize = 28; const avatarX = 10; const avatarY = 10; const avatarR = avatarSize / 2; // Avatar circle background ctx.save(); ctx.beginPath(); ctx.arc(avatarX + avatarR, avatarY + avatarR, avatarR, 0, Math.PI * 2); ctx.closePath(); ctx.fillStyle = 'rgba(30,48,84,0.7)'; ctx.fill(); ctx.strokeStyle = 'rgba(255,215,0,0.4)'; ctx.lineWidth = 1; ctx.stroke(); // Avatar image or default icon if (profile && profile.avatarUrl && this._avatarImg && this._avatarImg.complete) { ctx.clip(); ctx.drawImage(this._avatarImg, avatarX, avatarY, avatarSize, avatarSize); } else { // Default user icon (simple silhouette) ctx.fillStyle = 'rgba(255,215,0,0.5)'; ctx.beginPath(); ctx.arc(avatarX + avatarR, avatarY + avatarR - 2, avatarR * 0.35, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.ellipse(avatarX + avatarR, avatarY + avatarR + avatarR * 0.55, avatarR * 0.55, avatarR * 0.3, 0, Math.PI, 0); ctx.fill(); } ctx.restore(); // Nickname const displayName = profile ? profile.getDisplayName() : 'Tanker'; ctx.font = 'bold 11px Arial'; ctx.fillStyle = MC.GOLD; ctx.textAlign = 'left'; ctx.textBaseline = 'middle'; ctx.fillText(displayName, avatarX + avatarSize + 6, avatarY + avatarR - 5); // Hint text (only if not yet granted) if (profile && !profile.granted) { ctx.font = '9px Arial'; ctx.fillStyle = MC.SUBTITLE; ctx.fillText(t('menu.tapToAuth') || 'Tap to authorize', avatarX + avatarSize + 6, avatarY + avatarR + 8); } // ---- Gold Balance (top-right pill) ---- const gold = GameGlobal.currencyManager ? GameGlobal.currencyManager.getGold() : 0; const goldText = `🪙 ${gold}`; ctx.font = 'bold 12px Arial'; const gtw = ctx.measureText(goldText).width; const pillW = gtw + 16; const pillH = 22; const pillX = SCREEN_WIDTH - pillW - 12; const pillY = 10; ctx.fillStyle = 'rgba(255, 215, 0, 0.08)'; ctx.strokeStyle = 'rgba(255, 215, 0, 0.3)'; ctx.lineWidth = 1; this._roundRect(ctx, pillX, pillY, pillW, pillH, pillH / 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = MC.GOLD; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(goldText, pillX + pillW / 2, pillY + pillH / 2); // ---- Title with glow ---- ctx.save(); ctx.shadowColor = MC.GOLD; ctx.shadowBlur = 16; ctx.fillStyle = MC.TITLE; ctx.font = 'bold 34px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(t('menu.title'), SCREEN_WIDTH / 2, SCREEN_HEIGHT * 0.15); ctx.restore(); // ---- Subtitle ---- ctx.fillStyle = MC.SUBTITLE; ctx.font = '13px Arial'; ctx.textAlign = 'center'; ctx.fillText(t('menu.subtitle'), SCREEN_WIDTH / 2, SCREEN_HEIGHT * 0.22); // ---- Animated Tank Icon ---- this._drawTankIcon(ctx, SCREEN_WIDTH / 2, SCREEN_HEIGHT * 0.30); // ---- Main Buttons ---- for (let i = 0; i < mainBtnRects.length; i++) { const btn = mainBtnRects[i]; const isPressed = this._pressedIndex === i; this._drawMenuButton(ctx, btn, t(btn.labelKey), isPressed, 'bold 16px Arial', 8); } // ---- Utility Buttons ---- for (let i = 0; i < utilBtnRects.length; i++) { const btn = utilBtnRects[i]; const globalIdx = mainBtnRects.length + i; const isPressed = this._pressedIndex === globalIdx; const isDailyGold = btn.scene === 'DAILY_GOLD'; let label = t(btn.labelKey); let customBg = null; if (isDailyGold) { const remaining = GameGlobal.adManager ? GameGlobal.adManager.getDailyGoldRemaining() : 0; if (remaining > 0) { label = `${t('dailyGold.btn')} ${remaining}/3`; customBg = '#1a3a2a'; } else { label = t('dailyGold.exhausted') || 'Come back tomorrow'; customBg = '#2a2a2a'; } } this._drawMenuButton(ctx, btn, label, isPressed, 'bold 13px Arial', 6, customBg); } // ---- Footer ---- ctx.fillStyle = MC.FOOTER; ctx.font = '10px Arial'; ctx.textAlign = 'center'; ctx.fillText('v1.0.0', SCREEN_WIDTH / 2, SCREEN_HEIGHT - 18); }, // ---- Menu Button ---- _drawMenuButton(ctx, btn, label, isPressed, font, radius, customBg) { const r = radius || 8; // Shadow ctx.fillStyle = 'rgba(0,0,0,0.2)'; this._roundRect(ctx, btn.x + 1, btn.y + 2, btn.w, btn.h, r); ctx.fill(); // Body ctx.fillStyle = isPressed ? MC.BTN_HOVER : (customBg || MC.BTN_BG); ctx.strokeStyle = MC.BTN_BORDER; ctx.lineWidth = 1.5; this._roundRect(ctx, btn.x, btn.y, btn.w, btn.h, r); ctx.fill(); ctx.stroke(); // Label ctx.fillStyle = isPressed ? MC.TITLE : MC.BTN_TEXT; ctx.font = font || 'bold 16px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(label, btn.x + btn.w / 2, btn.y + btn.h / 2); }, // ---- Tank Icon ---- _drawTankIcon(ctx, cx, cy) { const bounce = Math.sin(this._tankAnim * 3) * 2; const pulse = 0.5 + 0.5 * Math.sin(this._tankAnim * 2); const s = 15; // body half-size (square tank: 2s × 2s) ctx.save(); ctx.translate(cx, cy + bounce); // ── 1. OUTER GLOW HALO (breathing golden aura) ── ctx.save(); ctx.globalAlpha = 0.15 + pulse * 0.12; ctx.fillStyle = MC.GOLD; ctx.beginPath(); ctx.arc(0, 0, s * 1.55, 0, Math.PI * 2); ctx.fill(); ctx.restore(); // ── 2. GROUND SHADOW (soft ellipse underneath) ── ctx.save(); ctx.globalAlpha = 0.35; ctx.fillStyle = '#000'; ctx.beginPath(); ctx.ellipse(0, s + 6, s * 1.1, 3, 0, 0, Math.PI * 2); ctx.fill(); ctx.restore(); // ── 3. TRACKS (left & right, with segment pattern) ── const trackW = 5; const trackX = s; // Left track ctx.fillStyle = '#4A3508'; this._roundRect(ctx, -trackX - trackW, -s, trackW, s * 2, 1.5); ctx.fill(); // Right track this._roundRect(ctx, trackX, -s, trackW, s * 2, 1.5); ctx.fill(); // Track top highlight ctx.fillStyle = 'rgba(255, 220, 120, 0.35)'; ctx.fillRect(-trackX - trackW + 0.8, -s + 0.8, trackW - 1.6, 1); ctx.fillRect(trackX + 0.8, -s + 0.8, trackW - 1.6, 1); // Track segment lines (metallic plate pattern) ctx.strokeStyle = 'rgba(0, 0, 0, 0.55)'; ctx.lineWidth = 0.8; for (let ty = -s + 4; ty < s - 1; ty += 4) { ctx.beginPath(); ctx.moveTo(-trackX - trackW, ty); ctx.lineTo(-trackX, ty); ctx.stroke(); ctx.beginPath(); ctx.moveTo(trackX, ty); ctx.lineTo(trackX + trackW, ty); ctx.stroke(); } // ── 4. BODY (square, with vertical metallic gradient) ── ctx.save(); ctx.shadowColor = MC.GOLD; ctx.shadowBlur = 12; const bodyGrad = ctx.createLinearGradient(0, -s, 0, s); bodyGrad.addColorStop(0, '#FFF3A8'); // top highlight bodyGrad.addColorStop(0.3, MC.GOLD); // main gold bodyGrad.addColorStop(0.75, '#C89A1C'); bodyGrad.addColorStop(1, '#7A5A0A'); // bottom shadow ctx.fillStyle = bodyGrad; this._roundRect(ctx, -s, -s, s * 2, s * 2, 3); ctx.fill(); ctx.restore(); // ── 5. BODY EDGE OUTLINE ── ctx.strokeStyle = 'rgba(255, 235, 150, 0.7)'; ctx.lineWidth = 1; this._roundRect(ctx, -s, -s, s * 2, s * 2, 3); ctx.stroke(); // ── 6. TOP HIGHLIGHT STRIP (bright metallic sheen) ── ctx.fillStyle = 'rgba(255, 255, 255, 0.35)'; this._roundRect(ctx, -s + 2, -s + 2, s * 2 - 4, 3, 1.5); ctx.fill(); // ── 7. ARMOR PLATE DETAIL (X-cross rivets in 4 corners + center crosshair) ── const rivetOffset = s * 0.6; ctx.fillStyle = '#6B4A08'; for (const [rx, ry] of [[-rivetOffset, -rivetOffset], [rivetOffset, -rivetOffset], [-rivetOffset, rivetOffset], [rivetOffset, rivetOffset]]) { ctx.beginPath(); ctx.arc(rx, ry, 1.4, 0, Math.PI * 2); ctx.fill(); // Tiny rivet highlight ctx.fillStyle = 'rgba(255, 240, 180, 0.8)'; ctx.beginPath(); ctx.arc(rx - 0.3, ry - 0.3, 0.5, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#6B4A08'; } // ── 8. TURRET (diamond-shaped center cap with gradient) ── const turretR = s * 0.42; ctx.save(); ctx.shadowColor = MC.GOLD; ctx.shadowBlur = 6; const turretGrad = ctx.createRadialGradient(-turretR * 0.3, -turretR * 0.3, 0, 0, 0, turretR); turretGrad.addColorStop(0, '#FFF3A8'); turretGrad.addColorStop(0.5, '#E0B020'); turretGrad.addColorStop(1, '#8B6914'); ctx.fillStyle = turretGrad; // Diamond (rotated square) for "military hatch" feel ctx.beginPath(); ctx.moveTo(0, -turretR); ctx.lineTo(turretR, 0); ctx.lineTo(0, turretR); ctx.lineTo(-turretR, 0); ctx.closePath(); ctx.fill(); ctx.restore(); // Turret edge ctx.strokeStyle = 'rgba(255, 235, 150, 0.8)'; ctx.lineWidth = 0.8; ctx.beginPath(); ctx.moveTo(0, -turretR); ctx.lineTo(turretR, 0); ctx.lineTo(0, turretR); ctx.lineTo(-turretR, 0); ctx.closePath(); ctx.stroke(); // Turret internal cross ctx.strokeStyle = 'rgba(0, 0, 0, 0.35)'; ctx.lineWidth = 0.6; ctx.beginPath(); ctx.moveTo(0, -turretR); ctx.lineTo(0, turretR); ctx.stroke(); ctx.beginPath(); ctx.moveTo(-turretR, 0); ctx.lineTo(turretR, 0); ctx.stroke(); // Turret center hatch ctx.fillStyle = '#FFF3A8'; ctx.beginPath(); ctx.arc(0, 0, 2.5, 0, Math.PI * 2); ctx.fill(); // ── 9. BARREL (thick, with metallic gradient) ── const barrelW = 6; const barrelH = 16; const barrelY = -s - barrelH; ctx.save(); const barrelGrad = ctx.createLinearGradient(-barrelW / 2, 0, barrelW / 2, 0); barrelGrad.addColorStop(0, '#6B4A08'); barrelGrad.addColorStop(0.3, '#B8860B'); barrelGrad.addColorStop(0.5, '#FFF3A8'); barrelGrad.addColorStop(0.7, '#B8860B'); barrelGrad.addColorStop(1, '#6B4A08'); ctx.fillStyle = barrelGrad; this._roundRect(ctx, -barrelW / 2, barrelY, barrelW, barrelH, 1.5); ctx.fill(); ctx.restore(); // Barrel outline ctx.strokeStyle = 'rgba(255, 235, 150, 0.55)'; ctx.lineWidth = 0.6; this._roundRect(ctx, -barrelW / 2, barrelY, barrelW, barrelH, 1.5); ctx.stroke(); // ── 10. MUZZLE TIP (flared end with glow) ── ctx.save(); ctx.shadowColor = '#FFF3A8'; ctx.shadowBlur = 5 + pulse * 3; ctx.fillStyle = '#2A1D05'; this._roundRect(ctx, -barrelW / 2 - 1, barrelY - 2, barrelW + 2, 3, 1); ctx.fill(); ctx.restore(); // Muzzle inner bright dot ctx.fillStyle = `rgba(255, 240, 150, ${0.6 + pulse * 0.4})`; ctx.beginPath(); ctx.arc(0, barrelY - 0.5, 1, 0, Math.PI * 2); ctx.fill(); // ── 11. HEADLIGHTS (front of tank — 2 small glowing dots) ── ctx.fillStyle = `rgba(255, 255, 200, ${0.7 + pulse * 0.3})`; ctx.shadowColor = '#FFF3A8'; ctx.shadowBlur = 4; ctx.beginPath(); ctx.arc(-s * 0.55, -s + 2.5, 1.3, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.arc(s * 0.55, -s + 2.5, 1.3, 0, Math.PI * 2); ctx.fill(); ctx.shadowBlur = 0; ctx.restore(); }, // ---- Utility ---- _roundRect(ctx, x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x + r, y); ctx.lineTo(x + w - r, y); ctx.arcTo(x + w, y, x + w, y + r, r); ctx.lineTo(x + w, y + h - r); ctx.arcTo(x + w, y + h, x + w - r, y + h, r); ctx.lineTo(x + r, y + h); ctx.arcTo(x, y + h, x, y + h - r, r); ctx.lineTo(x, y + r); ctx.arcTo(x, y, x + r, y, r); ctx.closePath(); }, // ============================================================ // Player Profile (nickname acquisition) // ============================================================ /** * Load avatar image from URL for Canvas rendering. * @param {string} url * @private */ _loadAvatarImage(url) { if (!url || this._avatarImg) return; try { const img = wx.createImage(); img.onload = () => { this._avatarImg = img; }; img.onerror = () => { console.warn('[MenuScene] Failed to load avatar image'); }; img.src = url; } catch (e) { console.warn('[MenuScene] _loadAvatarImage error:', e && e.message); } }, /** * Kick off profile acquisition on menu enter. * * Since WeChat 2022-10, `wx.getUserInfo` returns "scope unauthorized" — * the ONLY way to get the real nickname + avatar is `wx.createUserInfoButton`. * We create a transparent overlay button that covers the avatar area in the * top-left corner. When the user taps their avatar, WeChat returns the real * profile data. * @private */ _initPlayerProfile() { const profile = GameGlobal.playerProfile; if (!profile) return; // If already granted (from a previous session's cache), no button needed if (profile.granted) return; // Layout must match the avatar area drawn in render(): // avatarX=10, avatarY=10, avatarSize=28 + nickname text area const avatarLayout = { x: 8, y: 8, width: 120, height: 32, }; // Create the UserInfoButton — visible style covering avatar + nickname area if (typeof profile.fetchSilent === 'function') { profile.fetchSilent(avatarLayout).then((ok) => { console.log('[MenuScene] fetchSilent completed, granted=', ok); if (ok) { // Button was tapped and profile was granted — destroy it profile.destroyUserInfoButton(); } }).catch((e) => { console.warn('[MenuScene] fetchSilent error:', e); }); } }, // ============================================================ // Touch // ============================================================ handleTouch(eventType, e) { if (eventType === 'touchstart') { const touch = e.touches[0]; const tx = touch.clientX; const ty = touch.clientY; for (let i = 0; i < buttonRects.length; i++) { const btn = buttonRects[i]; if (tx >= btn.x && tx <= btn.x + btn.w && ty >= btn.y && ty <= btn.y + btn.h) { this._pressedIndex = i; break; } } } else if (eventType === 'touchend') { if (this._pressedIndex >= 0) { const btn = buttonRects[this._pressedIndex]; this._pressedIndex = -1; const sm = GameGlobal.sceneManager; if (btn.scene === SCENE.GAME) { if (!sm._scenes.has(SCENE.BUFF_SELECT)) { const BuffSelectScene = require('./BuffSelectScene'); sm.register(SCENE.BUFF_SELECT, BuffSelectScene); } sm.switchTo(SCENE.BUFF_SELECT, { mode: btn.mode }); } else if (btn.scene === 'DAILY_GOLD') { const adm = GameGlobal.adManager; if (adm && adm.getDailyGoldRemaining() > 0) { adm.showDailyGoldAd((completed) => { if (completed) { try { wx.showToast({ title: t('dailyGold.reward') || '+100 Gold!', icon: 'none', duration: 1500 }); } catch (e) {} } }); } } else if (btn.scene === SCENE.SHOP) { if (!sm._scenes.has(SCENE.SHOP)) { const ShopScene = require('./ShopScene'); sm.register(SCENE.SHOP, ShopScene); } sm.switchTo(SCENE.SHOP); } else if (btn.scene === SCENE.SKIN) { if (!sm._scenes.has(SCENE.SKIN)) { const SkinScene = require('./SkinScene'); sm.register(SCENE.SKIN, SkinScene); } sm.switchTo(SCENE.SKIN); } else if (btn.scene === SCENE.SETTINGS) { if (!sm._scenes.has(SCENE.SETTINGS)) { const SettingsScene = require('./SettingsScene'); sm.register(SCENE.SETTINGS, SettingsScene); } sm.switchTo(SCENE.SETTINGS); } else if (btn.scene === SCENE.RANKING) { if (!sm._scenes.has(SCENE.RANKING)) { const RankingScene = require('./RankingScene'); sm.register(SCENE.RANKING, RankingScene); } sm.switchTo(SCENE.RANKING); } else if (btn.scene === SCENE.PVP_ROOM) { if (!sm._scenes.has(SCENE.PVP_ROOM)) { const RoomScene = require('./RoomScene'); sm.register(SCENE.PVP_ROOM, RoomScene); } sm.switchTo(SCENE.PVP_ROOM); } else if (btn.scene === SCENE.TEAM_ROOM) { if (!sm._scenes.has(SCENE.TEAM_ROOM)) { const TeamRoomScene = require('./TeamRoomScene'); sm.register(SCENE.TEAM_ROOM, TeamRoomScene); } sm.switchTo(SCENE.TEAM_ROOM); } } } }, }; module.exports = MenuScene;