Ui Components
Π ΡΡΠΎΠΌ ΡΠ°Π·Π΄Π΅Π»Π΅ ΠΎΠΏΠΈΡΡΠ²Π°ΡΡΡΡ Π³ΠΎΡΠΎΠ²ΡΠ΅ UI ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ Π±ΡΡΡΡΠΎΠ³ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π²Π΅Π±-ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² Π² Wudgine.
ΠΠ²Π΅Π΄Π΅Π½ΠΈΠ΅
Wudgine ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π½Π°Π±ΠΎΡ Π³ΠΎΡΠΎΠ²ΡΡ UI ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠΌΠΎΠ³ΡΡ Π²Π°ΠΌ Π±ΡΡΡΡΠΎ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠ΅ ΠΈΠ³ΡΠΎΠ²ΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ. ΠΡΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Ρ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ Π΄Π²ΠΈΠΆΠΊΠΎΠΌ ΠΈ ΡΠ»Π΅Π΄ΡΡΡ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΈΠ³ΡΠΎΠ²ΡΡ UI.
ΠΠ°Π·ΠΎΠ²ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ
ΠΠ½ΠΎΠΏΠΊΠΈ
<button class="wg-button wg-button-primary">ΠΠ°ΡΠ°ΡΡ ΠΈΠ³ΡΡ</button>
<button class="wg-button wg-button-secondary">ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ</button>
<button class="wg-button wg-button-danger">ΠΡΡ
ΠΎΠ΄</button>
ΠΠΎΡΡΡΠΏΠ½ΡΠ΅ ΠΊΠ»Π°ΡΡΡ Π΄Π»Ρ ΠΊΠ½ΠΎΠΏΠΎΠΊ:
wg-button-primary
- ΠΎΡΠ½ΠΎΠ²Π½Π°Ρ ΠΊΠ½ΠΎΠΏΠΊΠ°wg-button-secondary
- Π²ΡΠΎΡΠΎΡΡΠ΅ΠΏΠ΅Π½Π½Π°Ρ ΠΊΠ½ΠΎΠΏΠΊΠ°wg-button-danger
- ΠΊΠ½ΠΎΠΏΠΊΠ° Π΄Π»Ρ ΠΎΠΏΠ°ΡΠ½ΡΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉwg-button-small
- ΠΌΠ°Π»Π΅Π½ΡΠΊΠ°Ρ ΠΊΠ½ΠΎΠΏΠΊΠ°wg-button-large
- Π±ΠΎΠ»ΡΡΠ°Ρ ΠΊΠ½ΠΎΠΏΠΊΠ°wg-button-disabled
- ΠΎΡΠΊΠ»ΡΡΠ΅Π½Π½Π°Ρ ΠΊΠ½ΠΎΠΏΠΊΠ°
ΠΠ°Π½Π΅Π»ΠΈ
<div class="wg-panel">
<div class="wg-panel-header">ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΏΠ°Π½Π΅Π»ΠΈ</div>
<div class="wg-panel-body">
Π‘ΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΠΏΠ°Π½Π΅Π»ΠΈ
</div>
<div class="wg-panel-footer">
<button class="wg-button wg-button-primary">OK</button>
<button class="wg-button wg-button-secondary">ΠΡΠΌΠ΅Π½Π°</button>
</div>
</div>
ΠΠ½Π΄ΠΈΠΊΠ°ΡΠΎΡΡ ΠΏΡΠΎΠ³ΡΠ΅ΡΡΠ°
<!-- ΠΡΠΎΡΡΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ΅ΡΡ-Π±Π°Ρ -->
<div class="wg-progress">
<div class="wg-progress-bar" style="width: 75%"></div>
</div>
<!-- ΠΡΠΎΠ³ΡΠ΅ΡΡ-Π±Π°Ρ Ρ ΡΠ΅ΠΊΡΡΠΎΠΌ -->
<div class="wg-progress">
<div class="wg-progress-bar" style="width: 75%">75%</div>
</div>
<!-- ΠΡΠΎΠ³ΡΠ΅ΡΡ-Π±Π°Ρ Ρ Π΄Π²ΡΠΌΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π·Π΄ΠΎΡΠΎΠ²ΡΠ΅/ΠΌΠ°Π½Π°) -->
<div class="wg-progress wg-progress-dual">
<div class="wg-progress-bar wg-progress-primary" style="width: 60%"></div>
<div class="wg-progress-bar wg-progress-secondary" style="width: 40%"></div>
</div>
Π‘Π»ΠΎΡΡ ΠΈΠ½Π²Π΅Π½ΡΠ°ΡΡ
<div class="wg-inventory-grid">
<div class="wg-inventory-slot">
<div class="wg-item" data-item-id="sword_01">
<img src="items/sword.png" alt="ΠΠ΅Ρ">
<span class="wg-item-count">1</span>
</div>
</div>
<div class="wg-inventory-slot"></div>
<div class="wg-inventory-slot">
<div class="wg-item" data-item-id="potion_health">
<img src="items/health_potion.png" alt="ΠΠ΅Π»ΡΠ΅ Π·Π΄ΠΎΡΠΎΠ²ΡΡ">
<span class="wg-item-count">5</span>
</div>
</div>
<!-- ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΠ»ΠΎΡΡ -->
</div>
ΠΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΡΠ΅ ΠΎΠΊΠ½Π°
<div class="wg-dialog" id="confirmDialog">
<div class="wg-dialog-content">
<div class="wg-dialog-header">
<h3>ΠΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅</h3>
<button class="wg-dialog-close">×</button>
</div>
<div class="wg-dialog-body">
<p>ΠΡ ΡΠ²Π΅ΡΠ΅Π½Ρ, ΡΡΠΎ Ρ
ΠΎΡΠΈΡΠ΅ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ?</p>
</div>
<div class="wg-dialog-footer">
<button class="wg-button wg-button-primary" id="confirmYes">ΠΠ°</button>
<button class="wg-button wg-button-secondary" id="confirmNo">ΠΠ΅Ρ</button>
</div>
</div>
</div>
// ΠΠΎΠΊΠ°Π·Π°ΡΡ Π΄ΠΈΠ°Π»ΠΎΠ³
document.getElementById('confirmDialog').classList.add('wg-dialog-visible');
// Π‘ΠΊΡΡΡΡ Π΄ΠΈΠ°Π»ΠΎΠ³
document.getElementById('confirmDialog').classList.remove('wg-dialog-visible');
ΠΡΠΏΠ»ΡΠ²Π°ΡΡΠΈΠ΅ ΠΏΠΎΠ΄ΡΠΊΠ°Π·ΠΊΠΈ
<div class="wg-tooltip-container">
<button class="wg-button wg-button-primary">ΠΠ°Π²ΡΠΊ</button>
<div class="wg-tooltip">
<h4>ΠΠ³Π½Π΅Π½Π½ΡΠΉ ΡΠ°Ρ</h4>
<p>ΠΠ°Π½ΠΎΡΠΈΡ 50-75 ΡΡΠΎΠ½Π° ΠΎΠ³Π½Π΅ΠΌ</p>
<p class="wg-tooltip-cooldown">ΠΠ΅ΡΠ΅Π·Π°ΡΡΠ΄ΠΊΠ°: 30 ΡΠ΅ΠΊ</p>
</div>
</div>
HUD ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ
ΠΠΈΠ½ΠΈΠΊΠ°ΡΡΠ°
<div class="wg-minimap">
<div class="wg-minimap-container">
<!-- ΠΠ΄Π΅ΡΡ Π±ΡΠ΄Π΅Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡΡΡ ΠΊΠ°ΡΡΠ° -->
</div>
<div class="wg-minimap-controls">
<button class="wg-minimap-zoom-in">+</button>
<button class="wg-minimap-zoom-out">-</button>
</div>
</div>
class Minimap {
constructor(options = {}) {
this.container = document.querySelector(options.container || '.wg-minimap-container');
this.scale = options.initialScale || 1.0;
this.playerMarker = null;
this.markers = new Map();
this.initialize();
}
initialize() {
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΌΠ°ΡΠΊΠ΅ΡΠ° ΠΈΠ³ΡΠΎΠΊΠ°
this.playerMarker = document.createElement('div');
this.playerMarker.className = 'wg-minimap-player-marker';
this.container.appendChild(this.playerMarker);
// ΠΠΎΠ΄ΠΏΠΈΡΠΊΠ° Π½Π° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ ΠΈΠ³ΡΠΎΠΊΠ°
engine.subscribe('playerPositionChanged', (data) => {
this.updatePlayerPosition(data.x, data.y);
});
// ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ
document.querySelector('.wg-minimap-zoom-in').addEventListener('click', () => {
this.setScale(this.scale + 0.1);
});
document.querySelector('.wg-minimap-zoom-out').addEventListener('click', () => {
this.setScale(this.scale - 0.1);
});
}
updatePlayerPosition(x, y) {
// ΠΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ ΠΈΠ³ΡΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠΈΡΠ° Π² ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ ΠΌΠΈΠ½ΠΈΠΊΠ°ΡΡΡ
const mapX = x * this.scale;
const mapY = y * this.scale;
this.playerMarker.style.transform = `translate(${mapX}px, ${mapY}px)`;
}
setScale(newScale) {
// ΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΠΌΠ°ΡΡΡΠ°Π±Π°
this.scale = Math.max(0.5, Math.min(2.0, newScale));
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ
this.container.style.transform = `scale(${this.scale})`;
}
addMarker(id, x, y, type = 'default') {
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΌΠ°ΡΠΊΠ΅ΡΠ° Π½Π° ΠΊΠ°ΡΡΠ΅
const marker = document.createElement('div');
marker.className = `wg-minimap-marker wg-minimap-marker-${type}`;
marker.style.transform = `translate(${x * this.scale}px, ${y * this.scale}px)`;
this.container.appendChild(marker);
this.markers.set(id, marker);
return marker;
}
removeMarker(id) {
const marker = this.markers.get(id);
if (marker) {
marker.remove();
this.markers.delete(id);
}
}
}
ΠΠ½Π΄ΠΈΠΊΠ°ΡΠΎΡΡ Π·Π΄ΠΎΡΠΎΠ²ΡΡ ΠΈ ΡΠ΅ΡΡΡΡΠΎΠ²
<div class="wg-player-stats">
<div class="wg-stat-container">
<div class="wg-stat-label">ΠΠ΄ΠΎΡΠΎΠ²ΡΠ΅</div>
<div class="wg-progress">
<div class="wg-progress-bar wg-health-bar" style="width: 75%">750/1000</div>
</div>
</div>
<div class="wg-stat-container">
<div class="wg-stat-label">ΠΠ°Π½Π°</div>
<div class="wg-progress">
<div class="wg-progress-bar wg-mana-bar" style="width: 50%">250/500</div>
</div>
</div>
<div class="wg-stat-container">
<div class="wg-stat-label">ΠΡΠ½ΠΎΡΠ»ΠΈΠ²ΠΎΡΡΡ</div>
<div class="wg-progress">
<div class="wg-progress-bar wg-stamina-bar" style="width: 90%">90/100</div>
</div>
</div>
</div>
class PlayerStatsUI {
constructor() {
this.healthBar = document.querySelector('.wg-health-bar');
this.manaBar = document.querySelector('.wg-mana-bar');
this.staminaBar = document.querySelector('.wg-stamina-bar');
this.initialize();
}
initialize() {
// ΠΠΎΠ΄ΠΏΠΈΡΠΊΠ° Π½Π° ΡΠΎΠ±ΡΡΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Ρ
Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊ ΠΈΠ³ΡΠΎΠΊΠ°
engine.subscribe('playerStatsChanged', (data) => {
this.updateStats(data);
});
// ΠΠ°ΡΠ°Π»ΡΠ½ΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅
this.updateStats(engine.call('getPlayerStats'));
}
updateStats(stats) {
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»ΠΎΡΡ Π·Π΄ΠΎΡΠΎΠ²ΡΡ
const healthPercent = (stats.currentHealth / stats.maxHealth) * 100;
this.healthBar.style.width = `${healthPercent}%`;
this.healthBar.textContent = `${stats.currentHealth}/${stats.maxHealth}`;
// ΠΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ²Π΅ΡΠ° ΠΏΡΠΈ Π½ΠΈΠ·ΠΊΠΎΠΌ Π·Π΄ΠΎΡΠΎΠ²ΡΠ΅
if (healthPercent < 25) {
this.healthBar.classList.add('wg-critical');
} else {
this.healthBar.classList.remove('wg-critical');
}
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»ΠΎΡΡ ΠΌΠ°Π½Ρ
const manaPercent = (stats.currentMana / stats.maxMana) * 100;
this.manaBar.style.width = `${manaPercent}%`;
this.manaBar.textContent = `${stats.currentMana}/${stats.maxMana}`;
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»ΠΎΡΡ Π²ΡΠ½ΠΎΡΠ»ΠΈΠ²ΠΎΡΡΠΈ
const staminaPercent = (stats.currentStamina / stats.maxStamina) * 100;
this.staminaBar.style.width = `${staminaPercent}%`;
this.staminaBar.textContent = `${stats.currentStamina}/${stats.maxStamina}`;
}
}
ΠΠ°Π½Π΅Π»Ρ Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉ
<div class="wg-action-bar">
<div class="wg-action-slot" data-slot="1">
<img src="skills/fireball.png" alt="ΠΠ³Π½Π΅Π½Π½ΡΠΉ ΡΠ°Ρ">
<span class="wg-action-keybind">1</span>
<div class="wg-action-cooldown" style="height: 30%"></div>
</div>
<div class="wg-action-slot" data-slot="2">
<img src="skills/heal.png" alt="ΠΡΡΠ΅Π»Π΅Π½ΠΈΠ΅">
<span class="wg-action-keybind">2</span>
</div>
<!-- ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΠ»ΠΎΡΡ -->
</div>
class ActionBar {
constructor() {
this.slots = document.querySelectorAll('.wg-action-slot');
this.cooldowns = new Map();
this.initialize();
}
initialize() {
// ΠΠΎΠ΄ΠΏΠΈΡΠΊΠ° Π½Π° ΡΠΎΠ±ΡΡΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠ΅ΠΉ
engine.subscribe('abilityCooldownChanged', (data) => {
this.updateCooldown(data.slotIndex, data.remainingCooldown, data.totalCooldown);
});
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π°ΠΆΠ°ΡΠΈΠΉ Π½Π° ΡΠ»ΠΎΡΡ
this.slots.forEach(slot => {
slot.addEventListener('click', () => {
const slotIndex = parseInt(slot.dataset.slot);
this.activateAbility(slotIndex);
});
});
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π°ΠΆΠ°ΡΠΈΠΉ ΠΊΠ»Π°Π²ΠΈΡ
document.addEventListener('keydown', (e) => {
// ΠΡΠΎΠ²Π΅ΡΠΊΠ°, ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈ Π½Π°ΠΆΠ°ΡΠ°Ρ ΠΊΠ»Π°Π²ΠΈΡΠ° ΡΠΈΡΡΠΎΠΉ ΠΎΡ 1 Π΄ΠΎ 9
if (e.key >= '1' && e.key <= '9') {
const slotIndex = parseInt(e.key);
this.activateAbility(slotIndex);
}
});
}
activateAbility(slotIndex) {
// ΠΡΠΎΠ²Π΅ΡΠΊΠ°, Π½Π΅ Π½Π° ΠΏΠ΅ΡΠ΅Π·Π°ΡΡΠ΄ΠΊΠ΅ Π»ΠΈ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΡ
if (this.cooldowns.has(slotIndex)) {
return;
}
// ΠΡΠ·ΠΎΠ² ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ ΡΠ΅ΡΠ΅Π· Π΄Π²ΠΈΠΆΠΎΠΊ
const result = engine.call('activateAbility', { slotIndex });
if (result.success) {
// ΠΡΠ»ΠΈ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΡ ΡΡΠΏΠ΅ΡΠ½ΠΎ Π°ΠΊΡΠΈΠ²ΠΈΡΠΎΠ²Π°Π½Π°, Π½Π°ΡΠΈΠ½Π°Π΅ΠΌ ΠΎΡΡΡΠ΅Ρ ΠΏΠ΅ΡΠ΅Π·Π°ΡΡΠ΄ΠΊΠΈ
if (result.cooldown > 0) {
this.updateCooldown(slotIndex, result.cooldown, result.cooldown);
}
}
}
updateCooldown(slotIndex, remainingCooldown, totalCooldown) {
const slot = document.querySelector(`.wg-action-slot[data-slot="${slotIndex}"]`);
if (!slot) return;
const cooldownOverlay = slot.querySelector('.wg-action-cooldown');
if (remainingCooldown <= 0) {
// ΠΠ΅ΡΠ΅Π·Π°ΡΡΠ΄ΠΊΠ° Π·Π°Π²Π΅ΡΡΠ΅Π½Π°
cooldownOverlay.style.height = '0%';
this.cooldowns.delete(slotIndex);
} else {
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΈΠ½Π΄ΠΈΠΊΠ°ΡΠΎΡΠ° ΠΏΠ΅ΡΠ΅Π·Π°ΡΡΠ΄ΠΊΠΈ
const percent = (remainingCooldown / totalCooldown) * 100;
cooldownOverlay.style.height = `${percent}%`;
// Π‘ΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΎ ΠΏΠ΅ΡΠ΅Π·Π°ΡΡΠ΄ΠΊΠ΅
this.cooldowns.set(slotIndex, {
remaining: remainingCooldown,
total: totalCooldown
});
// Π£ΠΌΠ΅Π½ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΡΡΠ°Π²ΡΠ΅Π³ΠΎΡΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ
setTimeout(() => {
this.updateCooldown(slotIndex, remainingCooldown - 0.1, totalCooldown);
}, 100);
}
}
}
ΠΠ΅Π½Ρ ΠΈ ΡΠΊΡΠ°Π½Ρ
ΠΠ»Π°Π²Π½ΠΎΠ΅ ΠΌΠ΅Π½Ρ
<div class="wg-main-menu">
<div class="wg-menu-logo">
<img src="logo.png" alt="ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ ΠΈΠ³ΡΡ">
</div>
<div class="wg-menu-buttons">
<button class="wg-button wg-button-primary wg-button-large" id="btnPlay">ΠΠ³ΡΠ°ΡΡ</button>
<button class="wg-button wg-button-primary wg-button-large" id="btnContinue">ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ</button>
<button class="wg-button wg-button-secondary wg-button-large" id="btnSettings">ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ</button>
<button class="wg-button wg-button-secondary wg-button-large" id="btnCredits">ΠΠ²ΡΠΎΡΡ</button>
<button class="wg-button wg-button-danger wg-button-large" id="btnExit">ΠΡΡ
ΠΎΠ΄</button>
</div>
<div class="wg-menu-footer">
<p>ΠΠ΅ΡΡΠΈΡ 1.0.0</p>
<p>© 2023 Wudgine Studios</p>
</div>
</div>
class MainMenu {
constructor() {
this.initialize();
}
initialize() {
// ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π°Π»ΠΈΡΠΈΡ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠΉ
const hasSaveGame = engine.call('checkSaveGame');
// ΠΠΎΠΊΠ°Π·Π°ΡΡ/ΡΠΊΡΡΡΡ ΠΊΠ½ΠΎΠΏΠΊΡ "ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ"
const continueButton = document.getElementById('btnContinue');
continueButton.style.display = hasSaveGame ? 'block' : 'none';
// ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² ΡΠΎΠ±ΡΡΠΈΠΉ
document.getElementById('btnPlay').addEventListener('click', () => {
engine.call('startNewGame');
});
document.getElementById('btnContinue').addEventListener('click', () => {
engine.call('loadGame');
});
document.getElementById('btnSettings').addEventListener('click', () => {
engine.call('showSettings');
});
document.getElementById('btnCredits').addEventListener('click', () => {
engine.call('showCredits');
});
document.getElementById('btnExit').addEventListener('click', () => {
engine.call('exitGame');
});
}
}
ΠΠΊΡΠ°Π½ Π½Π°ΡΡΡΠΎΠ΅ΠΊ
<div class="wg-settings-screen">
<div class="wg-panel">
<div class="wg-panel-header">
<h2>ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ</h2>
<button class="wg-panel-close" id="btnCloseSettings">×</button>
</div>
<div class="wg-panel-body">
<div class="wg-tabs">
<div class="wg-tab-buttons">
<button class="wg-tab-button active" data-tab="graphics">ΠΡΠ°ΡΠΈΠΊΠ°</button>
<button class="wg-tab-button" data-tab="audio">ΠΠ²ΡΠΊ</button>
<button class="wg-tab-button" data-tab="controls">Π£ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅</button>
<button class="wg-tab-button" data-tab="gameplay">ΠΠ΅ΠΉΠΌΠΏΠ»Π΅ΠΉ</button>
</div>
<div class="wg-tab-content">
<div class="wg-tab-pane active" id="graphics">
<!-- ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ Π³ΡΠ°ΡΠΈΠΊΠΈ -->
<div class="wg-setting-row">
<label for="resolution">Π Π°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠ΅:</label>
<select id="resolution" class="wg-select">
<option value="1920x1080">1920x1080</option>
<option value="1280x720">1280x720</option>
<!-- ΠΡΡΠ³ΠΈΠ΅ Π²Π°ΡΠΈΠ°Π½ΡΡ -->
</select>
</div>
<div class="wg-setting-row">
<label for="quality">ΠΠ°ΡΠ΅ΡΡΠ²ΠΎ Π³ΡΠ°ΡΠΈΠΊΠΈ:</label>
<select id="quality" class="wg-select">
<option value="low">ΠΠΈΠ·ΠΊΠΎΠ΅</option>
<option value="medium">Π‘ΡΠ΅Π΄Π½Π΅Π΅</option>
<option value="high">ΠΡΡΠΎΠΊΠΎΠ΅</option>
<option value="ultra">Π£Π»ΡΡΡΠ°</option>
</select>
</div>
<div class="wg-setting-row">
<label for="fullscreen">ΠΠΎΠ»Π½ΠΎΡΠΊΡΠ°Π½Π½ΡΠΉ ΡΠ΅ΠΆΠΈΠΌ:</label>
<input type="checkbox" id="fullscreen" class="wg-checkbox">
</div>
</div>
<!-- ΠΡΡΠ³ΠΈΠ΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Π½Π°ΡΡΡΠΎΠ΅ΠΊ -->
</div>
</div>
</div>
<div class="wg-panel-footer">
<button class="wg-button wg-button-primary" id="btnSaveSettings">Π‘ΠΎΡ
ΡΠ°Π½ΠΈΡΡ</button>
<button class="wg-button wg-button-secondary" id="btnResetSettings">Π‘Π±ΡΠΎΡΠΈΡΡ</button>
</div>
</div>
</div>
class SettingsScreen {
constructor() {
this.currentSettings = {};
this.initialize();
}
async initialize() {
// ΠΠ°Π³ΡΡΠ·ΠΊΠ° ΡΠ΅ΠΊΡΡΠΈΡ
Π½Π°ΡΡΡΠΎΠ΅ΠΊ
this.currentSettings = await engine.call('getSettings');
// ΠΠ°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Π΅ΠΉ ΡΠΎΡΠΌΡ
this.populateForm();
// ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π²ΠΊΠ»Π°Π΄ΠΎΠΊ
const tabButtons = document.querySelectorAll('.wg-tab-button');
tabButtons.forEach(button => {
button.addEventListener('click', () => {
// Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ Π°ΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° Ρ Π²ΡΠ΅Ρ
ΠΊΠ½ΠΎΠΏΠΎΠΊ ΠΈ ΠΏΠ°Π½Π΅Π»Π΅ΠΉ
document.querySelectorAll('.wg-tab-button').forEach(btn => {
btn.classList.remove('active');
});
document.querySelectorAll('.wg-tab-pane').forEach(pane => {
pane.classList.remove('active');
});
// ΠΠΊΡΠΈΠ²Π°ΡΠΈΡ Π²ΡΠ±ΡΠ°Π½Π½ΠΎΠΉ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ
button.classList.add('active');
const tabId = button.dataset.tab;
document.getElementById(tabId).classList.add('active');
});
});
// ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ
document.getElementById('btnCloseSettings').addEventListener('click', () => {
engine.call('hideSettings');
});
document.getElementById('btnSaveSettings').addEventListener('click', () => {
this.saveSettings();
});
document.getElementById('btnResetSettings').addEventListener('click', () => {
this.resetSettings();
});
}
populateForm() {
// ΠΠ°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Π΅ΠΉ ΡΠΎΡΠΌΡ ΡΠ΅ΠΊΡΡΠΈΠΌΠΈ Π½Π°ΡΡΡΠΎΠΉΠΊΠ°ΠΌΠΈ
document.getElementById('resolution').value = this.currentSettings.resolution;
document.getElementById('quality').value = this.currentSettings.quality;
document.getElementById('fullscreen').checked = this.currentSettings.fullscreen;
// ΠΠ°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄ΡΡΠ³ΠΈΡ
Π½Π°ΡΡΡΠΎΠ΅ΠΊ
// ...
}
async saveSettings() {
// Π‘Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ
ΠΈΠ· ΡΠΎΡΠΌΡ
const newSettings = {
resolution: document.getElementById('resolution').value,
quality: document.getElementById('quality').value,
fullscreen: document.getElementById('fullscreen').checked,
// ΠΡΡΠ³ΠΈΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ
};
// Π‘ΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ Π½Π°ΡΡΡΠΎΠ΅ΠΊ
const result = await engine.call('saveSettings', newSettings);
if (result.success) {
// ΠΠΎΠΊΠ°Π·Π°ΡΡ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΎΠ± ΡΡΠΏΠ΅ΡΠ½ΠΎΠΌ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠΈ
this.showNotification('ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΡΠΎΡ
ΡΠ°Π½Π΅Π½Ρ');
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΡΠΈΡ
Π½Π°ΡΡΡΠΎΠ΅ΠΊ
this.currentSettings = newSettings;
} else {
// ΠΠΎΠΊΠ°Π·Π°ΡΡ ΠΎΡΠΈΠ±ΠΊΡ
this.showNotification('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠΈ Π½Π°ΡΡΡΠΎΠ΅ΠΊ', 'error');
}
}
async resetSettings() {
// Π‘Π±ΡΠΎΡ Π½Π°ΡΡΡΠΎΠ΅ΠΊ ΠΊ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ
const defaultSettings = await engine.call('getDefaultSettings');
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠΎΡΠΌΡ
this.currentSettings = defaultSettings;
this.populateForm();
// ΠΠΎΠΊΠ°Π·Π°ΡΡ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅
this.showNotification('ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ ΡΠ±ΡΠΎΡΠ΅Π½Ρ ΠΊ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ');
}
showNotification(message, type = 'success') {
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ
const notification = document.createElement('div');
notification.className = `wg-notification wg-notification-${type}`;
notification.textContent = message;
// ΠΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° ΡΡΡΠ°Π½ΠΈΡΡ
document.body.appendChild(notification);
// Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΡΠ΅ΡΠ΅Π· 3 ΡΠ΅ΠΊΡΠ½Π΄Ρ
setTimeout(() => {
notification.classList.add('wg-notification-hide');
setTimeout(() => {
notification.remove();
}, 300);
}, 3000);
}
}