/** * RankingScene.js * Ranking/leaderboard scene. * In production, this would use WeChat Open Data Domain (SharedCanvas). * For now, displays local high scores with a placeholder for friend rankings. */ const { SCREEN_WIDTH, SCREEN_HEIGHT, COLORS, SCENE, GAME_MODE, } = require('../base/GameGlobal'); const { t } = require('../i18n/I18n'); const StorageManager = require('../managers/StorageManager'); const RankingScene = { _storage: null, _scores: [], _buttons: {}, enter() { this._storage = new StorageManager(); this._buttons = {}; // Load local scores this._scores = [ { label: t('ranking.classicHigh'), score: this._storage.getHighScore(GAME_MODE.CLASSIC), }, { label: t('ranking.endlessHigh'), score: this._storage.getHighScore(GAME_MODE.ENDLESS), }, { label: t('ranking.highestLevel'), score: this._storage.getHighestLevel(), suffix: t('ranking.levelSuffix'), }, ]; }, exit() {}, update(dt) {}, render(ctx) { // Background ctx.fillStyle = COLORS.MENU_BG; ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); const cx = SCREEN_WIDTH / 2; let y = 60; // Title ctx.fillStyle = COLORS.MENU_TITLE; ctx.font = 'bold 28px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(t('ranking.title'), cx, y); y += 60; // Local scores section ctx.fillStyle = '#AAAAAA'; ctx.font = '14px Arial'; ctx.fillText(t('ranking.personalRecord'), cx, y); y += 40; for (const item of this._scores) { // Card background const cardW = SCREEN_WIDTH * 0.75; const cardH = 55; const cardX = cx - cardW / 2; ctx.fillStyle = '#1e1e3a'; ctx.fillRect(cardX, y - cardH / 2, cardW, cardH); ctx.strokeStyle = '#333366'; ctx.lineWidth = 1; ctx.strokeRect(cardX, y - cardH / 2, cardW, cardH); // Label ctx.fillStyle = COLORS.HUD_TEXT; ctx.font = '14px Arial'; ctx.textAlign = 'left'; ctx.fillText(item.label, cardX + 15, y - 5); // Score ctx.fillStyle = '#FFD700'; ctx.font = 'bold 18px Arial'; ctx.textAlign = 'right'; const suffix = item.suffix || t('ranking.scoreSuffix'); ctx.fillText(`${item.score} ${suffix}`, cardX + cardW - 15, y + 2); y += 70; } y += 20; // Friend ranking placeholder ctx.fillStyle = '#666666'; ctx.font = '13px Arial'; ctx.textAlign = 'center'; ctx.fillText(t('ranking.friendHint'), cx, y); ctx.fillText('(SharedCanvas)', cx, y + 20); // Back button y = SCREEN_HEIGHT - 80; const btnW = SCREEN_WIDTH * 0.4; const btnH = 42; const btnX = cx - btnW / 2; this._buttons['back'] = { x: btnX, y: y - btnH / 2, w: btnW, h: btnH }; ctx.fillStyle = COLORS.MENU_BTN; ctx.strokeStyle = COLORS.MENU_BTN_BORDER; ctx.lineWidth = 2; ctx.fillRect(btnX, y - btnH / 2, btnW, btnH); ctx.strokeRect(btnX, y - btnH / 2, btnW, btnH); ctx.fillStyle = COLORS.MENU_BTN_TEXT; ctx.font = 'bold 16px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(t('common.back'), cx, y); }, handleTouch(eventType, e) { if (eventType !== 'touchstart') return; const touch = e.touches[0]; const tx = touch.clientX; const ty = touch.clientY; const back = this._buttons['back']; if (back && tx >= back.x && tx <= back.x + back.w && ty >= back.y && ty <= back.y + back.h) { GameGlobal.sceneManager.switchTo(SCENE.MENU); } }, }; module.exports = RankingScene;