GlobalAPI.js

  1. /*
  2. * Copyright 2020 WICKLETS LLC
  3. *
  4. * This file is part of Wick Engine.
  5. *
  6. * Wick Engine is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Wick Engine is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Wick Engine. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. GlobalAPI = class {
  20. /**
  21. * Defines all api members such as functions and properties.
  22. * @type {string[]}
  23. */
  24. static get apiMemberNames () {
  25. return [
  26. 'stop','play','gotoAndStop','gotoAndPlay','gotoNextFrame','gotoPrevFrame',
  27. // These are currently disabled, they are very slow for some reason.
  28. // They are currently hacked in inside Tickable._runFunction
  29. //'project','root','parent','parentObject',
  30. 'isMouseDown','mouseX','mouseY','mouseMoveX','mouseMoveY',
  31. 'key','keys','isKeyDown','keyIsDown','isKeyJustPressed','keyIsJustPressed',
  32. 'random',
  33. 'playSound','stopAllSounds',
  34. 'onEvent',
  35. 'hideCursor','showCursor',
  36. 'hitTestOptions',
  37. ];
  38. }
  39. /**
  40. * @param {object} scriptOwner The tickable object which owns the script being evaluated.
  41. */
  42. constructor (scriptOwner) {
  43. this.scriptOwner = scriptOwner;
  44. }
  45. /**
  46. * Returns a list of api members bound to the script owner.
  47. * @returns {object[]} Array of functions, properties, and api members.
  48. */
  49. get apiMembers () {
  50. var members = [];
  51. GlobalAPI.apiMemberNames.forEach(name => {
  52. var fn = this[name];
  53. if(fn instanceof Function) {
  54. fn = fn.bind(this);
  55. }
  56. members.push({
  57. name: name,
  58. fn: fn,
  59. })
  60. });
  61. return members;
  62. }
  63. /**
  64. * Stops the timeline of the object's parent clip.
  65. */
  66. stop () {
  67. this.scriptOwner.parentClip.stop();
  68. }
  69. /**
  70. * Plays the timeline of the object's parent clip.
  71. */
  72. play () {
  73. this.scriptOwner.parentClip.play();
  74. }
  75. /**
  76. * Moves the plahead of the parent clip to a frame and stops the timeline of that parent clip.
  77. * @param {string | number} frame Frame name or number to move playhead to.
  78. */
  79. gotoAndStop (frame) {
  80. this.scriptOwner.parentClip.gotoAndStop(frame);
  81. }
  82. /**
  83. * Moves the plahead of the parent clip to a frame and plays the timeline of that parent clip.
  84. * @param {string | number} frame Frame name or number to move playhead to.
  85. */
  86. gotoAndPlay (frame) {
  87. this.scriptOwner.parentClip.gotoAndPlay(frame);
  88. }
  89. /**
  90. * Moves the playhead of the parent clip of the object to the next frame.
  91. */
  92. gotoNextFrame () {
  93. this.scriptOwner.parentClip.gotoNextFrame();
  94. }
  95. /**
  96. * Moves the playhead of the parent clip of this object to the previous frame.
  97. */
  98. gotoPrevFrame () {
  99. this.scriptOwner.parentClip.gotoPrevFrame();
  100. }
  101. hitTestOptions (options) {
  102. this.scriptOwner.project.hitTestOptions = options;
  103. }
  104. /**
  105. * Returns an object representing the project with properties such as width, height, framerate, background color, and name.
  106. * @returns {object} Project object.
  107. */
  108. get project () {
  109. var project = this.scriptOwner.project && this.scriptOwner.project.root;
  110. if(project) {
  111. // Attach some aliases to the project settings
  112. project.width = this.scriptOwner.project.width;
  113. project.height = this.scriptOwner.project.height;
  114. project.framerate = this.scriptOwner.project.framerate;
  115. project.backgroundColor = this.scriptOwner.project.backgroundColor;
  116. project.name = this.scriptOwner.project.name;
  117. project.hitTestOptions = this.scriptOwner.project.hitTestOptions;
  118. }
  119. return project;
  120. }
  121. /**
  122. * @deprecated
  123. * Legacy item which returns the project. Use 'project' instead.
  124. */
  125. get root () {
  126. return this.project;
  127. }
  128. /**
  129. * Returns a reference to the current object's parent.
  130. * @returns Current object's parent.
  131. */
  132. get parent () {
  133. return this.scriptOwner.parentClip;
  134. }
  135. /**
  136. * @deprecated
  137. * Legacy item which returns the parent clip. Use 'parent' instead.
  138. */
  139. get parentObject () {
  140. return this.scriptOwner.parentClip;
  141. }
  142. /**
  143. * Returns the last key pressed down.
  144. * @returns {string | null} Returns null if no key has been pressed yet.
  145. */
  146. get key () {
  147. if(!this.scriptOwner.project) return null;
  148. return this.scriptOwner.project.currentKey;
  149. }
  150. /**
  151. * Returns a list of all keys currently pressed down.
  152. * @returns {string[]} All keys represented as strings. If no keys are pressed, an empty array is returned.
  153. */
  154. get keys () {
  155. if(!this.scriptOwner.project) return null;
  156. return this.scriptOwner.project.keysDown;
  157. }
  158. /**
  159. * Returns true if the given key is currently down.
  160. * @param {string} key
  161. * @returns {bool}
  162. */
  163. isKeyDown (key) {
  164. if(!this.scriptOwner.project) return null;
  165. return this.scriptOwner.project.isKeyDown(key);
  166. }
  167. /**
  168. * @deprecated
  169. * Legacy item, use 'isKeyDown' instead.
  170. */
  171. keyIsDown (key) {
  172. return this.isKeyDown(key.toLowerCase());
  173. }
  174. /**
  175. * Returns true if the given key was just pressed within the last tick.
  176. * @param {string} key
  177. * @returns {bool}
  178. */
  179. isKeyJustPressed (key) {
  180. if(!this.scriptOwner.project) return null;
  181. return this.scriptOwner.project.isKeyJustPressed(key);
  182. }
  183. /**
  184. * @deprecated
  185. * Legacy item, use 'isKeyJustPressed' instead.
  186. */
  187. keyIsJustPressed (key) {
  188. return this.keyIsJustPressed(key.toLowerCase());
  189. }
  190. /**
  191. * Returns true if the mouse is currently held down.
  192. * @returns {bool | null} Returns null if the object does not have a project.
  193. */
  194. isMouseDown () {
  195. if(!this.scriptOwner.project) return null;
  196. return this.scriptOwner.project.isMouseDown;
  197. }
  198. /**
  199. * Returns the current x position of the mouse in relation to the canvas.
  200. * @returns {number}
  201. */
  202. get mouseX () {
  203. if(!this.scriptOwner.project) return null;
  204. return this.scriptOwner.project.mousePosition.x;
  205. }
  206. /**
  207. * Returns the current y position of the mouse in relation to the canvas.
  208. * @returns {number}
  209. */
  210. get mouseY () {
  211. if(!this.scriptOwner.project) return null;
  212. return this.scriptOwner.project.mousePosition.y;
  213. }
  214. /**
  215. * Returns the amount the mouse moved in the last tick on the x axis.
  216. * @returns {number}
  217. */
  218. get mouseMoveX () {
  219. if(!this.scriptOwner.project) return null;
  220. return this.scriptOwner.project.mouseMove.x;
  221. }
  222. /**
  223. * Returns the amount the mouse moved in the last tick on the y axis.
  224. * @returns {number}
  225. */
  226. get mouseMoveY () {
  227. if(!this.scriptOwner.project) return null;
  228. return this.scriptOwner.project.mouseMove.y;
  229. }
  230. /**
  231. * Returns a new random object.
  232. * @returns {GlobalAPI.Random}
  233. */
  234. get random () {
  235. return new GlobalAPI.Random();
  236. }
  237. /**
  238. * Plays a sound which is currently in the asset library.
  239. * @param {string} name - name of the sound asset in the library.
  240. * @param {Object} options - options for the sound. See Wick.SoundAsset.play
  241. * @returns {object} object representing the sound which was played.
  242. */
  243. playSound (assetName, options) {
  244. if(!this.scriptOwner.project) return null;
  245. return this.scriptOwner.project.playSound(assetName, options);
  246. }
  247. /**
  248. * Stops sound(s) currently playing.
  249. * @param {string} assetName - The name of the SoundAsset to stop.
  250. * @param {number} id - (optional) The ID of the sound to stop. Returned by playSound. If an ID is not given, all instances of the given sound asset will be stopped.
  251. */
  252. stopSound (assetName, id) {
  253. if(!this.scriptOwner.project) return null;
  254. return this.scriptOwner.project.stopSound(assetName, id);
  255. }
  256. /**
  257. * Stops all currently playing sounds.
  258. */
  259. stopAllSounds () {
  260. if(!this.scriptOwner.project) return null;
  261. this.scriptOwner.project.stopAllSounds();
  262. }
  263. /**
  264. * Attach a function to an event with a given name.
  265. * @param {string} name - the name of the event to attach the function to
  266. * @param {function} fn - the function to attach to the event
  267. */
  268. onEvent (name, fn) {
  269. this.scriptOwner.onEvent(name, fn);
  270. }
  271. /**
  272. * Hide the cursor while the project is running.
  273. */
  274. hideCursor () {
  275. if(!this.scriptOwner.project) return null;
  276. this.scriptOwner.project.hideCursor = true;
  277. }
  278. /**
  279. * Don't hide the cursor while the project is running.
  280. */
  281. showCursor () {
  282. if(!this.scriptOwner.project) return null;
  283. this.scriptOwner.project.hideCursor = false;
  284. }
  285. }
  286. GlobalAPI.Random = class {
  287. constructor () {
  288. }
  289. /**
  290. * Returns a random integer (whole number) between two given numbers, 0 and a given number, or 0 and 1. The random number is inclusive of the maximum range.
  291. * @param {number} min The minimum of the returned integer, or the maximum of the returned number if it is the only argument.
  292. * @param {number} max The maximum of the returned integer.
  293. * @returns {number} A random number between num1 and num2, 0 and num1, or 0 and 1. Will return 0 if max is greater than min.
  294. * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
  295. */
  296. integer(min,max) {
  297. if (typeof min === 'undefined' && typeof max === 'undefined') {
  298. min = 0;
  299. max = 1;
  300. } else if (typeof min === 'number' && typeof max === 'undefined') {
  301. max = Math.ceil(min);
  302. min = 0;
  303. }
  304. if (max < min) return 0;
  305. // The maximum is inclusive and the minimum is inclusive
  306. return Math.floor(Math.random() * (max - min + 1) + min);
  307. }
  308. /**
  309. * Returns a random floating point (decimal) number between two given numbers, 0 and a given number, or 0 and 1.
  310. * @param {number} num1 The minimum of the returned number, or the maximum of the returned number if it is the only argument.
  311. * @param {number} num2 The maximum of the returned number.
  312. * @returns {number} A random number between num1 and num2, 0 and num1, or 0 and 1.
  313. * https://stackoverflow.com/questions/4959975/generate-random-number-between-two-numbers-in-javascript
  314. */
  315. float(num1, num2) {
  316. if ((typeof num1 !== "undefined") && (typeof num2 !== "undefined")) {
  317. return (Math.random()*(num2-num1)+num1);
  318. } else if ((typeof num1 !== "undefined") && (typeof num2 == "undefined")) {
  319. return Math.random()*num1;
  320. } else {
  321. return Math.random();
  322. }
  323. }
  324. /**
  325. * Returns a random item from an array of items.
  326. * @param {array} An array of objects.
  327. * @returns {object | null} A random item contained in the array. Returns null if the given array has no items.
  328. * https://stackoverflow.com/questions/4550505/getting-a-random-value-from-a-javascript-array
  329. */
  330. choice(array) {
  331. if (array.length <= 0) return null;
  332. return array[Math.floor(Math.random() * array.length)]
  333. }
  334. }