diff --git a/0000 b/0000 index 0971e97..21ca982 100644 --- a/0000 +++ b/0000 @@ -1,5 +1,5 @@ МАОН_1 -1.0.10 +1.0.11 https://git.opengamestudio.org/MAOH/MAOH_1 /three.js diff --git a/🗄️.js b/🗄️.js index a045d7d..a0987e5 100644 --- a/🗄️.js +++ b/🗄️.js @@ -2048,6 +2048,768 @@ gitjs.мир.разобрать(` `; +// // // // +// MARK: https://git.opengamestudio.org/MAOH/PEEMA/raw/branch/master/0000 +// // // // + + +// MARK: /🎬.js + + +ОбновитьСписокТемМаджонга = мир => +{ + темы = {}; + for (var указатель in мир.модули.модули) + { + var м = мир.модули.модули[указатель]; + var файлы = Object.keys(м.структура).sort(); + // Проверяем наличие не менее 43 файлов (42 текстуры и 1 фишка). + if (файлы.length < 43) + { + continue; + } + // Проверяем наличие 42 изображений. + естьТекстура = (файл) => { return рисовательПоддерживаетИзображениеСИменемФайла(файл); }; + if (файлы.filter(естьТекстура).length < 42) + { + continue; + } + // Проверяем наличие хотя бы одного файла `*.gltf`. + естьФишка = (файл) => { return файл.endsWith(".gltf"); }; + if (!файлы.filter(естьФишка).length) + { + continue; + } + темы[указатель] = { + "📁": файлы, + }; + } + + мир.реестрМаджонга["🀄"] = темы; + console.debug("темы:", темы); +}; + + +// // // // + + +ОбновитьСписокРаскладокМаджонга = мир => +{ + раскладки = {}; + for (var указатель in мир.модули.модули) + { + var м = мир.модули.модули[указатель]; + var файлы = Object.keys(м.структура).sort(); + var лишьРаскладки = true; + for (var н in файлы) + { + var файл = файлы[н]; + if (!файл.endsWith(".layout")) + { + лишьРаскладки = false; + break; + } + } + if (лишьРаскладки) + { + раскладки[указатель] = { + "📁": файлы, + }; + } + } + + мир.реестрМаджонга["📍"] = раскладки; + console.debug("раскладки:", раскладки); +}; + + +// // // // + + +ОбновитьРеестрМаджонга = мир => +{ + мир.уведомить("надо обновить реестр маджонга"); +}; + + +// // // // + + +ПодготовитьРеестрМаджонга = мир => +{ + мир.реестрМаджонга = { + "📍": {}, + "🀄": {}, + }; +}; + + +// MARK: /🎬.череда + + +gitjs.мир.разобрать(` + +ручной пуск + подготовить реестр маджонга + обновить реестр маджонга + +надо обновить реестр маджонга + обновить список раскладок маджонга + обновить список тем маджонга + +`); + + +// // // // +// MARK: https://git.opengamestudio.org/MAOH/CYMA/raw/branch/master/0000 +// // // // + + +// MARK: /🎬.js + + +const ТЕМА_ПО_УМОЛЧАНИЮ = "https://git.opengamestudio.org/MAOH/TEMA_M1K/raw/branch/master/0000"; +const РАСК_ПО_УМОЛЧАНИЮ = "https://git.opengamestudio.org/MAOH/PACK_M1/raw/branch/master/0000"; + + +// // // // + + +ЦентрироватьОкноВПортретномРежиме = мир => +{ + if (!мир.ориентацияПортретная) + { + return; + } + var смещение = (мир.ширинаОкна - window.innerWidth * мир.масштаб) / 2; + window.scrollTo(смещение, 0); +}; + + +// // // // + + +ЗадатьКоличествоФишекДляОтображения = мир => +{ + var всего = мир.фишкиМаджонга.length; + var доступно = Object.keys(мир.индексыФишекМаджонга).length; + var убрано = всего - доступно; + мир.количествоФишекМаджонга = `${убрано}/${всего}`; +}; + + +// // // // + + +УменьшитьМасштаб = мир => +{ + мир.масштаб -= 0.5; + if (мир.масштаб < 1) + { + мир.масштаб = 1; + } + мир.уведомить("изменили масштаб"); +}; + + +// // // // + + +УвеличитьМасштаб = мир => +{ + мир.масштаб += 0.5; + мир.уведомить("изменили масштаб"); +}; + + +// // // // + + +РазрешитьВыборФишек = мир => +{ + мир.отслеживатьНажатияВРисователе = true; +}; + + +// // // // + + +ЗапретитьВыборФишек = мир => +{ + мир.отслеживатьНажатияВРисователе = false; +}; + + +// // // // + + +ОбновитьСчётчикКадров = мир => +{ + var время = Math.floor(мир.времяРисования / 1000.0); + + // Первый вызов. Создаём. + if (!мир.счётчикКадров) + { + var счётчик = document.createElement("div"); + счётчик.style = "position: fixed; left: 0; bottom: 0;"; + document.body.appendChild(счётчик); + мир.счётчикКадров = счётчик; + мир.счётчикКадровВремя = время; + мир.счётчикКадровРазы = 0; + return; + } + + // Последующие вызовы. + ++мир.счётчикКадровРазы; + if (время - мир.счётчикКадровВремя) + { + мир.счётчикКадров.innerHTML = мир.счётчикКадровРазы; + мир.счётчикКадровВремя = время; + мир.счётчикКадровРазы = 0; + } +}; + + +// // // // + + +ИспользоватьВыбраннуюТему = мир => +{ + var э = мир.списокТем[мир.номерВыбраннойТемыМаджонга]; + var файлыТемы = мир.реестрМаджонга["🀄"][э[1]]["📁"]; + мир.настройкиМаджонга["🀄/📦"] = э[1]; + мир.настройкиМаджонга["🀄/📁"] = файлыТемы[42]; + мир.уведомить("изменили настройки маджонга"); +}; + + +// // // // + + +ИспользоватьВыбраннуюРаскладку = мир => +{ + var э = мир.списокРаскладок[мир.номерВыбраннойРаскладкиМаджонга]; + мир.настройкиМаджонга["📍/📦"] = э[1]; + мир.настройкиМаджонга["📍/📁"] = э[0]; + мир.уведомить("изменили настройки маджонга"); +}; + + +// // // // + + +ВывестиПоражение = мир => +{ + console.debug("ПОРАЖЕНИЕ"); +}; + + +// // // // + + +ВывестиПобеду = мир => +{ + console.debug("ПОБЕДА"); +}; + + +// // // // + + +ЗадатьФишкуДляВыбора = мир => +{ + var номер = мир.выбранныйУзел.userData; + мир.фишкаМаджонгаДляВыбора = номер; +} + + +// // // // + + +ПодготовитьФишкиКВыбору = мир => +{ + мир.выборныеУзлы = мир.фишкиСцены; +}; + + +// // // // + + +ПодготовитьсяКСозданиюФишек = мир => +{ + var настройки = мир.настройкиМаджонга; + var позиции = мир.позицииФишек; + + var фишки = []; + var группа = 0; + for (var номер in позиции) + { + var п = позиции[номер]; + фишки.push({ + "📍": [п[0], п[1], п[2]], + "🚩": группа, + }); + if (номер % 2) + { + ++группа; + if (группа > 41) + { + группа = 0; + } + } + }; + + мир.фишкиМаджонга = фишки; + мир.модельФишкиСцены = мир.полигональныеСетки[настройки["🀄/📦"]][настройки["🀄/📁"]]; + мир.сцена.add(мир.сценаМаджонга); +}; + + +// // // // + + +ПеремешатьПозицииФишек = мир => +{ + var настройки = мир.настройкиМаджонга; + var м = мир.модули.модульПоУказателю(настройки["📍/📦"]); + var содержимое = м.содержимое[настройки["📍/📁"]]; + var было = разобратьРаскладкуKMahjongg(содержимое); + var стало = []; + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#Getting_a_random_integer_between_two_values + function getRandomInt(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive + } + + // Перемешиваем. + while (было.length) + { + var н = getRandomInt(0, было.length); + стало.push(было[н]); + было.splice(н, 1); + } + + мир.позицииФишек = стало; +}; + + +// // // // + + +СоздатьФишки = мир => +{ + мир.уведомить("надо создать фишки"); +}; + + +// // // // + + +СоздатьМатериалыФишек = мир => +{ + var настройки = мир.настройкиМаджонга; + + мир.материалыФишекСцены = []; + мир.выбранныеМатериалыФишекСцены = []; + + var текстуры = мир.текстуры[настройки["🀄/📦"]]; + for (var имя in текстуры) + { + var текстура = текстуры[имя]; + var материал = new THREE.MeshLambertMaterial({ + map: текстура, + color: new THREE.Color(0xCCCCCC), + }); + мир.материалыФишекСцены.push(материал); + var выбранныйМатериал = new THREE.MeshLambertMaterial({ + map: текстура, + color: new THREE.Color(0xFFFFFF), + }); + мир.выбранныеМатериалыФишекСцены.push(выбранныйМатериал); + } +}; + + +// // // // + + +ПодготовитьсяКЗагрузкеРесурсов = мир => +{ + var настройки = мир.настройкиМаджонга; + + мир.полигональныеСетки = { + [настройки["🀄/📦"]]: { + [настройки["🀄/📁"]]: null, + }, + }; + + мир.текстуры = { + [настройки["🀄/📦"]]: { }, + }; + var м = мир.модули.модульПоУказателю(настройки["🀄/📦"]); + var файлы = Object.keys(м.структура).sort(); + var колво = 42; + for (var номер = 0; номер < колво; ++номер) + { + var файл = файлы[номер]; + мир.текстуры[настройки["🀄/📦"]][файл] = null; + } +}; + + +// // // // + + +ПроверитьНеобходимостьЗагрузкиРесурсов = мир => +{ + var настройки = мир.настройкиМаджонга; + if ( + мир.полигональныеСетки && + настройки["🀄/📦"] in мир.полигональныеСетки && + настройки["🀄/📁"] in мир.полигональныеСетки[настройки["🀄/📦"]] && + мир.текстуры && + настройки["🀄/📦"] in мир.текстуры + ) { + мир.уведомить("ресурсы не нужно загружать"); + } + else + { + мир.уведомить("ресурсы нужно загружать"); + } +}; + + +// // // // + + +ЗагрузитьМодулиРесурсов = мир => +{ + var указатели = мир.списокМодулейРесурсовДляЗагрузки; + var сообщение = "Загрузка модулей ресурсов ⚬ 加载资源模块 ⚬ Loading resource modules"; + console.debug(сообщение, указатели); + мир.модули.использовали.подписатьРаз(function() { + мир.уведомить("загрузили модули ресурсов"); + }); + мир.модули.использовать(указатели); +}; + + +// // // // + + +ПроверитьНеобходимостьЗагрузкиМодулейРесурсов = мир => +{ + if (мир.списокМодулейРесурсовДляЗагрузки.length) + { + мир.уведомить("модули ресурсов нужно загружать"); + } + else + { + мир.уведомить("модули ресурсов не нужно загружать"); + } +} + + +// // // // + + +ПодготовитьПредставлениеСпискаТем = мир => +{ + var список = мир.списокТем; + + var названия = []; + for (var н in список) + { + var название = список[н][0]; + названия.push(название); + } + + мир.списокТемМаджонга = названия; +}; + + +// // // // + + +ПодготовитьСписокТем = мир => +{ + var темы = мир.реестрМаджонга["🀄"]; + + var список = []; + var указатели = Object.keys(темы).sort(); + for (var н in указатели) + { + var указатель = указатели[н]; + var м = мир.модули.модульПоУказателю(указатель); + список.push([м.имя, указатель]); + } + + мир.списокТем = список; +}; + + +// // // // + + +ПодготовитьСписокМодулейРесурсовДляЗагрузки = мир => +{ + var проверить = [ + мир.настройкиМаджонга["🀄/📦"], + мир.настройкиМаджонга["📍/📦"], + ]; + var загрузить = []; + for (var н in проверить) + { + var указатель = проверить[н]; + var м = мир.модули.модульПоУказателю(указатель); + + // Модуль не загружен. + if (!м.содержимое) + { + загрузить.push(указатель); + } + } + мир.списокМодулейРесурсовДляЗагрузки = загрузить; +}; + + +// // // // + + +ПодготовитьПредставлениеСпискаРаскладок = мир => +{ + var список = мир.списокРаскладок; + + var названия = []; + for (var н in список) + { + var файл = список[н][0]; + var название = файл + .substring(1) + .replace(".layout", ""); + названия.push(название); + } + + мир.списокРаскладокМаджонга = названия; +}; + + +// // // // + + +ПодготовитьСписокРаскладок = мир => +{ + var раскладки = мир.реестрМаджонга["📍"]; + + var список = []; + var указатели = Object.keys(раскладки).sort(); + for (var н in указатели) + { + var указатель = указатели[н]; + var файлы = раскладки[указатель]["📁"]; + for (var номер in файлы) + { + var файл = файлы[номер]; + список.push([файл, указатель]); + } + } + + мир.списокРаскладок = список; +}; + + +// // // // + + +ЗадатьНастройкиМаджонгаПоУмолчанию = мир => +{ + var файлыТемы = мир.реестрМаджонга["🀄"][ТЕМА_ПО_УМОЛЧАНИЮ]["📁"]; + var файлыРаскладок = мир.реестрМаджонга["📍"][РАСК_ПО_УМОЛЧАНИЮ]["📁"]; + + мир.настройкиМаджонга = { + "🀄/📦": ТЕМА_ПО_УМОЛЧАНИЮ, + "🀄/📁": файлыТемы[42], + "📍/📦": РАСК_ПО_УМОЛЧАНИЮ, + "📍/📁": файлыРаскладок[0], + } + + мир.номерВыбраннойРаскладкиМаджонга = 0; + мир.номерВыбраннойТемыМаджонга = 0; + + + мир.уведомить("изменили настройки маджонга"); +}; + + +// // // // + + +СоздатьПримерСцены = мир => +{ + мир.сцена.background = new THREE.Color(0xFFFFFF); + мир.свет = new THREE.DirectionalLight(0xFFFFFF, 1); + мир.свет.position.set(-0.5, 1, 0.5).normalize(); + мир.сцена.add(мир.свет); +}; + + +// // // // + + +ПлавноУбратьСтраницуЗагрузкиИСкрытьКрутилку = мир => +{ + плавноСкрытьИУдалить("экран-загрузки", { "задержка": 0.4 }); + плавноСкрыть("крутилка", { "задержка": 0.4 }); +}; + + +// MARK: /🎬.череда + + +gitjs.мир.разобрать(` + +надо окончить загрузку приложения + плавно убрать страницу загрузки и скрыть крутилку + создать пример сцены + подготовить список раскладок + подготовить представление списка раскладок + задать список раскладок маджонга + подготовить список тем + подготовить представление списка тем + задать список тем маджонга + отобразить окно управления + задать настройки маджонга по умолчанию +изменили настройки маджонга +# засечь время А + отобразить выбор раскладки маджонга + отобразить выбор темы маджонга + подготовить список модулей ресурсов для загрузки +# засечь время А + проверить необходимость загрузки модулей ресурсов +модули ресурсов не нужно загружать + проверить необходимость загрузки ресурсов +модули ресурсов нужно загружать + загрузить модули ресурсов +загрузили модули ресурсов + проверить необходимость загрузки ресурсов +ресурсы не нужно загружать + создать фишки +ресурсы нужно загружать + подготовиться к загрузке ресурсов + загрузить полигональные сетки +загрузили полигональные сетки + загрузить текстуры +загрузили текстуры + удалить фишки сцены + создать материалы фишек + создать фишки + +надо создать фишки +# засечь время А + перемешать позиции фишек + подготовиться к созданию фишек + создать фишки в сцене + создать индексы фишек маджонга + подготовить фишки к выбору +# засечь время А + собрать доступные для выбора номера фишек маджонга + подсчитать количество ходов в маджонге + задать количество фишек для отображения + отобразить количество фишек маджонга +# засечь время А +# вывести времена + +изменили номер выбранной раскладки маджонга + использовать выбранную раскладку +изменили номер выбранной темы маджонга + использовать выбранную тему + +нажатие в рисователе + выбрать узел сцены +выбрали узел сцены + задать фишку для выбора + выбрать фишку маджонга +изменили выбранные фишки маджонга + задать материалы фишкам сцены + выделить выбранные фишки в сцене +убрали фишки маджонга + скрыть убранные фишки в сцене +победа в маджонге + вывести победу + отобразить победу +поражение в маджонге + вывести поражение + отобразить поражение + +отрисовали кадр + обновить счётчик кадров + +кнопка раскладки отобразить + запретить выбор фишек +кнопка раскладки скрыть + разрешить выбор фишек +кнопка темы отобразить + запретить выбор фишек +кнопка темы скрыть + разрешить выбор фишек +кнопка увеличения масштаба + увеличить масштаб +кнопка уменьшения масштаба + уменьшить масштаб + +изменили масштаб + отобразить текущее значение масштаба +изменили ориентацию + центрировать окно в портретном режиме + +изменили количество ходов в маджонге + отобразить количество ходов в маджонге + задать количество фишек для отображения + отобразить количество фишек маджонга + +`); + + +// MARK: /🔨.js + + + +// // // // +// Рисователь. Поддержка портретного режима +// // // // + +ИзменитьРазмерРисователя = мир => +{ + var ширина = window.innerWidth * мир.масштаб; + var высота = window.innerHeight * мир.масштаб; + var отношение = ширина / высота; + + // Портрет. + if (отношение < 1) + { + мир.высотаОкна = высота; + мир.высотаОкнаПроц = 100; + мир.ширинаОкна = высота * 1.5; + мир.ширинаОкнаПроц = мир.ширинаОкна * 100 / ширина; + // Уведомляем. + мир.ориентацияПортретная = true; + мир.уведомить("изменили ориентацию"); + } + // Ландшафт. + else + { + мир.ширинаОкна = window.innerWidth * мир.масштаб; + мир.высотаОкна = window.innerHeight * мир.масштаб; + мир.ширинаОкнаПроц = мир.масштаб * 100; + мир.высотаОкнаПроц = мир.масштаб * 100; + // Уведомляем. + мир.ориентацияПортретная = false; + мир.уведомить("изменили ориентацию"); + } +}; + // // // // // MARK: https://git.opengamestudio.org/MAOH/MAOH/raw/branch/master/0000 @@ -2063,10 +2825,6 @@ gitjs.мир.разобрать(` # 启动时要加载的模块指针列表 # List of module pointers to load at startup -https://git.opengamestudio.org/MAOH/PEEMA/raw/branch/master/0000 -https://git.opengamestudio.org/MAOH/OTMA/raw/branch/master/0000 -https://git.opengamestudio.org/MAOH/CYMA/raw/branch/master/0000 - https://git.opengamestudio.org/MAOH/TEMA_M1K/raw/branch/master/0000 https://git.opengamestudio.org/MAOH/PACK_M1/raw/branch/master/0000