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.

150 lines
4.8KB

  1. function Тела(события, физика, физмир)
  2. {
  3. this.создать = function()
  4. {
  5. this.умолчание = {
  6. пр: [0, 0, 40, 20],
  7. части: [],
  8. часть: false,
  9. };
  10. this.задано = {};
  11. this.тела = {};
  12. this.имена = {};
  13. события.подписать(this);
  14. };
  15. this.именаЧастей = function(за)
  16. {
  17. var имена = [];
  18. for (var ключ in за)
  19. {
  20. if (ключ.startsWith("части"))
  21. {
  22. имена.push(за[ключ]);
  23. }
  24. }
  25. return имена;
  26. };
  27. this.обработатьКлюч = function(ключ, путь, значение)
  28. {
  29. if (путь[0] != "тела")
  30. {
  31. return;
  32. }
  33. var имя = путь[1];
  34. var свойство = путь.slice(2).join(".");
  35. if (!this.задано[имя])
  36. {
  37. this.задано[имя] = {};
  38. }
  39. this.задано[имя][свойство] = значение;
  40. this.пересоздатьТело(имя);
  41. };
  42. this.обработатьСобытие = function(событие)
  43. {
  44. let префикс = "физика/";
  45. if (событие.startsWith(префикс))
  46. {
  47. let физ = событие.substring(префикс.length);
  48. this.пересоздатьТелаФизики(физ);
  49. }
  50. };
  51. this.пересоздатьТелаФизики = function(физ)
  52. {
  53. for (let имя in this.задано)
  54. {
  55. let заданнаяФизика = this.задано[имя]["физика"];
  56. if (заданнаяФизика && заданнаяФизика == физ)
  57. {
  58. this.пересоздатьТело(имя);
  59. }
  60. }
  61. };
  62. this.пересоздатьТело = function(имя)
  63. {
  64. // Удаляем старое тело.
  65. if (имя in this.тела)
  66. {
  67. var тело = this.тела[имя];
  68. delete this.имена[тело.id];
  69. // Всегда удаляем из мира: и составные, и несоставные тела.
  70. Matter.Composite.remove(физмир, тело);
  71. }
  72. var за = this.задано[имя];
  73. var ум = this.умолчание;
  74. let пр = this.пр(имя);
  75. // Переводим x,y из левого верхнего угла в центр.
  76. пр[0] = пр[0] + пр[2] / 2.0;
  77. пр[1] = пр[1] + пр[3] / 2.0;
  78. // Параметры тела.
  79. var параметры = {};
  80. if (за.физика)
  81. {
  82. let заф = физика.задано[за.физика];
  83. for (let параметр in заф)
  84. {
  85. мир.задатьПолныйКлюч(параметры, параметр, заф[параметр]);
  86. }
  87. }
  88. var тело = null;
  89. // Создаём новое составное тело.
  90. if (за["части.0"])
  91. {
  92. параметры["parts"] = this.телаЧастей(this.именаЧастей(за));
  93. тело = Matter.Body.create(параметры);
  94. }
  95. // Создаём новое несоставное тело.
  96. // Вполне может быть частью другого составного тела.
  97. else
  98. {
  99. тело = Matter.Bodies.rectangle(пр[0], пр[1], пр[2], пр[3], параметры);
  100. }
  101. this.тела[имя] = тело;
  102. this.имена[тело.id] = имя;
  103. // Добавляем тело в физический мир, если оно не является частью другого составного тела.
  104. var часть = за.часть ? за.часть : ум.часть;
  105. if (!часть)
  106. {
  107. Matter.Composite.add(физмир, тело);
  108. }
  109. };
  110. this.пр = function(имя)
  111. {
  112. let за = this.задано[имя];
  113. let пр = this.умолчание.пр;
  114. return [
  115. за["пр.0"] ? за["пр.0"] : пр[0],
  116. за["пр.1"] ? за["пр.1"] : пр[1],
  117. за["пр.2"] ? за["пр.2"] : пр[2],
  118. за["пр.3"] ? за["пр.3"] : пр[3],
  119. ];
  120. };
  121. this.телаЧастей = function(имена)
  122. {
  123. var тела = [];
  124. for (var н in имена)
  125. {
  126. var имя = имена[н];
  127. var тело = this.тела[имя];
  128. тела.push(тело);
  129. }
  130. return тела;
  131. };
  132. // Конструктор.
  133. this.создать();
  134. }