123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. function grСцена(состояние, состояниЯ, события, тела, адресИгры)
  2. {
  3. this.создать = function()
  4. {
  5. this.задано = {};
  6. this.сцены = null;
  7. this.состояниеИгрока = null;
  8. события.подписать(this);
  9. };
  10. this.загрузитьСцену = function(имя)
  11. {
  12. let z64 = this.сцены[имя];
  13. window.location = адресИгры + z64;
  14. };
  15. this.загрузитьОглавление = function(адрес)
  16. {
  17. var тут = this;
  18. var запрос = new XMLHttpRequest();
  19. запрос.onreadystatechange = function()
  20. {
  21. if (this.readyState == 4)
  22. {
  23. if (this.status == 200)
  24. {
  25. тут.разобратьОглавление(this.responseText);
  26. }
  27. else
  28. {
  29. console.error("Не удалось загрузить оглавление сцен:", this.status);
  30. }
  31. }
  32. }
  33. запрос.open("GET", адрес);
  34. запрос.send();
  35. };
  36. this.задатьСостояниеИгрока = function(идёт, направление)
  37. {
  38. let стоятьЛ = this.задано["игрок.стоять.0"];
  39. let стоятьП = this.задано["игрок.стоять.1"];
  40. let идтиЛ = this.задано["игрок.идти.0"];
  41. let идтиП = this.задано["игрок.идти.1"];
  42. if (!стоятьЛ || !стоятьП || !идтиЛ || !идтиП)
  43. {
  44. return;
  45. }
  46. var название = идтиЛ;
  47. if (идёт && направление > 0)
  48. {
  49. название = идтиП;
  50. }
  51. else if (!идёт && направление < 0)
  52. {
  53. название = стоятьЛ;
  54. }
  55. else if (!идёт && направление > 0)
  56. {
  57. название = стоятьП;
  58. }
  59. if (this.состояниеИгрока != название)
  60. {
  61. состояниЯ.применить(название);
  62. this.состояниеИгрока = название;
  63. }
  64. };
  65. this.обновить = function()
  66. {
  67. this.переместитьИгрока();
  68. };
  69. this.обработатьКлюч = function(ключ, путь, значение)
  70. {
  71. if (!ключ.startsWith("gr.сцена"))
  72. {
  73. return;
  74. }
  75. var свойство = путь.slice(2).join(".");
  76. this.задано[свойство] = значение;
  77. if (свойство == "оглавление")
  78. {
  79. this.загрузитьОглавление(значение);
  80. }
  81. };
  82. this.обработатьНажатиеМышиУказатьИНажать = function(x, y, указатель)
  83. {
  84. let цель = this.задано["цель"];
  85. if (!this.типИгрыУказатьИНажать() || !цель)
  86. {
  87. return;
  88. }
  89. let тело = тела.тела[цель];
  90. if (!тело)
  91. {
  92. return;
  93. }
  94. var пр = [
  95. тело.bounds.min.x,
  96. тело.bounds.min.y,
  97. тело.bounds.max.x - тело.bounds.min.x,
  98. тело.bounds.max.y - тело.bounds.min.y,
  99. ]
  100. let ширина = пр[2];
  101. пр[0] = x - ширина;
  102. состояние.разобрать({
  103. тела: {
  104. [цель]: {
  105. пр: пр,
  106. },
  107. },
  108. });
  109. };
  110. this.обработатьСобытие = function(событие)
  111. {
  112. let мышь = "мышь/нажатие/";
  113. let сцена = "сцена/";
  114. if (событие.startsWith(мышь))
  115. {
  116. let значения = событие.substring(мышь.length).split("/");
  117. let x = Number(значения[0]);
  118. let y = Number(значения[1]);
  119. let указатель = значения[2];
  120. this.обработатьНажатиеМышиУказатьИНажать(x, y, указатель);
  121. }
  122. else if (событие.startsWith(сцена))
  123. {
  124. let название = событие.substring(сцена.length);
  125. this.загрузитьСцену(название);
  126. }
  127. };
  128. this.переместитьИгрока = function()
  129. {
  130. let цель = this.задано["цель"];
  131. let объект = this.задано["игрок.объект"];
  132. let скоростьX = this.задано["игрок.скорость.0"];
  133. if (!this.типИгрыУказатьИНажать() || !цель || !объект || !скоростьX)
  134. {
  135. return;
  136. }
  137. let игрок = `объекты-${объект}`;
  138. let телоЦели = тела.тела[цель];
  139. let телоИгрока = тела.тела[игрок];
  140. if (!телоЦели || !телоИгрока)
  141. {
  142. return;
  143. }
  144. let игрокX = телоИгрока.position.x;
  145. let цельX = телоЦели.position.x;
  146. let ширина = телоЦели.bounds.max.x - телоЦели.bounds.min.x;
  147. let расстояние = цельX - игрокX;
  148. let направление = расстояние > 0 ? 1 : -1;
  149. if (Math.abs(расстояние) < ширина / 2)
  150. {
  151. this.задатьСостояниеИгрока(false, направление);
  152. return;
  153. }
  154. this.задатьСостояниеИгрока(true, направление);
  155. Matter.Sleeping.set(телоИгрока, false);
  156. Matter.Body.setVelocity(телоИгрока, { x: скоростьX * направление, y: 0 });
  157. };
  158. this.разобратьОглавление = function(содержимое)
  159. {
  160. let код = "this.сцены = " + содержимое;
  161. eval(код);
  162. };
  163. this.типИгрыУказатьИНажать = function()
  164. {
  165. var тип = this.задано["тип"];
  166. return тип && тип == "указать и нажать";
  167. };
  168. // Конструктор.
  169. this.создать();
  170. };