Основа Маджонга | Mahjong's base
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

506 lines
14KB

  1. const ИМЯ = "ОМ | MB";
  2. const ИМЯ_МОДУЛЯ_РЕСУРСОВ = "Ресурсы Маджонга | Mahjong resources";
  3. const ИМЯ_ОТЛ_РАСКЛАДКИ = "Отладочные раскладки Маджонга | Mahjong debug layouts";
  4. // // // //
  5. ОкраситьВыбранныеФишки = мир =>
  6. {
  7. /*
  8. // Очищаем цвета всех фишек.
  9. for (var номер in мир.фишки)
  10. {
  11. var фишка = мир.фишки[номер];
  12. фишка.color = new THREE.Color();
  13. }
  14. */
  15. // Окрашиваем выбранные фишки.
  16. for (var номерЭлемента in мир.номераВыбранныхФишек)
  17. {
  18. var номер = мир.номераВыбранныхФишек[номерЭлемента];
  19. console.debug("окрасить фишку", номер);
  20. //мир.фишки[номер].color = new THREE.Color(0xff0000);
  21. }
  22. };
  23. // // // //
  24. ВывестиВыбранныеФишки = мир =>
  25. {
  26. var номер = мир.номерВыбраннойФишки;
  27. var группа = мир.группыФишек[номер];
  28. console.debug(`Выбрали фишку. номер: '${номер}' группа: '${группа}'`);
  29. console.debug("Номера выбранных фишек", мир.номераВыбранныхФишек);
  30. };
  31. // // // //
  32. ПодготовитьВыборФишек = мир =>
  33. {
  34. мир.номераВыбранныхФишек = [];
  35. };
  36. // // // //
  37. ВыбратьФишкуВКоординатахНажатия = мир =>
  38. {
  39. мир.ловецНажатий.setFromCamera(мир.позицияНажатия, мир.камера);
  40. var пересечения = мир.ловецНажатий.intersectObjects(мир.корень.children);
  41. if (пересечения.length)
  42. {
  43. var фишка = пересечения[0].object;
  44. var номер = номерФишки(мир.фишки, фишка.id);
  45. if (номер)
  46. {
  47. мир.номерВыбраннойФишки = номер;
  48. мир.номераВыбранныхФишек.push(Number(номер));
  49. мир.уведомить("выбор фишки");
  50. }
  51. }
  52. };
  53. // // // //
  54. ЗагрузитьОтладочнуюРаскладку = мир =>
  55. {
  56. var модуль = мир.модули.модульПоИмени(ИМЯ_ОТЛ_РАСКЛАДКИ);
  57. var ресурс = "/успех|success.layout";
  58. var содержимое = модуль.содержимое[ресурс];
  59. мир.раскладкаKMahjongg = {
  60. "содержимое": содержимое,
  61. };
  62. };
  63. // // // //
  64. ВывестиКоординатыНажатия = мир =>
  65. {
  66. var п = мир.позицияНажатия;
  67. console.debug("нажатие", п.x, п.y);
  68. };
  69. // // // //
  70. ИсправитьОтслеживаниеНажатийНаIOS = мир =>
  71. {
  72. // https://stackoverflow.com/a/31459240/3404710
  73. мир.отрисовщик.domElement.style.cursor = "pointer";
  74. };
  75. // // // //
  76. ОтслеживатьНажатияПальцем = мир =>
  77. {
  78. window.addEventListener(
  79. "touchstart",
  80. function(событие) {
  81. var позиция = new THREE.Vector2();
  82. позиция.x = (событие.touches[0].clientX / window.innerWidth) * 2 - 1;
  83. позиция.y = - (событие.touches[0].clientY / window.innerHeight) * 2 + 1;
  84. мир.позицияНажатия = позиция;
  85. мир.уведомить("нажали");
  86. }
  87. );
  88. };
  89. // // // //
  90. ОтслеживатьНажатияМышью = мир =>
  91. {
  92. window.addEventListener(
  93. "click",
  94. function(событие) {
  95. var позиция = new THREE.Vector2();
  96. позиция.x = (событие.clientX / window.innerWidth) * 2 - 1;
  97. позиция.y = - (событие.clientY / window.innerHeight) * 2 + 1;
  98. мир.позицияНажатия = позиция;
  99. мир.уведомить("нажали");
  100. }
  101. );
  102. };
  103. // // // //
  104. ЗадатьМатериалыФишкамПоГруппам = мир =>
  105. {
  106. for (var номер in мир.группыФишек)
  107. {
  108. var группа = мир.группыФишек[номер];
  109. var материал = мир.материалыФишек[группа];
  110. фишка = мир.фишки[номер];
  111. фишка.material = материал;
  112. }
  113. };
  114. // // // //
  115. СоздатьГруппыФишек = мир =>
  116. {
  117. мир.группыФишек = [];
  118. const позиции = мир.раскладкаKMahjongg.позиции;
  119. var группа = 0;
  120. for (var номер in позиции)
  121. {
  122. мир.группыФишек.push(группа);
  123. // Меняем группу каждую пару фишек.
  124. if (номер % 2 == 1)
  125. {
  126. ++группа;
  127. // Начинаем группы заново, как только они заканчиваются.
  128. if (группа >= 42)
  129. {
  130. группа = 0;
  131. }
  132. }
  133. }
  134. };
  135. // // // //
  136. СоздатьУзлыФишек = мир =>
  137. {
  138. var границы = мир.фишка.geometry.boundingBox;
  139. var размеры = [
  140. (границы.max.x - границы.min.x) / 2,
  141. (границы.max.z - границы.min.z) / 2,
  142. границы.max.y - границы.min.y,
  143. ];
  144. const позиции = мир.раскладкаKMahjongg.позиции;
  145. мир.фишки = [];
  146. for (var номер in позиции)
  147. {
  148. // Модель.
  149. var фишка = мир.фишка.clone();
  150. мир.фишки.push(фишка);
  151. мир.корень.add(фишка);
  152. // Расположение.
  153. var позиция = позиции[номер];
  154. var слой = позиция[0];
  155. var ряд = позиция[1];
  156. var столбец = позиция[2];
  157. фишка.position.x = столбец * размеры[0];
  158. фишка.position.z = ряд * размеры[1];
  159. фишка.position.y = слой;
  160. }
  161. };
  162. // // // //
  163. ОтобразитьРаскладкуПоследовательноСоВсемиТекстурами = мир =>
  164. {
  165. var границы = мир.фишка.geometry.boundingBox;
  166. var размеры = [
  167. (границы.max.x - границы.min.x) / 2,
  168. (границы.max.z - границы.min.z) / 2,
  169. границы.max.y - границы.min.y,
  170. ];
  171. const позиции = мир.раскладкаKMahjongg.позиции;
  172. мир.фишки = [];
  173. for (var номер in позиции)
  174. {
  175. // Модель.
  176. var фишка = мир.фишка.clone();
  177. мир.фишки.push(фишка);
  178. мир.корень.add(фишка);
  179. // Расположение.
  180. var позиция = позиции[номер];
  181. var слой = позиция[0];
  182. var ряд = позиция[1];
  183. var столбец = позиция[2];
  184. фишка.position.x = столбец * размеры[0];
  185. фишка.position.z = ряд * размеры[1];
  186. фишка.position.y = слой;
  187. // Материал.
  188. var номерМатериала = номер % 42;
  189. var материал = мир.материалыФишек[номерМатериала];
  190. фишка.material = материал;
  191. }
  192. };
  193. // // // //
  194. СоздатьМатериалыФишекОтладочнойТемы = мир =>
  195. {
  196. мир.материалыФишек = [];
  197. var тема = "отладочная|debug";
  198. for (var номер = 1; номер <= 42; ++номер)
  199. {
  200. var текстура = мир.текстурыТемФишек[тема][номер];
  201. var материал = new THREE.MeshLambertMaterial({map: текстура});
  202. мир.материалыФишек.push(материал);
  203. }
  204. };
  205. // // // //
  206. ВывестиФактЗагрузкиТемыФишекМаджонга = мир =>
  207. {
  208. console.debug("ВывестиФактЗагрузкиТемыФишекМаджонга");
  209. };
  210. // // // //
  211. ЗадатьТемуФишекДляЗагрузки = мир =>
  212. {
  213. мир.темаФишек = "отладочная|debug";
  214. };
  215. // // // //
  216. ЦентрироватьСцену = мир =>
  217. {
  218. var мин = {
  219. "x": 0,
  220. "z": 0,
  221. };
  222. var макс = {
  223. "x": 0,
  224. "z": 0,
  225. };
  226. for (var номер in мир.фишки)
  227. {
  228. const фишка = мир.фишки[номер];
  229. if (фишка.position.x < мин.x)
  230. {
  231. мин.x = фишка.position.x;
  232. }
  233. if (фишка.position.x > макс.x)
  234. {
  235. макс.x = фишка.position.x;
  236. }
  237. if (фишка.position.z < мин.z)
  238. {
  239. мин.z = фишка.position.z;
  240. }
  241. if (фишка.position.z > макс.z)
  242. {
  243. макс.z = фишка.position.z;
  244. }
  245. }
  246. мир.корень.position.x -= (макс.x - мин.x) / 2;
  247. мир.корень.position.z -= (макс.z - мин.z) / 2;
  248. };
  249. // // // //
  250. ОтобразитьРаскладкуОднойФишкой = мир =>
  251. {
  252. var границы = мир.фишка.geometry.boundingBox;
  253. var размеры = [
  254. (границы.max.x - границы.min.x) / 2,
  255. (границы.max.z - границы.min.z) / 2,
  256. границы.max.y - границы.min.y,
  257. ];
  258. const позиции = мир.раскладкаKMahjongg.позиции;
  259. мир.фишки = [];
  260. for (var номер in позиции)
  261. {
  262. var фишка = мир.фишка.clone();
  263. мир.фишки.push(фишка);
  264. мир.корень.add(фишка);
  265. var позиция = позиции[номер];
  266. var слой = позиция[0];
  267. var ряд = позиция[1];
  268. var столбец = позиция[2];
  269. фишка.position.x = столбец * размеры[0];
  270. фишка.position.z = ряд * размеры[1];
  271. фишка.position.y = слой;
  272. }
  273. };
  274. // // // //
  275. ЗагрузитьРаскладку = мир =>
  276. {
  277. var модуль = мир.модули.модульПоИмени(ИМЯ_МОДУЛЯ_РЕСУРСОВ);
  278. //var ресурс = "/cat.layout";
  279. var ресурс = "/X_shaped.layout";
  280. var содержимое = модуль.содержимое[ресурс];
  281. мир.раскладкаKMahjongg = {
  282. "содержимое": содержимое,
  283. };
  284. };
  285. // // // //
  286. ПовернутьФишку = мир =>
  287. {
  288. мир.фишка.rotation.x += 0.03;
  289. мир.фишка.rotation.y += 0.02;
  290. };
  291. // // // //
  292. Отладка = мир =>
  293. {
  294. console.debug("Отладка", Date());
  295. };
  296. // // // //
  297. ЗапуститьТаймерПоворотаФишки = мир =>
  298. {
  299. setInterval(
  300. function() {
  301. мир.уведомить("поворот фишки");
  302. },
  303. 60
  304. );
  305. };
  306. // // // //
  307. ПодготовитьСцену = мир =>
  308. {
  309. var коэффициент = 2;
  310. var расстояние = 6;
  311. мир.камера.position.y = расстояние * коэффициент;
  312. мир.камера.position.z = расстояние;
  313. мир.камера.lookAt(new THREE.Vector3(0, 0, 0));
  314. мир.свет = new THREE.DirectionalLight(0xffffff, 1);
  315. мир.свет.position.set(-0.5, 1, 0.5).normalize();
  316. мир.сцена.add(мир.свет);
  317. мир.корень = new THREE.Group();
  318. мир.сцена.add(мир.корень);
  319. };
  320. // // // //
  321. ПодготовитьФишку = мир =>
  322. {
  323. var материал = new THREE.MeshLambertMaterial({map: мир.текстураФишки});
  324. мир.фишка.material = материал;
  325. };
  326. // // // //
  327. ЗагрузитьТекстуруФишкиИзМодуля = мир =>
  328. {
  329. var модуль = мир.модули.модульПоИмени(ИМЯ_МОДУЛЯ_РЕСУРСОВ);
  330. var ресурс = "/текстура.png";
  331. var содержимое = модуль.содержимое[ресурс];
  332. var b64 = base64js.fromByteArray(new Uint8Array(содержимое));
  333. var адрес = `data:image/png;base64,${b64}`;
  334. мир.загрузчикТекстур.load(
  335. адрес,
  336. function(текстура) {
  337. мир.текстураФишки = текстура;
  338. мир.текстураФишки.flipY = false;
  339. мир.уведомить("загрузили текстуру фишки из модуля");
  340. },
  341. null,
  342. function(error) {
  343. console.error("ОШИБКА | ERROR", error);
  344. }
  345. );
  346. };
  347. // // // //
  348. СоздатьЗагрузчикТекстур = мир =>
  349. {
  350. мир.загрузчикТекстур = new THREE.TextureLoader();
  351. };
  352. // // // //
  353. ЗагрузитьФишку = мир =>
  354. {
  355. var модуль = мир.модули.модульПоИмени(ИМЯ_МОДУЛЯ_РЕСУРСОВ);
  356. var ресурс = "/фишка.gltf";
  357. var адрес = `${window.location.origin}${ресурс}`;
  358. THREE.Cache.enabled = true;
  359. THREE.Cache.add(адрес, модуль.содержимое[ресурс]);
  360. мир.загрузчикGLTF.load(
  361. адрес,
  362. function(gltf) {
  363. // Вычленяем Mesh.
  364. gltf.scene.traverse(function(ребёнок) {
  365. if (ребёнок.isMesh)
  366. {
  367. мир.фишка = ребёнок;
  368. }
  369. });
  370. мир.уведомить("загрузили фишку");
  371. },
  372. null,
  373. function(error) {
  374. console.error("ОШИБКА | ERROR", error);
  375. }
  376. );
  377. };
  378. // // // //
  379. СоздатьЗагрузчикGLTF = мир =>
  380. {
  381. мир.загрузчикGLTF = new THREE.GLTFLoader();
  382. };