25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.2KB

  1. function Слежение(состояние, изображения, тела)
  2. {
  3. this.создать = function()
  4. {
  5. this.умолчание = {
  6. смещение: [0, 0],
  7. скорость: 1,
  8. предел: 0,
  9. };
  10. this.задано = {};
  11. };
  12. this.обновить = function()
  13. {
  14. for (var имя in this.задано)
  15. {
  16. this.расположитьИзображение(имя);
  17. }
  18. };
  19. this.обработатьКлюч = function(ключ, путь, значение)
  20. {
  21. if (путь[0] != "слежение")
  22. {
  23. return;
  24. }
  25. var имя = путь[1];
  26. var свойство = путь.slice(2).join(".");
  27. if (!this.задано[имя])
  28. {
  29. this.задано[имя] = {};
  30. }
  31. this.задано[имя][свойство] = значение;
  32. };
  33. this.расположитьИзображение = function(имя)
  34. {
  35. let за = this.задано[имя];
  36. let тело = тела.тела[за.тело];
  37. let элемент = изображения.элементы[за.изображение];
  38. if (!тело || !элемент)
  39. {
  40. return;
  41. }
  42. let ум = this.умолчание;
  43. // Параметры.
  44. var скорость = за.скорость ? за.скорость : ум.скорость;
  45. var смещениеX = за["смещение.0"] ? за["смещение.0"] : ум.смещение[0];
  46. var смещениеY = за["смещение.1"] ? за["смещение.1"] : ум.смещение[1];
  47. var предел = за.предел ? за.предел : ум.предел;
  48. // Текущая позиция.
  49. var x0 = 0;
  50. if (элемент.dataset.слежениеX)
  51. {
  52. x0 = элемент.dataset.слежениеX;
  53. }
  54. var y0 = 0;
  55. if (элемент.dataset.слежениеY)
  56. {
  57. y0 = элемент.dataset.слежениеY;
  58. }
  59. // Целевая позиция.
  60. var x1 = тело.position.x + смещениеX;
  61. var y1 = тело.position.y + смещениеY;
  62. // Radians -> Degrees.
  63. var угол = тело.angle * 180 / Math.PI;
  64. // Устанавливаемая плавно позиция.
  65. var x = this.lerp(x0, x1, скорость, предел);
  66. var y = this.lerp(y0, y1, скорость, предел);
  67. // Ничего не делаем, если разница ничтожна.
  68. let ничтожно = 0.00001;
  69. if (
  70. элемент.dataset.слежениеX != null &&
  71. элемент.dataset.слежениеY != null &&
  72. элемент.dataset.слежениеУгол != null &&
  73. Math.abs(элемент.dataset.слежениеX - x) < ничтожно &&
  74. Math.abs(элемент.dataset.слежениеY - y) < ничтожно &&
  75. Math.abs(элемент.dataset.слежениеУгол - угол) < ничтожно
  76. ) {
  77. return;
  78. }
  79. // Иначе применяем новые значения.
  80. элемент.dataset.слежениеX = x;
  81. элемент.dataset.слежениеY = y;
  82. элемент.dataset.слежениеУгол = угол;
  83. var описание = {
  84. пр: [x, y],
  85. угол: угол,
  86. };
  87. состояние.разобратьЛишьНовое({
  88. изображения: {
  89. [за.изображение]: описание,
  90. },
  91. });
  92. };
  93. this.lerp = function(v0, v1, t, предел) {
  94. // Убираем мельтешение в случае наличия предела.
  95. if (предел)
  96. {
  97. var delta = Math.abs(v0 - v1);
  98. if (delta < предел) {
  99. return v0;
  100. }
  101. }
  102. return v0 * (1 - t) + v1 * t;
  103. };
  104. // Конструктор.
  105. this.создать();
  106. };