editor.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. let editorState = "";
  2. let start = { x: 0, y: 0 };
  3. let end = { x: 0, y: 0 };
  4. let started = false;
  5. let selectedSprite;
  6. window.addEventListener("keydown", event => {
  7. switch (event.keyCode) {
  8. case 27:
  9. editorState = "";
  10. delete localStorage['selectedSprite'];
  11. break;
  12. case 87:
  13. if (event.shiftKey) {
  14. editorState = "wall";
  15. }
  16. break;
  17. case 84:
  18. if (event.shiftKey) {
  19. editorState = "tile";
  20. window.open(`spritesheet.html?path=${encodeURI(atlas.assetsPath)}&file=${encodeURI(atlas.xmlFilename)}`, "Spritesheet", `width=${atlas.spritesheetImage.width},height=${atlas.spritesheetImage.height}`);
  21. }
  22. break;
  23. case 82:
  24. if (event.shiftKey) {
  25. editorState = "decal";
  26. window.open(`spritesheet.html?path=${encodeURI(atlas.assetsPath)}&file=${encodeURI(atlas.xmlFilename)}`, "Spritesheet", `width=${atlas.spritesheetImage.width},height=${atlas.spritesheetImage.height}`);
  27. }
  28. break;
  29. case 46:
  30. deleteObject();
  31. break;
  32. }
  33. });
  34. window.addEventListener("mousedown", event => {
  35. started = true;
  36. switch (editorState) {
  37. case "wall":
  38. updateStart(event);
  39. break;
  40. case "tile":
  41. updateEnd(event);
  42. setTile(event);
  43. break;
  44. }
  45. });
  46. window.addEventListener("contextmenu", event => {
  47. event.preventDefault();
  48. switch (editorState) {
  49. case "tile":
  50. updateEnd(event);
  51. break;
  52. }
  53. return false;
  54. });
  55. window.addEventListener("mousemove", event => {
  56. switch (editorState) {
  57. case "wall":
  58. updateEnd(event);
  59. break;
  60. case "tile":
  61. updateEnd(event);
  62. break;
  63. case "decal":
  64. updateEnd(event);
  65. selectedSprite = JSON.parse(localStorage['selectedSprite']);
  66. break;
  67. }
  68. });
  69. window.addEventListener("mouseup", event => {
  70. started = false;
  71. switch (editorState) {
  72. case "wall":
  73. updateEnd(event)
  74. addWall(event);
  75. break;
  76. case "tile":
  77. if(!!localStorage['selectedSprite']) {
  78. setTile(event);
  79. }
  80. break;
  81. case "decal":
  82. updateEnd(event);
  83. if(!!localStorage['selectedSprite']) {
  84. placeDecal(event);
  85. }
  86. break;
  87. }
  88. });
  89. window.addEventListener('wheel', event => {
  90. switch (editorState) {
  91. }
  92. });
  93. function deleteObject() {
  94. switch (editorState) {
  95. case "wall":
  96. let wallsToDelete = [];
  97. roomData.walls.forEach(wall => {
  98. if (pointCollision(wall, end)) {
  99. wallsToDelete.push(wall);
  100. return;
  101. }
  102. });
  103. wallsToDelete.forEach(wallToDelete => {
  104. roomData.walls.splice(roomData.walls.indexOf(wallToDelete), 1);
  105. });
  106. ajaxPost(`${apidataurl}/room-${userData.coordinates.x},${userData.coordinates.y}`, roomData).then(result => {
  107. getRoom(userData.coordinates.x, userData.coordinates.y);
  108. });
  109. break;
  110. case "decal":
  111. let decalsToDelete = [];
  112. roomData.decals.forEach(decal => {
  113. if (pointCollision(decal, end)) {
  114. decalsToDelete.push(decal);
  115. return;
  116. }
  117. });
  118. decalsToDelete.forEach(decalToDelete => {
  119. roomData.decals.splice(roomData.decals.indexOf(decalToDelete), 1);
  120. });
  121. ajaxPost(`${apidataurl}/room-${userData.coordinates.x},${userData.coordinates.y}`, roomData).then(result => {
  122. getRoom(userData.coordinates.x, userData.coordinates.y);
  123. });
  124. break;
  125. }
  126. }
  127. function updateStart(event) {
  128. let canvasBounds = canvas.getBoundingClientRect();
  129. start = { x: (event.clientX - canvasBounds.x) / canvasBounds.width, y: (event.clientY - canvasBounds.y) / canvasBounds.height };
  130. }
  131. function updateEnd(event) {
  132. let canvasBounds = canvas.getBoundingClientRect();
  133. end = { x: (event.clientX - canvasBounds.x) / canvasBounds.width, y: (event.clientY - canvasBounds.y) / canvasBounds.height };
  134. }
  135. function getWallBounds(start, end) {
  136. let bounds = {
  137. x: 0,
  138. y: 0,
  139. width: 0,
  140. height: 0,
  141. };
  142. if (end.x > start.x) {
  143. bounds.x = start.x;
  144. } else {
  145. bounds.x = end.x;
  146. }
  147. if (end.y > start.y) {
  148. bounds.y = start.y;
  149. } else {
  150. bounds.y = end.y;
  151. }
  152. bounds.width = Math.abs(start.x - end.x);
  153. bounds.height = Math.abs(start.y - end.y);
  154. return bounds;
  155. }
  156. function addWall(event) {
  157. ajaxGet(`${apidataurl}/room-${userData.coordinates.x},${userData.coordinates.y}`).then(currentRoom => {
  158. let bounds = getWallBounds(start, end);
  159. let newWall = {
  160. x: bounds.x,
  161. y: bounds.y,
  162. width: bounds.width,
  163. height: bounds.height,
  164. color: "black"
  165. };
  166. if (newWall.width == 0 || newWall.height == 0) {
  167. return;
  168. }
  169. currentRoom.walls.push(newWall);
  170. roomData.walls = currentRoom.walls;
  171. ajaxPost(`${apidataurl}/room-${userData.coordinates.x},${userData.coordinates.y}`, currentRoom).then(result => {
  172. getRoom(userData.coordinates.x, userData.coordinates.y);
  173. });
  174. });
  175. }
  176. function setTile(event) {
  177. let canvasBounds = canvas.getBoundingClientRect();
  178. let trueTile = {
  179. x: Math.floor((event.clientX - canvasBounds.x) / 126) * 126,
  180. y: Math.floor((event.clientY - canvasBounds.y) / 126) * 126,
  181. width: 126,
  182. height: 126
  183. }
  184. let x = trueTile.x / 126;
  185. let y = trueTile.y / 126;
  186. let tileIndex = 8 * y + x;
  187. try {
  188. let selectedSprite = JSON.parse(localStorage['selectedSprite']);
  189. roomData.tiles[tileIndex] = selectedSprite.name;
  190. ajaxPost(`${apidataurl}/room-${userData.coordinates.x},${userData.coordinates.y}`, roomData);
  191. } catch (e) {
  192. console.error(e);
  193. }
  194. }
  195. function placeDecal(event) {
  196. let newDecal = {
  197. "spriteName": selectedSprite.name,
  198. "x": end.x - ((selectedSprite.width / canvas.width) / 2),
  199. "y": end.y - ((selectedSprite.height / canvas.height) / 2),
  200. "width": selectedSprite.width / canvas.width,
  201. "height": selectedSprite.height / canvas.height
  202. };
  203. roomData.decals.push(newDecal);
  204. try {
  205. ajaxPost(`${apidataurl}/room-${userData.coordinates.x},${userData.coordinates.y}`, roomData);
  206. } catch (e) {
  207. console.error(e);
  208. }
  209. }
  210. function drawEditor(context) {
  211. document.body.style.cursor = "auto";
  212. if (editorState != "") {
  213. document.body.style.cursor = "crosshair";
  214. context.font = "14px Arial";
  215. context.textAlign = "center";
  216. context.fillStyle = "#000000";
  217. context.fillText("Editor mode:" + editorState.toLocaleUpperCase(), 504, 20);
  218. }
  219. switch (editorState) {
  220. case "wall":
  221. if (!started) {
  222. roomData.walls.forEach(wall => {
  223. if (pointCollision(wall, end)) {
  224. context.beginPath();
  225. context.strokeStyle = "red";
  226. context.fillStyle = "rgba(255, 150, 150, 0.2)";
  227. context.rect(wall.x * canvas.width, wall.y * canvas.height, wall.width * canvas.width, wall.height * canvas.height);
  228. context.fill();
  229. context.stroke();
  230. } else {
  231. context.beginPath();
  232. context.strokeStyle = wall.color ?? "red";
  233. context.rect(wall.x * canvas.width, wall.y * canvas.height, wall.width * canvas.width, wall.height * canvas.height);
  234. context.stroke();
  235. context.strokeStyle = "#000000";
  236. context.beginPath();
  237. context.rect(userData.position.x * canvas.width, userData.position.y * canvas.height, userData.size.width * canvas.width, userData.size.height * canvas.height);
  238. context.stroke();
  239. }
  240. });
  241. return;
  242. }
  243. context.fillStyle = "rgba(150, 255, 150, 0.2)";
  244. context.strokeStyle = "rgba(50, 255, 50, 1)";
  245. let bounds = getWallBounds(start, end);
  246. context.beginPath();
  247. context.rect(bounds.x * canvas.width, bounds.y * canvas.height, bounds.width * canvas.width, bounds.height * canvas.height);
  248. context.fill();
  249. context.stroke();
  250. break;
  251. case "tile":
  252. context.fillStyle = "rgba(150, 255, 150, 0.2)";
  253. context.strokeStyle = "rgba(50, 255, 50, 1)";
  254. let trueTile = {
  255. x: Math.floor(end.x * canvas.width / 126) * 126,
  256. y: Math.floor(end.y * canvas.height / 126) * 126,
  257. width: 126,
  258. height: 126
  259. }
  260. context.beginPath();
  261. context.rect(trueTile.x, trueTile.y, trueTile.width, trueTile.height);
  262. context.fill();
  263. context.stroke();
  264. break;
  265. case "decal":
  266. if(!!selectedSprite) {
  267. let centerPos = { x: (end.x * canvas.width), y: (end.y * canvas.height)};
  268. atlas.drawCentered(context, selectedSprite.name, centerPos);
  269. }
  270. break;
  271. }
  272. }