PlayerNavigationHud.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. require('TemplateLoader');
  2. class PlayerNavigationHud {
  3. constructor() {
  4. this.templateLoader = new TemplateLoader();
  5. this.containerId = "navigation-container";
  6. this.systemContext = null;
  7. this.mousePosition = { x: 0, y: 0 };
  8. this.lastSector = { x: 3, y: 1 };
  9. this.currentSector = { x: 3, y: 1 };
  10. this.targetSector = { x: 3, y: 1 };
  11. this.invalidSectors = [];
  12. this.gridSize = 32;
  13. this.halfGridSize = 16;
  14. this.travelEndTime = 0;
  15. this.travelDuration = 0;
  16. }
  17. async attach(parent) {
  18. let template = await this.templateLoader.get('navigation');
  19. let container = document.getElementById(this.containerId);
  20. container.innerHTML = template;
  21. this.systemCanvas = document.getElementById("navigation--system");
  22. this.impulseButton = document.getElementById("navigation--impulse");
  23. this.impulseButton.addEventListener('click', (event) => this.startShipTravel(event));
  24. this.starchartCanvas = document.getElementById("navigation--starchart");
  25. this.jumpButton = document.getElementById("navigation--jump");
  26. this.systemCanvas.addEventListener('mousemove', (event) => this.handleMouseMove(event));
  27. this.systemCanvas.addEventListener('click', (event) => this.handleMouseClick(event));
  28. this.handleResize();
  29. this.buildSectorData();
  30. this.impulseButton.style.visibility = "hidden";
  31. this.hide();
  32. }
  33. buildSectorData() {
  34. this.invalidSectors = [];
  35. for (let x = 0; x <= Math.floor(this.systemCanvas.width / this.gridSize); x++) {
  36. for (let y = 0; y <= Math.floor(this.systemCanvas.height / this.gridSize); y++) {
  37. this.invalidSectors.push({ x: x, y: y });
  38. }
  39. }
  40. let items = game.sector.getItems();
  41. for (let i = 0; i < items.length; i++) {
  42. let itemCoords = items[i].getCoordinates();
  43. this.invalidSectors.splice(this.invalidSectors.findIndex((sector) => {
  44. return sector.x == itemCoords.x && sector.y == itemCoords.y;
  45. }), 1);
  46. }
  47. this.impulseButton.style.visibility = "hidden";
  48. }
  49. draw() {
  50. let currentTime = new Date().getTime();
  51. if (this.travelEndTime > currentTime) {
  52. let distanceTraveled = 1 - ((this.travelEndTime - currentTime) / this.travelDuration);
  53. let xDelta = this.targetSector.x - this.lastSector.x;
  54. let yDelta = this.targetSector.y - this.lastSector.y;
  55. this.currentSector.x = this.lastSector.x + (xDelta * distanceTraveled);
  56. this.currentSector.y = this.lastSector.y + (yDelta * distanceTraveled);
  57. }
  58. if (this.systemCanvas) {
  59. this.systemContext.clearRect(0, 0, this.systemCanvas.width, this.systemCanvas.height);
  60. this.systemContext.save();
  61. this.systemContext.translate(0.5, 0.5);
  62. this.systemDraw(this.systemContext);
  63. this.drawMovementCursor(this.systemContext);
  64. this.systemContext.restore();
  65. }
  66. }
  67. drawMovementCursor(context) {
  68. if (this.isInvalidSector(this.mousePosition)) {
  69. context.strokeStyle = "#FF0000";
  70. } else {
  71. context.strokeStyle = "#00FF00";
  72. }
  73. context.save();
  74. context.translate((this.mousePosition.x * this.gridSize) + this.halfGridSize, (this.mousePosition.y * this.gridSize) + this.halfGridSize);
  75. context.lineWidth = 2;
  76. this.cursor(context);
  77. context.restore();
  78. this.drawTargetSector(context);
  79. this.drawCurrentSector(context);
  80. }
  81. isInvalidSector(position) {
  82. for (let i = 0; i < this.invalidSectors.length; i++) {
  83. let sector = this.invalidSectors[i];
  84. if (position.x == sector.x && position.y == sector.y) {
  85. return true;
  86. }
  87. }
  88. return false;
  89. }
  90. drawCurrentSector(context) {
  91. context.strokeStyle = "#0000FF";
  92. context.save();
  93. context.translate(Math.floor(this.currentSector.x * this.gridSize) + this.halfGridSize, Math.floor(this.currentSector.y * this.gridSize) + this.halfGridSize);
  94. context.lineWidth = 2;
  95. this.cursor(context);
  96. context.restore();
  97. }
  98. cursor(context) {
  99. context.beginPath();
  100. context.moveTo(-this.halfGridSize, -this.halfGridSize);
  101. context.lineTo(-this.halfGridSize, -(this.halfGridSize / 2));
  102. context.moveTo(-this.halfGridSize, -this.halfGridSize);
  103. context.lineTo(-(this.halfGridSize / 2), -this.halfGridSize);
  104. context.moveTo(this.halfGridSize, this.halfGridSize);
  105. context.lineTo(this.halfGridSize, (this.halfGridSize / 2));
  106. context.moveTo(this.halfGridSize, this.halfGridSize);
  107. context.lineTo((this.halfGridSize / 2), this.halfGridSize);
  108. context.moveTo(-this.halfGridSize, this.halfGridSize);
  109. context.lineTo(-this.halfGridSize, (this.halfGridSize / 2));
  110. context.moveTo(-this.halfGridSize, this.halfGridSize);
  111. context.lineTo(-(this.halfGridSize / 2), this.halfGridSize);
  112. context.moveTo(this.halfGridSize, -this.halfGridSize);
  113. context.lineTo(this.halfGridSize, -(this.halfGridSize / 2));
  114. context.moveTo(this.halfGridSize, -this.halfGridSize);
  115. context.lineTo((this.halfGridSize / 2), -this.halfGridSize);
  116. context.stroke();
  117. }
  118. drawTargetSector(context) {
  119. context.strokeStyle = "#FFFF00";
  120. context.save();
  121. context.translate(Math.floor(this.targetSector.x * this.gridSize) + this.halfGridSize, Math.floor(this.targetSector.y * this.gridSize) + this.halfGridSize);
  122. context.lineWidth = 2;
  123. this.cursor(context);
  124. context.restore();
  125. if (this.currentSector.x != this.targetSector.x ||
  126. this.currentSector.y != this.targetSector.y) {
  127. context.strokeStyle = "#FFFF00";
  128. context.lineWidth = 1;
  129. context.setLineDash([3, 6]);
  130. context.beginPath();
  131. context.moveTo(Math.floor(this.currentSector.x * this.gridSize) + this.halfGridSize, Math.floor(this.currentSector.y * this.gridSize) + this.halfGridSize);
  132. context.lineTo(Math.floor(this.targetSector.x * this.gridSize) + this.halfGridSize, Math.floor(this.targetSector.y * this.gridSize) + this.halfGridSize);
  133. context.stroke();
  134. context.setLineDash([]);
  135. }
  136. }
  137. systemDraw(context) {
  138. game.sector.drawNav(context, this.gridSize, this.halfGridSize);
  139. }
  140. handleResize(event) {
  141. let dpi = system.getDpi();
  142. this.gridSize = 32 * dpi;
  143. this.halfGridSize = 16 * dpi;
  144. if (this.systemCanvas) {
  145. this.systemCanvas.width = this.systemCanvas.clientWidth * dpi;
  146. this.systemCanvas.height = this.systemCanvas.clientHeight * dpi;
  147. this.systemContext = this.systemCanvas.getContext('2d');
  148. this.systemContext.webkitImageSmoothingEnabled = true;
  149. this.systemContext.imageSmoothingEnabled = true;
  150. this.systemCenter = { x: Math.floor(this.systemCanvas.width / 2), y: Math.floor(this.systemCanvas.height / 2) };
  151. }
  152. }
  153. startShipTravel(event) {
  154. game.startShipTravel();
  155. }
  156. startTravelAnimation(duration) {
  157. this.travelDuration = duration;
  158. this.travelEndTime = new Date().getTime() + duration;
  159. }
  160. finishShipTravel() {
  161. this.currentSector.x = this.targetSector.x;
  162. this.currentSector.y = this.targetSector.y;
  163. this.lastSector.x = this.currentSector.x;
  164. this.lastSector.y = this.currentSector.y;
  165. this.buildSectorData();
  166. }
  167. hide() {
  168. document.getElementById(this.containerId).style.opacity = "0";
  169. document.getElementById(this.containerId).style.visibility = "hidden";
  170. }
  171. show() {
  172. document.getElementById(this.containerId).style.opacity = "1";
  173. document.getElementById(this.containerId).style.visibility = "visible";
  174. }
  175. handleMouseMove(event) {
  176. let dpi = system.getDpi();
  177. this.mousePosition.x = Math.floor((event.offsetX * dpi) / this.gridSize);
  178. this.mousePosition.y = Math.floor((event.offsetY * dpi) / this.gridSize);
  179. }
  180. handleMouseClick(event) {
  181. if (!this.isInvalidSector(this.mousePosition)) {
  182. this.targetSector = { x: this.mousePosition.x, y: this.mousePosition.y };
  183. this.impulseButton.style.visibility = "visible";
  184. }
  185. if (this.currentSector.x == this.targetSector.x && this.currentSector.y == this.targetSector.y) {
  186. this.impulseButton.style.visibility = "hidden";
  187. }
  188. }
  189. }