Documentation

Javascript Api

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ описываСтся JavaScript API, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт Π²Π΅Π±-интСрфСйсам Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ с Π΄Π²ΠΈΠΆΠΊΠΎΠΌ Wudgine.

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅

Wudgine прСдоставляСт ΠΌΠΎΡ‰Π½Ρ‹ΠΉ JavaScript API для взаимодСйствия Π²Π΅Π±-интСрфСйсов с Π΄Π²ΠΈΠΆΠΊΠΎΠΌ. Π­Ρ‚ΠΎΡ‚ API позволяСт Π²Π°ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ динамичСскиС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ интСрфСйсы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ с ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ, Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° события Π² ΠΈΠ³Ρ€Π΅ ΠΈ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΈΠ³Ρ€ΠΎΠ²Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ.

Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ engine

Основной Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ Π²Ρ…ΠΎΠ΄Π° Π² JavaScript API являСтся Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ engine, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ автоматичСски доступСн Π² любом Π²Π΅Π±-интСрфСйсС, Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠΌ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ WebUIComponent.

// ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования глобального ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° engine
const playerHealth = engine.call('getPlayerHealth');
console.log(`Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π΄ΠΎΡ€ΠΎΠ²ΡŒΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°: ${playerHealth}`);

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹

Π’Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ C++

/**
 * Π’Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ Π² C++
 * @param {string} functionName - Имя Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
 * @param {Object} params - ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ)
 * @returns {*} Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
 */
engine.call(functionName, params);

ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

// Π’Ρ‹Π·ΠΎΠ² C++ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²
const playerPosition = engine.call('getPlayerPosition');
console.log(`ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΈΠ³Ρ€ΠΎΠΊΠ°: ${playerPosition.x}, ${playerPosition.y}, ${playerPosition.z}`);

// Π’Ρ‹Π·ΠΎΠ² C++ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ
const damageResult = engine.call('applyDamage', {
  targetId: 'enemy_123',
  amount: 50,
  damageType: 'fire'
});

if (damageResult.success) {
  console.log(`НанСсСно ${damageResult.actualDamage} ΡƒΡ€ΠΎΠ½Π°!`);
}

РСгистрация JavaScript Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ

/**
 * РСгистрируСт JavaScript Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для Π²Ρ‹Π·ΠΎΠ²Π° ΠΈΠ· C++
 * @param {string} functionName - Имя Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
 * @param {Function} callback - Ѐункция ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°
 */
engine.register(functionName, callback);

ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

// РСгистрация Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для обновлСния интСрфСйса
engine.register('updateHealthUI', (data) => {
  const healthBar = document.getElementById('health-bar');
  const healthText = document.getElementById('health-text');
  
  // ОбновлСниС Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ прСдставлСния
  healthBar.style.width = `${data.healthPercent}%`;
  healthText.textContent = `${data.currentHealth}/${data.maxHealth}`;
  
  // ИзмСнСниС Ρ†Π²Π΅Ρ‚Π° ΠΏΡ€ΠΈ Π½ΠΈΠ·ΠΊΠΎΠΌ Π·Π΄ΠΎΡ€ΠΎΠ²ΡŒΠ΅
  if (data.healthPercent < 25) {
    healthBar.classList.add('critical');
  } else {
    healthBar.classList.remove('critical');
  }
  
  // Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π² C++
  return { success: true };
});

Π Π°Π±ΠΎΡ‚Π° с событиями

Подписка Π½Π° события

/**
 * ΠŸΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°Π΅Ρ‚ΡΡ Π½Π° событиС Π΄Π²ΠΈΠΆΠΊΠ°
 * @param {string} eventName - Имя события
 * @param {Function} callback - Ѐункция ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°
 * @returns {number} ID подписки
 */
engine.subscribe(eventName, callback);

ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

// Подписка Π½Π° событиС получСния ΡƒΡ€ΠΎΠ½Π°
const damageSubscriptionId = engine.subscribe('playerDamaged', (data) => {
  // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ мигания экрана
  const damageFlash = document.createElement('div');
  damageFlash.className = 'damage-flash';
  document.body.appendChild(damageFlash);
  
  // Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ эффСкта Ρ‡Π΅Ρ€Π΅Π· 500 мс
  setTimeout(() => {
    document.body.removeChild(damageFlash);
  }, 500);
});

ΠžΡ‚ΠΏΠΈΡΠΊΠ° ΠΎΡ‚ событий

/**
 * ΠžΡ‚ΠΏΠΈΡΡ‹Π²Π°Π΅Ρ‚ΡΡ ΠΎΡ‚ события
 * @param {number} subscriptionId - ID подписки
 */
engine.unsubscribe(subscriptionId);

ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° событий

/**
 * ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ событиС Π² Π΄Π²ΠΈΠΆΠΎΠΊ
 * @param {string} eventName - Имя события
 * @param {Object} data - Π”Π°Π½Π½Ρ‹Π΅ события
 */
engine.emit(eventName, data);

Π Π°Π±ΠΎΡ‚Π° с ΠΈΠ³Ρ€ΠΎΠ²Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ

Π”Π°Π½Π½Ρ‹Π΅ ΠΈΠ³Ρ€ΠΎΠΊΠ°

// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ³Ρ€ΠΎΠΊΠ°
const playerData = engine.call('getPlayerData');

// ОбновлСниС ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°
engine.call('updatePlayerStat', {
  statName: 'strength',
  newValue: 15
});

Π˜Π½Π²Π΅Π½Ρ‚Π°Ρ€ΡŒ

// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ содСрТимого инвСнтаря
const inventory = engine.call('getInventory');

// ИспользованиС ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚Π°
function useItem(itemId) {
  const result = engine.call('useItem', { itemId });
  
  if (result.success) {
    // ОбновлСниС UI
    updateInventoryUI();
  } else {
    // Показ сообщСния ΠΎΠ± ошибкС
    showErrorMessage(result.errorMessage);
  }
}

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсами

Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ

/**
 * Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ· рСсурсов ΠΈΠ³Ρ€Ρ‹
 * @param {string} imagePath - ΠŸΡƒΡ‚ΡŒ ΠΊ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΡŽ
 * @returns {Promise<string>} URL изобраТСния
 */
async function loadGameImage(imagePath) {
  const result = await engine.call('loadImage', { path: imagePath });
  return result.imageUrl;
}

ВоспроизвСдСниС Π·Π²ΡƒΠΊΠΎΠ²

/**
 * Воспроизводит Π·Π²ΡƒΠΊ
 * @param {string} soundId - ID Π·Π²ΡƒΠΊΠ°
 * @param {Object} options - ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ воспроизвСдСния
 */
function playSound(soundId, options = {}) {
  engine.call('playSound', {
    soundId,
    volume: options.volume || 1.0,
    pitch: options.pitch || 1.0,
    loop: options.loop || false
  });
}

Анимации ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Ρ‹

Анимация UI элСмСнтов

/**
 * АнимируСт свойство элСмСнта
 * @param {HTMLElement} element - Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ для Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ
 * @param {string} property - CSS свойство
 * @param {string|number} targetValue - Π¦Π΅Π»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅
 * @param {number} duration - Π”Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π² мс
 * @returns {Promise} Promise, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ
 */
function animateProperty(element, property, targetValue, duration = 300) {
  return new Promise(resolve => {
    element.style.transition = `${property} ${duration}ms ease-out`;
    element.style[property] = targetValue;
    
    const onTransitionEnd = () => {
      element.removeEventListener('transitionend', onTransitionEnd);
      resolve();
    };
    
    element.addEventListener('transitionend', onTransitionEnd);
  });
}

ΠžΡ‚Π»Π°Π΄ΠΊΠ° ΠΈ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

/**
 * ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ сообщСниС Π² Π»ΠΎΠ³ Π΄Π²ΠΈΠΆΠΊΠ°
 * @param {string} message - Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅
 * @param {string} level - Π£Ρ€ΠΎΠ²Π΅Π½ΡŒ логирования (debug, info, warning, error)
 */
function log(message, level = 'info') {
  engine.call('log', {
    message,
    level
  });
}

Локализация

/**
 * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡƒΡŽ строку
 * @param {string} key - ΠšΠ»ΡŽΡ‡ строки
 * @param {Object} params - ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ для подстановки
 * @returns {string} Локализованная строка
 */
function getLocalizedString(key, params = {}) {
  const result = engine.call('getLocalizedString', {
    key,
    params
  });
  
  return result.text;
}

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°: БистСма инвСнтаря

class InventorySystem {
  constructor() {
    this.inventoryData = null;
    this.draggedItem = null;
    
    // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ
    this.initialize();
  }
  
  async initialize() {
    // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… инвСнтаря
    this.inventoryData = await engine.call('getInventory');
    
    // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ слотов
    this.createInventorySlots();
    
    // Настройка пСрСтаскивания
    this.setupDragAndDrop();
    
    // РСгистрация Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ обновлСния инвСнтаря
    engine.register('updateInventory', (data) => {
      this.updateInventoryUI(data);
      return { success: true };
    });
  }
  
  createInventorySlots() {
    const container = document.getElementById('inventory-container');
    container.innerHTML = '';
    
    // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ слотов Π½Π° основС Π΄Π°Π½Π½Ρ‹Ρ…
    for (let i = 0; i < this.inventoryData.slots.length; i++) {
      const slot = document.createElement('div');
      slot.className = 'inventory-slot';
      slot.dataset.slotIndex = i;
      
      // Если Π² слотС Π΅ΡΡ‚ΡŒ ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚, ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌ Π΅Π³ΠΎ
      const itemData = this.inventoryData.slots[i];
      if (itemData) {
        const itemElement = this.createItemElement(itemData);
        slot.appendChild(itemElement);
      }
      
      container.appendChild(slot);
    }
  }
  
  createItemElement(itemData) {
    const item = document.createElement('div');
    item.className = 'inventory-item';
    item.dataset.itemId = itemData.id;
    
    // Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚Π°
    const img = document.createElement('img');
    img.src = itemData.iconUrl;
    img.alt = itemData.name;
    item.appendChild(img);
    
    return item;
  }
  
  setupDragAndDrop() {
    // РСализация пСрСтаскивания ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ΠΎΠ²
    // ...
  }
  
  updateInventoryUI(data) {
    this.inventoryData = data;
    // ОбновлСниС UI Π½Π° основС Π½ΠΎΠ²Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…
    // ...
  }
}

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ шаги

UI ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹

Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ UI ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ для быстрого создания интСрфСйсов.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ интСрфСйсов

ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… интСрфСйсов.

ΠŸΠ»Π°Π³ΠΈΠ½Ρ‹

Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅ систСму ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² Wudgine.

Wudgine β€’ Β© 2025