Основа Маджонга | Mahjong's base
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

523 рядки
15KB

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