Browse Source

Добавить весь код маджонга

master
parent
commit
256f6e64e6
1 changed files with 480 additions and 0 deletions
  1. +480
    -0
      код/2019-09-10.js

+ 480
- 0
код/2019-09-10.js View File

@@ -0,0 +1,480 @@
var ресурсы = [
[БАЗА + "модели/фишка/2019-09-08.osgt", "mod"],
[БАЗА + "текстуры/заглушка.png", "tex.stub"],
[БАЗА + "шейдеры/освещение-изображение.vert", "ver"],
[БАЗА + "шейдеры/освещение-изображение.frag", "fra"],
[БАЗА + "раскладки/X_shaped.layout", "lay"],

[БАЗА + "классы/Раскладка/2019-08-16.js", "Layout"],
[БАЗА + "классы/Фишка/2019-09-07.js", "Tile"],
[БАЗА + "темыФишек/заглушка/2019-09-08.js", "theme.stub"],
];

мж.начали = new Уведомитель();
мж.начать = function()
{
муром.камера.позиция = [0, -70, 0];
муром.камера.вращение = [90, 0, 0];
мж.сцена = муром.узлы.создатьСферу("sce", 0);
мж.сцена.вращение = [60, 0, 0];
var мир = муром.узлы.узел("mir");
мир.добавитьДитя(мж.сцена);
мж.начали.уведомить();
};

мж.задатьНейтральныйМатериал = function()
{
var мат = муром.материалы.создатьМатериал("N");
var изо = муром.ресурсы.ресурс("tex.stub");
мат.задатьТекстуру("image", изо);
var вер = муром.ресурсы.ресурс("ver").содержимое;
var фра = муром.ресурсы.ресурс("fra").содержимое;
мат.задатьШейдеры(вер, фра);
мж.сцена.задатьМатериал(мат);
};

мж.разобратьРаскладку = function()
{
eval(муром.ресурсы.ресурс("Layout").содержимое);
var содержимое = муром.ресурсы.ресурс("lay").содержимое;
мж.раскладка = new Раскладка();
мж.раскладка.разобрать(содержимое);
};

мж.фишки = [];
мж.создатьФишки = function()
{
eval(муром.ресурсы.ресурс("Tile").содержимое);
for (var номер in мж.раскладка.позиции)
{
var ф = new Фишка();
ф.позиция = мж.раскладка.позиции[номер];
мж.фишки.push(ф);
}
};

мж.размерФишки = {
"ширина": 2.0,
"высота": 3.0,
"глубина": 1.0,
};
мж.создатьУзлыФишек = function()
{
const шагФишки = 2.0;
const коэффициенты = {
"x": мж.размерФишки.ширина / шагФишки,
"y": -мж.размерФишки.высота / шагФишки,
"z": мж.размерФишки.глубина,
};
var мод = муром.ресурсы.ресурс("mod");
for (var номер in мж.фишки)
{
var имя = номер.toString();
var узел = муром.узлы.создатьУзел(имя, мод);
мж.сцена.добавитьДитя(узел);
var ф = мж.фишки[номер];
var п = ф.позиция;
узел.позиция = [
п[2] * коэффициенты.x,
п[1] * коэффициенты.y,
п[0] * коэффициенты.z,
];
ф.узел = узел;
}
};

мж.центрироватьСцену = function()
{
var границы = {
"лево": 1000,
"право": -1000,
"верх": -1000,
"низ": 1000,
};
for (var номер in мж.фишки)
{
const ф = мж.фишки[номер];
const x = ф.узел.позиция[0];
const y = ф.узел.позиция[1];
if (x < границы.лево)
{
границы.лево = x;
}
if (x > границы.право)
{
границы.право = x;
}
if (y < границы.низ)
{
границы.низ = y;
}
if (y > границы.верх)
{
границы.верх = y;
}
}

const ширина = границы.право - границы.лево + мж.размерФишки.ширина;
const высота = границы.верх - границы.низ + мж.размерФишки.высота;
мж.сцена.позиция = [-ширина / 2.0, 0, высота / 2.0];
};

// http://www.rubl.com/rules/mahjong-solitaire-rules.html
мж.задатьФишкамГруппыПоследовательно = function()
{
var группы = [];
// Генерируем группы.
const группВсего = 42;
const группПо4Дубля = 34;
for (var г = 0; г < группВсего; ++г)
{
const четыреДубля = (г < группПо4Дубля);
const колвоДублей = четыреДубля ? 4 : 1;
for (var д = 0; д < колвоДублей; ++д)
{
группы.push(г);
}
}
// Задаём.
for (var номер in мж.фишки)
{
var ф = мж.фишки[номер];
ф.группа = Number(группы[номер]);
}
};

мж.применитьТемуФишек = function()
{
eval(муром.ресурсы.ресурс("theme.stub").contents);
const R = RR();
// Создать текстуры.
var обозначения = [];
var текстуры = [];
for (var номер in R)
{
var обозначение = R[номер][0];
обозначения.push(обозначение);
var имя = "tile.tex/" + обозначение;
var содержимое = R[номер][1];
var текстура = муром.ресурсы.создатьРесурс(имя, содержимое);
текстуры.push(текстура);
}
// Создать материалы.
var нейтраль = [];
var выбор = [];
var вер = муром.ресурсы.ресурс("ver").содержимое;
var фра = муром.ресурсы.ресурс("fra").содержимое;
// Нейтраль.
for (var номер = 0; номер < 42; ++номер)
{
var имя = "tile.mat/" + обозначения[номер];
var изо = текстуры[номер];
var мат = муром.материалы.создатьМатериал(имя);
мат.задатьТекстуру("image", изо);
мат.задатьШейдеры(вер, фра);
нейтраль.push(мат);
}
// Выбор.
for (var номер = 42; номер < 83; ++номер)
{
var имя = "tile.mat/" + обозначения[номер];
var изо = текстуры[номер];
var мат = муром.материалы.создатьМатериал(имя);
мат.задатьТекстуру("image", изо);
мат.задатьШейдеры(вер, фра);
выбор.push(мат);
}

// Применить тему.
for (var номер in мж.фишки)
{
var ф = мж.фишки[номер];
ф.нейтраль = нейтраль[ф.группа];
ф.выбор = выбор[ф.группа];
ф.показатьНейтраль();
}
};

мж.маскаВыбора = 0x2;
мж.сделатьФишкиВыбираемыми = function()
{
for (var номер in мж.фишки)
{
var ф = мж.фишки[номер];
ф.узел.задатьМаску(мж.маскаВыбора);
}
}

мж.индексПозиции = function(п)
{
return п[0] * 1000000 + п[1] * 1000 + п[2];
};

мж.индексПозиций = {};
мж.проиндексироватьПозиции = function()
{
for (var номер in мж.фишки)
{
var ф = мж.фишки[номер];
var и = мж.индексПозиции(ф.позиция);
мж.индексПозиций[и] = true;
}
};

мж.естьСоседи = function(позиция, смещениеПоля, смещениеСтолбца)
{
for (var смещениеРяда = -1; смещениеРяда <= 1; ++смещениеРяда)
{
var сосед = [
Number(позиция[0]) + смещениеПоля,
Number(позиция[1]) + смещениеРяда,
Number(позиция[2]) + смещениеСтолбца,
];
var и = мж.индексПозиции(сосед);
if (и in мж.индексПозиций)
{
return true;
}
}
// Соседей нет.
return false;
};

мж.можноВыбратьФишку = function(ф)
{
// Проверяем наличие фишек с левой и правой сторон одновременно.
var слева = this.естьСоседи(ф.позиция, 0, -2);
var справа = this.естьСоседи(ф.позиция, 0, 2);
if (слева && справа)
{
return false;
}
// Проверяем наличие фишек непосредственно сверху.
for (var смещение = -1; смещение <= 1; ++смещение)
{
if (this.естьСоседи(ф.позиция, 1, смещение))
{
return false;
}
}
// Фишка не заблокирована.
return true;
};

мж.номерВыбраннойФишки = null;
мж.выбраннаяФишка = null;
мж.выбранаФишка = new Уведомитель();
мж.выбратьФишку = function()
{
// Определить щелчок.
if (муром.мышь.нажатыеКнопки.length == 1)
{
var узел =
муром.камера.узелВПозиции(
муром.мышь.позиция,
мж.маскаВыбора
);
if (узел)
{
var номер = Number(узел.имя);
var ф = мж.фишки[номер];
if (мж.можноВыбратьФишку(ф))
{
мж.номерВыбраннойФишки = номер;
мж.выбраннаяФишка = ф;
мж.выбранаФишка.уведомить();
}
}
}
};

мж.отладитьВыборФишки = function()
{
мж.выбранаФишка.подписать(function(){
console.log(
"Выбор. Номер: '" +
мж.номерВыбраннойФишки +
"' Группа: '" +
мж.выбраннаяФишка.группа +
"'"
);
});
};

мж.показатьВыбраннуюФишку = function()
{
мж.выбраннаяФишка.показатьВыбор();
};

мж.выбранныеФишки = [];
мж.фишкиРазличаются = new Уведомитель();
мж.фишкиСовпадают = new Уведомитель();
мж.фишкиСравнили = new Уведомитель();
мж.сравнитьВыбранныеФишки = function()
{
// Собираем.
мж.выбранныеФишки.push(мж.выбраннаяФишка);
// Удостоверяемся в наличии пары фишек.
if (мж.выбранныеФишки.length != 2)
{
return;
}
var ф1 = мж.выбранныеФишки[0];
var ф2 = мж.выбранныеФишки[1];
// Убираем дубликат при двойном выборе одной фишки.
if (ф1.имя == ф2.имя)
{
мж.выбранныеФишки.shift();
return;
}
// Сравниваем.
if (ф1.группа == ф2.группа)
{
мж.фишкиСовпадают.уведомить();
}
else
{
мж.фишкиРазличаются.уведомить();
}
мж.фишкиСравнили.уведомить();
};

мж.отладитьСравнениеФишек = function()
{
мж.фишкиСовпадают.подписать(function(){
console.log("Фишки совпадают");
});
мж.фишкиРазличаются.подписать(function(){
console.log("Фишки различаются");
});
};

мж.скрытьСовпадающиеФишки = function()
{
мж.выбранныеФишки[0].скрыть();
мж.выбранныеФишки[1].скрыть();
};

мж.убратьСовпадающиеФишки = function()
{
var ф1 = мж.выбранныеФишки[0];
var ф2 = мж.выбранныеФишки[1];
var и1 = мж.индексПозиции(ф1.позиция);
var и2 = мж.индексПозиции(ф2.позиция);
delete мж.индексПозиций[и1];
delete мж.индексПозиций[и2];
};

мж.очиститьОтображениеВыбора = function()
{
мж.выбранныеФишки[0].показатьНейтраль();
мж.выбранныеФишки[1].показатьНейтраль();
};

мж.очиститьВыбор = function()
{
мж.номерВыбраннойФишки = 0;
мж.выбраннаяФишка = null;
мж.выбранныеФишки = [];
};

мж.оставшиесяФишки = [];
мж.задатьОставшиесяФишки = function()
{
мж.оставшиесяФишки = мж.фишки.slice();
};

мж.обновилиОставшиесяФишки = new Уведомитель();
мж.обновитьОставшиесяФишки = function()
{
var и1 = мж.оставшиесяФишки.indexOf(мж.выбранныеФишки[0]);
мж.оставшиесяФишки.splice(и1, 1);
var и2 = мж.оставшиесяФишки.indexOf(мж.выбранныеФишки[1]);
мж.оставшиесяФишки.splice(и2, 1);

мж.обновилиОставшиесяФишки.уведомить();
};

мж.доступныеДляВыбораФишки = function()
{
var фишки = [];
for (var номер in мж.оставшиесяФишки)
{
var ф = мж.оставшиесяФишки[номер];
if (мж.можноВыбратьФишку(ф))
{
фишки.push(ф);
}
}
return фишки;
};

мж.естьХод = function()
{
var фишки = мж.доступныеДляВыбораФишки();
for (var н1 in фишки)
{
for (var н2 in фишки)
{
var ф1 = фишки[н1];
var ф2 = фишки[н2];
if (
(ф1.имя != ф2.имя) &&
(ф1.группа == ф2.группа)
) {
return true;
}
}
}
return false;
}

мж.победа = new Уведомитель();
мж.поражение = new Уведомитель();
мж.проверитьЗавершение = function()
{
var кончилисьФишки = (мж.оставшиесяФишки.length == 0);
if (кончилисьФишки)
{
мж.победа.уведомить();
return;
}
if (!мж.естьХод())
{
мж.поражение.уведомить();
}
};

мж.отладитьЗавершение = function()
{
мж.победа.подписать(function(){
console.log("Игра завершена. ПОБЕДА!");
});
мж.поражение.подписать(function(){
console.log("Игра завершена. ПОРАЖЕНИЕ :(");
});
};

мж.задатьОтображениеЗавершения = function()
{
мж.победа.подписать(function(){
муром.камера.цветОчистки = [0.2, 0.5, 0.2];
});
мж.поражение.подписать(function(){
муром.камера.цветОчистки = [0.5, 0.2, 0.2];
});
};

Loading…
Cancel
Save