first commit
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* SettingsScene.js
|
||||
* Settings screen with sound, music, and vibration toggles.
|
||||
*/
|
||||
|
||||
const {
|
||||
SCREEN_WIDTH,
|
||||
SCREEN_HEIGHT,
|
||||
COLORS,
|
||||
SCENE,
|
||||
} = require('../base/GameGlobal');
|
||||
const { t } = require('../i18n/I18n');
|
||||
|
||||
const SettingsScene = {
|
||||
_settings: {
|
||||
soundEnabled: true,
|
||||
musicEnabled: true,
|
||||
vibrationEnabled: true,
|
||||
},
|
||||
_buttons: {},
|
||||
|
||||
enter() {
|
||||
// Load settings from storage
|
||||
try {
|
||||
const saved = wx.getStorageSync('game_settings');
|
||||
if (saved) {
|
||||
this._settings = { ...this._settings, ...JSON.parse(saved) };
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[Settings] Failed to load settings:', e);
|
||||
}
|
||||
this._buttons = {};
|
||||
},
|
||||
|
||||
exit() {
|
||||
// Save settings
|
||||
try {
|
||||
wx.setStorageSync('game_settings', JSON.stringify(this._settings));
|
||||
} catch (e) {
|
||||
console.warn('[Settings] Failed to save settings:', e);
|
||||
}
|
||||
},
|
||||
|
||||
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('settings.title'), cx, y);
|
||||
|
||||
y += 70;
|
||||
|
||||
// Toggle items
|
||||
const toggles = [
|
||||
{ key: 'soundEnabled', label: t('settings.sound'), icon: '🔊' },
|
||||
{ key: 'musicEnabled', label: t('settings.music'), icon: '🎵' },
|
||||
{ key: 'vibrationEnabled', label: t('settings.vibration'), icon: '📳' },
|
||||
];
|
||||
|
||||
for (const toggle of toggles) {
|
||||
this._renderToggle(ctx, cx, y, toggle);
|
||||
y += 70;
|
||||
}
|
||||
|
||||
// Back button
|
||||
y = SCREEN_HEIGHT - 80;
|
||||
this._renderBackButton(ctx, cx, y);
|
||||
},
|
||||
|
||||
_renderToggle(ctx, cx, y, toggle) {
|
||||
const w = SCREEN_WIDTH * 0.7;
|
||||
const h = 50;
|
||||
const x = cx - w / 2;
|
||||
const isOn = this._settings[toggle.key];
|
||||
|
||||
// Store button rect
|
||||
this._buttons[toggle.key] = { x, y: y - h / 2, w, h };
|
||||
|
||||
// Background
|
||||
ctx.fillStyle = '#1e1e3a';
|
||||
ctx.fillRect(x, y - h / 2, w, h);
|
||||
ctx.strokeStyle = '#333366';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeRect(x, y - h / 2, w, h);
|
||||
|
||||
// Icon and label
|
||||
ctx.fillStyle = COLORS.HUD_TEXT;
|
||||
ctx.font = '16px Arial';
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillText(`${toggle.icon} ${toggle.label}`, x + 15, y);
|
||||
|
||||
// Toggle switch
|
||||
const switchW = 50;
|
||||
const switchH = 26;
|
||||
const switchX = x + w - switchW - 15;
|
||||
const switchY = y - switchH / 2;
|
||||
|
||||
// Switch track
|
||||
ctx.fillStyle = isOn ? '#4CAF50' : '#555555';
|
||||
ctx.beginPath();
|
||||
ctx.arc(switchX + switchH / 2, y, switchH / 2, Math.PI / 2, Math.PI * 3 / 2);
|
||||
ctx.arc(switchX + switchW - switchH / 2, y, switchH / 2, -Math.PI / 2, Math.PI / 2);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
|
||||
// Switch knob
|
||||
ctx.fillStyle = '#FFFFFF';
|
||||
ctx.beginPath();
|
||||
const knobX = isOn ? switchX + switchW - switchH / 2 : switchX + switchH / 2;
|
||||
ctx.arc(knobX, y, switchH / 2 - 3, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
},
|
||||
|
||||
_renderBackButton(ctx, cx, y) {
|
||||
const w = SCREEN_WIDTH * 0.4;
|
||||
const h = 42;
|
||||
const x = cx - w / 2;
|
||||
|
||||
this._buttons['back'] = { x, y: y - h / 2, w, h };
|
||||
|
||||
ctx.fillStyle = COLORS.MENU_BTN;
|
||||
ctx.strokeStyle = COLORS.MENU_BTN_BORDER;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.fillRect(x, y - h / 2, w, h);
|
||||
ctx.strokeRect(x, y - h / 2, w, h);
|
||||
|
||||
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;
|
||||
|
||||
for (const [key, rect] of Object.entries(this._buttons)) {
|
||||
if (tx >= rect.x && tx <= rect.x + rect.w && ty >= rect.y && ty <= rect.y + rect.h) {
|
||||
if (key === 'back') {
|
||||
GameGlobal.sceneManager.switchTo(SCENE.MENU);
|
||||
} else if (this._settings.hasOwnProperty(key)) {
|
||||
this._settings[key] = !this._settings[key];
|
||||
// Notify audio system
|
||||
GameGlobal.eventBus.emit('settings:changed', this._settings);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = SettingsScene;
|
||||
Reference in New Issue
Block a user