litecanvas 0.53.0 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,13 +11,13 @@ Litecanvas is a lightweight HTML5 canvas engine suitable for small games, animat
11
11
  ### Features
12
12
 
13
13
  - **Tiny**: Only `~4KB` (minified + gzipped).
14
- - **Simple API**: Just few functions to draw shapes and some utilities to other things like sounds and math.
14
+ - **Simple API**: Just few functions to draw shapes and some utilities.
15
15
  - **Predefined colors**: Just use a number (from 0 to 11) to choose a color in our 12-color palette.
16
- - **Predefined sounds**: Packed with 4 sounds created in [ZzFX](https://killedbyapixel.github.io/ZzFX/).
16
+ - **ZzFX**: Play or create sound effects with [ZzFX](https://killedbyapixel.github.io/ZzFX/).
17
17
  - **Extensible**: Use or create [plugins](https://www.npmjs.com/search?q=keywords:litecanvas) to add functionalities or change the engine.
18
- - **Offline Playground**: Install the [playground](https://litecanvas.js.org/) webapp and use anywhere at any time.
18
+ - **Playground**: Access or install the [playground](https://litecanvas.js.org/) webapp to code and share games (even offline).
19
19
 
20
- [Learn more...](https://litecanvas.js.org/about.html)
20
+ [Learn more in the cheatsheet...](https://litecanvas.js.org/about.html)
21
21
 
22
22
  ## Getting Started
23
23
 
@@ -38,6 +38,8 @@ npm install litecanvas
38
38
  ```
39
39
 
40
40
  ```js
41
+ // import the engine or put the script in your HTML
42
+ // CDN: https://unpkg.com/browse/litecanvas/dist/
41
43
  import litecanvas from 'litecanvas'
42
44
 
43
45
  // you can setup other configurations here
@@ -84,7 +86,7 @@ Check out our [Cheatsheet](https://litecanvas.js.org/about.html).
84
86
 
85
87
  Try some demos in our playground:
86
88
 
87
- - [Pong](https://litecanvas.js.org?c=eJy1VV1S20gQfvcpOk%2BSsMCywQlFYVIu4gWqdsMWuEL8OEgje2rlkWs0BpKQXGFPsG85RM6zF9grbPf0SJYJSe3LVhl7erqn%2B%2Fv6j0JZmQp9J6rwUwfgXmV2cQT7gyRGaSHVfGGP4OAw6XyOOp18rVOrSg1KKxtGQC9WIruBEfQHCQvnJAz5%2FJ7OiVfMUDjYJyGTlSUVWaB4K4qCxNPJ2%2Bnkqr6ZNTcz2IXzycXZ%2BRR6cODV1%2BqjrCORPNbzgi6cf2VcZD7O%2FLFaSZnheeAAVWlpavtC5bLC8z6erXyw3vfNxZvpOYY8JHMrjHXPc1FUsoNXvR4UpchAQLqubLmEvNSWvOHlL3gMg2Wpy7kRyyCGoEfaqldf7Vmb43VoZBXB6MRlEkDl%2FoZQ5Ns%2BImchMTjYhSnvITgVGnRpGQVZB2iCZfrcKpQVq5XMwocYPnC5KMQLzybyYdv0rFlLf2mkXRtNPls1%2B%2FIlfMB6uKr3YLAdbb3KhJVhZp%2BLxe4obVZZrFWVGin1a2%2FnazDCirRN52IpobyT5rVP%2BRIFTIAkBFkh%2FWvXay%2FwsYNZ8%2FIdWEizchYxq2NI9pJh5Iix06zUAeZR2pZnFIUPxUjboY4JpXdPHeTK0mi7nJ4T7qDGkPuJc9fx3rjTu5uWPvGtXnOoh6P%2FMmlk6uhXLNaty7%2B7rtGxnPlDuN8myIVxj2FVVoqq1Uxed8QTs%2BNHZAcy2wwhK2fbSnZ6W2LdvVMs%2FlaWvOc2L6b%2F%2BOijHje6miqDGMHuhkQ%2F8u23ydWz7%2BoZ33rFKNOFTP9gkGlZFKqiRr1XdrHdQagzMrUMPGbycROqfeJOooXmvm9i6EdPoNQM3I7p0g5ssCWMrT01mRH3fpmmRUUWHtOvl%2BM3F2%2FP6nmor5%2BOLy0LUai5DoNUaisN7ZulInJ%2Ba5BFheDDerttrkO%2FdeN62eLb6fh3mF7C9XR8NUVf3EmbHudeO6ERYACUuFwVRfh9augfgveA7JRJnd2Pkjx01J%2FBy6vmCVmXBuK6EHqu9LxFNuwnWBb8C%2F7%2B6%2Bs%2F3%2F6EYM%2FIlRSWwUcxHLRCeX9SZ897%2B1Hq6oGmQPgJgwA73hU92kPi14QvfIm6aDuJ%2F0fZEMZgiA7Oxr9N4PLd5Cpo0v59NndwAx4Of%2Baty9m7Pr28mhwRrf9ADpv6X2AjW9I%3D)
89
+ - [Pong](https://litecanvas.js.org?c=eJy1Vmtu20YQ%2Fs9TTH%2BRjCia1MOO3diBotJxgNQqJLW2WhQFQ66kRWmSIFexm8S5Qk6Qfz1Ez9ML9Aqd2V2%2BHNvNn1rwivPYeX4zVMIFi8L0bVha7w3Av2sei%2B0RDAeeI%2Bkt45utOILRU2Tc2oaxtwfTXSmyK%2Fj53ekllNkujUtYZwWILS9hE14x0skLJgRnRZ9v0qxgRpSlpYAXsx%2FPpwEcwy8OOOCzIX253pCOATIcGBDHgcORpwXVx0WJu6%2F093%2F99mEfi%2BVkviQXnjt2AM2MPU9dG%2BExbHsZH3jaszy0I2%2F0mPkXk9evf5udni6m8yA4Jz%2B%2BO%2FRlOmN04LkeeSU%2FeBxIb5LqH7qHeO7TSR%2FP9f3qaSDvyXMkT58yNBImIA%2FjC3TiV%2F1A%2BozocU1eEuk14hXSo6GmY1YKUiA9xXkTJknrcdU8Lvg71jJNrEm6SYhXWeOF9FZTq4Yqc8ZiJAdVKGWERWvuJnzNSiSHihTsRpBDrSvCQsjr6zApmWGsd2kkeJYCT7mwbHjfxI5K0%2BB8GcwvmyRq3gr6cBa8enm2hD0YdTyhzsWr75ZnKPAHxm3LhwjznMXWjQN%2FVJ74GqxvdFQVrxuoKHasYa9vLIk7u2YheHZFKsnbTis%2BfrRuMErZ2D0Y2J1QdnkcCmbF4v5AlFFAcAousDNlVDCWPq81dZGPseptZRpKyN6y4rkhVZF1hSROLKM44oS1wZSwIrckYFTMCtR2fTXOUlMAgbO5j2SoDaqY6pCk0WcUjzbvSRHDNjfynirHiepQrar6pWpl1BZVx3sNZk90y9uNqqDi73sdHkHloGFVqFTfffA7Le3Ouq2bWdVB9UpahTwrOTWwBdPesZqXJ3o0nkAsWohV4lVXrCYFK%2FsG12rUHgjtU%2FGVT4TLnVprx%2B3KqBJ%2B%2BKCDelbL2sVScR5Dv0m%2FCaAG%2Bm3TNJXCg8bkWnjUVJ1QtGXR7yqfKEsSXtIUXHOxbQOTXKK0YJFQOTp6d9UBtJ8UdGkTyvMCd7B9T4CtZNWq6tEe%2FYqoZQGU1FYwkW%2B17iDHRXhd760oKS3PfnSx0JYKE3zTWGbEUsEK0wHzilMJTLujVWKSVrXUuiJLL0an2oZoYzn5AZYz9VZEm0P7bi8V9E9oQptwqNRrniTWl8WkN1BtR2bHi0jqPtSaanc8kMF9NZAVohJsw3TD082dGlg%2Bvrjp3%2Fz785%2F%2F%2FPUJTLdgOQuFysZ2YHS%2FXZbGj1it9k1l3TJNnCaJDtvFvBcUlYU%2FQjz7biX%2F705iVAP8YWG%2BnHwfwOynYG52evCFOdwnnvt0%2FF9We6qKi%2BlsHhxRsl%2BVMiL9Xz8ms6Q%3D)
88
90
  - [Bouncing ball](https://litecanvas.js.org?c=eJxtUj1vgzAQ3fkVNxpCAklbqRWlQ9WqZI%2FU2TImsuQCAkOLkvz3GvsKDs3gwff8Pu7OUijOaNnTlvieJ7mCumqFElUJKfSckW0ch%2Fr4Buu5rJhQQ2Jux4b206WhuehaTbp%2F9LyiK5nREKVQxIeTBxMXdT%2F3b4cs2IXZ%2B%2F4jO0Q7P9FvUBGfxAhq6OJodnVOFSe5srp%2FeTc%2FsEonF30LIFcuPlzhg8WdYFYAI8x8h%2BHAMz2K4LXS2ThURQE8P%2FJWV0UBZE62wum8gGkbzmcn9hrBZ4htR1eRghTW2%2BRGNd48PZiyM4AUmKRfteMc4mJC64xeviZelil1fzDlxMkv8wwmz3%2FrcWWWgg7GwN1a3tBv%2FAlMtiQ2%2B2aiYYWQ0g08a4YY%2FW7xAca%2FoRsbrFrDVdeUcBor2vIXzlHggw%3D%3D)
89
91
  - [Scroller](https://litecanvas.js.org?c=eJxVUMFOwzAMvfcrzAEtacNIxwZDsAPSJoG0AxJIO0w7hDZdI6XN1HhQgfbvOOs22CGJ7ff8nh1rUGeq%2FlSe8SgqtnWGxtVgaoPAOPxEAJX2Xq01TKC30DZzlQZ0YE%2BNFz0itQQvXqbvzxRvlKVsORQjcSvuxFjci1SKNF1Fu38W202uUAPLsbNB6pnNn17fZlPKvPnWR8nrwwR9q%2Bs1loSWBI3k3vZqAjdSQgw5nsnnjfo6bpBZzySnoHANMKsRDAnIB3oe4VycaknSdQEEJoa5MGGyn8aGn8p0UDcEHdv99sNjw4yA9I%2BVOesCiX5kWVjnGoYYjy4pPdjx1Z6LusWwMQsXP5VYpVrWChhInpg4YLHsjwWUyUAm3tRBbcjjUhzGEZ1hENjRZ%2FwCV%2F6J0w%3D%3D)
90
92
  - [3D Projection](https://litecanvas.js.org?c=eJyNVU2P2jAQvfMrpodqnWI%2By6kt7WW3hVulrtTuRjk4JCyG4CDHFJYV%2F73jj5CYDUslROx579njGc844yqdMfGXFSRoteZbMVM8F8AFVySAlxZAxkW644lakGGA04IfUhjD7%2Bnt%2FQS%2BwuRu%2BmNyD9%2FKQQ9G8MmhOEbBRubL1K46hhANAOGAQh9%2FEbVTHA%2F8qbaYaaRXyLlQRaXuaB8o1D8RhV4Pwj2FZwqHyPKaaHWkAehcQ2oEf7GLwGt7pxGIqliliT6sNjDxlOlw91vHWna2m4SplCTKZsiS2sjq9gctNMxzCSRLFXAt%2FYyfLy6I3SwVT2qBpnbbigFmuSgU4jrChjVcMyX5nnS7XasKeRQYql5T5opZD5G23mbEGNCtP8Q4ElC9luVf5D6cuI5yhf%2FYzHeul1Eb3lbK6tqdaU5sPJU%2BcSVG%2BOjFOZFs56pglhWkH5gUYUSIvaLff%2F6iMAp0yDfbYkE0riQTRabTUxbBkFbFYUqoKT2j85QIdIpwCoRDGwYBvIcRrZwNfBpSECU1bmBNlwQUeAPhaIptg%2BeoR6EUMQoxdfeoag3EXREWhX39KxnaMPAM8TkjPjE%2B%2Bju6FOoNXfRNntksz%2FQlZahxF7nCZL4z2DkQO1HcIIqdKC4BRPgciN3o3XhsGQGoBX4B%2ByDcSZlLcjPFjpnxBGylpMWNuQR2VZkWZfk2Zdp46mUbBfYuhrZxnVRLq1qiyhwDh5XKVmOxXZv2YC0n5coqV3o%2Fq1zVlWB0bR1KHoWrCD5gfFZRuIwc4ei%2B1jW043ooaZXYUR9XpmorheZ42av6gWQJx2qw%2Bzr2xRdglhcngWmnojatE33El%2FVdK23y5%2BEtf86W8Xe58E6d%2B%2Bg784Ynj%2F%2FvyaU4XA%2FCq4e07onX592r6TsT7rEuw2f9d4i0%2BB%2FEGGLo)
package/dist/dist.js CHANGED
@@ -1,5 +1,6 @@
1
1
  (() => {
2
2
  // src/zzfx.js
3
+ var zzfxX = /* @__PURE__ */ new AudioContext();
3
4
  var zzfx = (p = 1, k = 0.05, b = 220, e = 0, r = 0, t = 0.1, q = 0, D = 1, u = 0, y = 0, v = 0, z = 0, l = 0, E = 0, A = 0, F = 0, c = 0, w = 1, m = 0, B = 0, N = 0) => {
4
5
  let M = Math, d = 2 * M.PI, R = 44100, G = u *= 500 * d / R / R, C = b *= (1 - k + 2 * k * M.random(k = [])) * d / R, g = 0, H = 0, a = 0, n = 1, I = 0, J = 0, f = 0, h = N < 0 ? -1 : 1, x = d * h * N * 2 / R, L = M.cos(x), Z = M.sin, K = Z(x) / 4, O = 1 + K, X = -2 * L / O, Y = (1 - K) / O, P = (1 + h * L) / 2 / O, Q = -(h + L) / O, S = P, T = 0, U = 0, V = 0, W = 0;
5
6
  e = R * e + 9;
@@ -22,7 +23,6 @@
22
23
  b.connect(zzfxX.destination);
23
24
  b.start();
24
25
  };
25
- var zzfxX = /* @__PURE__ */ new AudioContext();
26
26
 
27
27
  // src/palette.js
28
28
  var colors = [
@@ -40,21 +40,9 @@
40
40
  "#a56243"
41
41
  ];
42
42
 
43
- // src/sounds.js
44
- var sounds = [
45
- // 0 - pickup
46
- [0.5, , 1675, , 0.06, 0.2, 1, 1.8, , , 637, 0.06],
47
- // 1 - hit
48
- [0.7, , 820, , , , , 1.5, , 0.3, , 0.1, 1.6, , , 0.1, 0.2],
49
- // 2 - jump
50
- [0.7, , 360, 0.01, , 0.08, 1, 1.7, 12, 32, , , , , , , , 0.63, 0.02, , 99],
51
- // 3 - powerup
52
- [, , 300, 0.02, 0.1, , 1, 3.2, , , 100, 0.08, 0.1, , , , , 0.6, 0.25, 0.3]
53
- ];
54
-
55
43
  // src/index.js
56
44
  function litecanvas(settings = {}) {
57
- const root = globalThis, PI = Math.PI, TWO_PI = PI * 2, on = (elem, evt, callback) => elem.addEventListener(evt, callback), defaults = {
45
+ const root = globalThis, PI = Math.PI, TWO_PI = PI * 2, DEFAULT_SFX_SOUND = [0.5, , 1675, , 0.06, 0.2, 1, 1.8, , , 637, 0.06], on = (elem, evt, callback) => elem.addEventListener(evt, callback), defaults = {
58
46
  fps: 60,
59
47
  fullscreen: true,
60
48
  width: null,
@@ -80,8 +68,7 @@
80
68
  tapped: false
81
69
  }, _helpers = {
82
70
  settings: Object.assign({}, settings),
83
- colors,
84
- sounds
71
+ colors
85
72
  };
86
73
  const instance = {
87
74
  /** @type {number} */
@@ -589,29 +576,37 @@
589
576
  },
590
577
  /** SOUND API */
591
578
  /**
592
- * Play a predefined sound or a ZzFX array of params.
593
- * By default has 4 predefined sounds.
579
+ * Play a sound made using ZzFX library.
580
+ * If the first argument is omitted, plays an default sound.
594
581
  *
595
- * @param {number|number[]} [sound=0] the sound index (from 0 to 3) or a ZzFX array of params
596
- * @param {number} [volume=1]
597
- * @param {number} [pitch=0]
598
- * @param {number} [randomness=null] an float value between 0 and 1
582
+ * @param {number|number[]} [sound] a ZzFX array of params
583
+ * @param {number} [volume] the volume factor
584
+ * @param {number} [pitch] a value to increment/decrement the pitch
585
+ * @param {number} [randomness] an float value between 0 and 1
599
586
  *
600
587
  * @see https://github.com/KilledByAPixel/ZzFX
601
- * @see https://github.com/litecanvas/game-engine/blob/main/src/sounds.js
602
588
  */
603
- sfx(sound = 0, volume = 1, pitch = 0, randomness = null) {
589
+ sfx(zzfxParams, volume, pitch, randomness) {
604
590
  if (navigator.userActivation && !navigator.userActivation.hasBeenActive) {
605
591
  return;
606
592
  }
607
- let sample = Array.isArray(sound) ? sound : sounds[sound % sounds.length];
608
- if (volume !== 1 || pitch || randomness) {
609
- sample = sample.slice();
610
- sample[0] = (Number(volume) || 1) * (sample[0] || 1);
611
- sample[1] = randomness != null ? randomness : sample[1];
612
- sample[10] = ~~sample[10] + ~~pitch;
593
+ zzfxParams = zzfxParams || DEFAULT_SFX_SOUND;
594
+ if (volume || pitch || randomness) {
595
+ zzfxParams = zzfxParams.slice();
596
+ zzfxParams[0] = (volume || 1) * (zzfxParams[0] || 1);
597
+ zzfxParams[1] = +randomness ? randomness : zzfxParams[1];
598
+ zzfxParams[10] = ~~zzfxParams[10] + ~~pitch;
613
599
  }
614
- zzfx.apply(0, sample);
600
+ zzfx.apply(0, zzfxParams);
601
+ },
602
+ /**
603
+ * Set the ZzFX's global volume.
604
+ * default: `0.3`
605
+ *
606
+ * @param {number} value
607
+ */
608
+ volume(value) {
609
+ root.zzfxV = +value || 1;
615
610
  },
616
611
  /** UTILS API */
617
612
  /**
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var e=(e=1,a=.05,l=220,n=0,i=0,r=.1,o=0,s=1,c=0,f=0,p=0,u=0,g=0,d=0,h=0,m=0,v=0,b=1,T=0,x=0,H=0)=>{let y=Math,E=2*y.PI,D=c*=500*E/44100/44100,w=l*=(1-a+2*a*y.random(a=[]))*E/44100,I=0,A=0,P=0,C=1,S=0,W=0,O=0,B=H<0?-1:1,X=E*B*H*2/44100,Y=y.cos(X),k=y.sin,G=k(X)/4,_=1+G,z=-2*Y/_,L=(1-G)/_,M=(1+B*Y)/2/_,N=-(B+Y)/_,R=0,j=0,F=0,$=0;for(n=44100*n+9,T*=44100,i*=44100,r*=44100,v*=44100,f*=500*E/85766121e6,h*=E/44100,p*=E/44100,u*=44100,g=44100*g|0,e*=globalThis.zzfxV||.3,B=n+T+i+r+v|0;P<B;a[P++]=O*e)++W%(100*m|0)||(O=o?1<o?2<o?3<o?k(I*I):y.max(y.min(y.tan(I),1),-1):1-(2*I/E%2+2)%2:1-4*y.abs(y.round(I/E)-I/E):k(I),O=(g?1-x+x*k(E*P/g):1)*(O<0?-1:1)*y.abs(O)**s*(P<n?P/n:P<n+T?1-(P-n)/T*(1-b):P<n+T+i?b:P<B-v?(B-P-v)/r*b:0),O=v?O/2+(v>P?0:(P<B-v?1:(B-P)/v)*a[P-v|0]/2/e):O,H&&(O=$=M*R+N*(R=j)+M*(j=O)-L*F-z*(F=$))),I+=(X=(l+=c+=f)*y.cos(h*A++))+X*d*k(P**5),C&&++C>u&&(l+=p,w+=p,C=0),!g||++S%g||(l=w,c=D,C=C||1);(e=t.createBuffer(1,B,44100)).getChannelData(0).set(a),(l=t.createBufferSource()).buffer=e,l.connect(t.destination),l.start()},t=/* @__PURE__ */new AudioContext,a=["#18161c","#6a7799","#aec2c2","#f3eade","#f04f78","#fcf660","#2f328f","#4b80ca","#327345","#63c64d","#703075","#a56243"],l=[[.5,,1675,,.06,.2,1,1.8,,,637,.06],[.7,,820,,,,,1.5,,.3,,.1,1.6,,,.1,.2],[.7,,360,.01,,.08,1,1.7,12,32,,,,,,,,.63,.02,,99],[,,300,.02,.1,,1,3.2,,,100,.08,.1,,,,,.6,.25,.3]];globalThis.litecanvas=function(t={}){let n=globalThis,i=Math.PI,r=2*i,o=(e,t,a)=>e.addEventListener(t,a);t=Object.assign({fps:60,fullscreen:!0,width:null,height:null,autoscale:!0,pixelart:!1,antialias:!0,canvas:null,global:!0,loop:null,tapEvents:!0,pauseOnBlur:!0},t);let s=!1,c=[],f=t.canvas||document.createElement("canvas"),p=t.fullscreen,u=t.autoscale,g=1,d,h,m,v=1,b,T=1/t.fps,x=1e3*T,H=0,y,E=0,D=0,w="sans-serif",I="",A=32,P=Date.now(),C={init:!1,update:!1,draw:!1,resized:!1,tap:!1,untap:!1,tapping:!1,tapped:!1},S={settings:Object.assign({},t),colors:a,sounds:l},W={WIDTH:t.width,HEIGHT:t.height||t.width,CANVAS:null,ELAPSED:0,FPS:t.fps,CENTERX:null,CENTERY:null,PI:i,TWO_PI:r,HALF_PI:.5*i,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>i/180*e,rad2deg:e=>180/i*e,clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*Math.floor((e-t)/(a-t)),map(e,t,a,l,n,i=!1){let r=(e-t)/(a-t)*(n-l)+l;return i?W.clamp(r,l,n):r},norm:(e,t,a)=>W.map(e,t,a,0,1),rand:(e=0,t=1)=>(P=(1664525*P+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>W.floor(W.rand()*(t-e+1)+e),seed:e=>null==e?P:P=~~e,cls(e){null==e?m.clearRect(0,0,W.WIDTH,W.HEIGHT):W.rectfill(0,0,W.WIDTH,W.HEIGHT,e)},rect(e,t,a,l,n=0,i=null){m.beginPath(),m[i?"roundRect":"rect"](~~e,~~t,a,l,i),W.stroke(n)},rectfill(e,t,a,l,n=0,i=null){m.beginPath(),m[i?"roundRect":"rect"](~~e,~~t,a,l,i),W.fill(n)},circ(e,t,a,l){m.beginPath(),m.arc(~~e,~~t,a,0,r),m.closePath(),W.stroke(l)},circfill(e,t,a,l){m.beginPath(),m.arc(~~e,~~t,a,0,r),m.closePath(),W.fill(l)},line(e,t,a,l,n){m.beginPath(),m.moveTo(~~e,~~t),m.lineTo(~~a,~~l),W.stroke(n)},linewidth(e){m.lineWidth=e},linedash(e,t=0){m.setLineDash(Array.isArray(e)?e:[e]),m.lineDashOffset=t},text(e,t,a,l=3){m.font=`${I||""} ${A}px ${w}`,m.fillStyle=W.getcolor(l),m.fillText(a,~~e,~~t)},textfont(e){w=e},textsize(e){A=e},textstyle(e){I=e},textalign(e,t){e&&(m.textAlign=e),t&&(m.textBaseline=t)},textmetrics(e,t){m.font=`${I||""} ${t||A}px ${w}`;let a=m.measureText(e);return a.height=a.actualBoundingBoxAscent+a.actualBoundingBoxDescent,a},image(e,t,a){m.drawImage(a,~~e,~~t)},paint(e,t,a,l={}){let n=new OffscreenCanvas(e,t),i=m,r=l.scale||1;if(n.width=e*r,n.height=t*r,(m=n.getContext("2d")).scale(r,r),Array.isArray(a)){let e=0,t=0;for(let l of(m.imageSmoothingEnabled=!1,a)){for(let a of l)" "!==a&&"."!==a&&W.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(n,m);return m=i,n},ctx:e=>(e&&(m=e),m),push:()=>m.save(),pop:()=>m.restore(),translate:(e,t)=>m.translate(~~e,~~t),scale:(e,t)=>m.scale(e,t||e),rotate:e=>m.rotate(e),transform:(e,t,a,l,n,i,r=!0)=>m[r?"setTransform":"transform"](e,t,a,l,n,i),alpha(e){m.globalAlpha=W.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){m.fillStyle=W.getcolor(e),m.fill(t)},stroke(e,t){m.strokeStyle=W.getcolor(e),t?m.stroke(t):m.stroke()},cliprect(e,t,a,l){m.beginPath(),m.rect(e,t,a,l),m.clip()},clipcirc(e,t,a){m.beginPath(),m.arc(e,t,a,0,r),m.clip()},blendmode(e){m.globalCompositeOperation=e},sfx(t=0,a=1,n=0,i=null){if(navigator.userActivation&&!navigator.userActivation.hasBeenActive)return;let r=Array.isArray(t)?t:l[t%l.length];(1!==a||n||i)&&((r=r.slice())[0]=(Number(a)||1)*(r[0]||1),r[1]=null!=i?i:r[1],r[10]=~~r[10]+~~n),e.apply(0,r)},colrect:(e,t,a,l,n,i,r,o)=>e<n+r&&e+a>n&&t<i+o&&t+l>i,colcirc:(e,t,a,l,n,i)=>(l-e)**2+(n-t)**2<=(a+i)**2,mousepos:()=>[d,h],timescale(e){v=e},use(e,t={}){e.__conf=t,s?k(e):c.push(e)},listen:(e,t)=>(C[e]=C[e]||[],C[e].push(t),()=>{C[e]=C[e].filter(e=>t!==e)}),emit(e,t,a,l,n){Y("before:"+e,t,a,l,n),Y(e,t,a,l,n),Y("after:"+e,t,a,l,n)},getcolor:e=>a[~~e%a.length],setvar(e,a){W[e]=a,t.global&&(n[e]=a)},resize(e,t){W.setvar("WIDTH",f.width=e),W.setvar("HEIGHT",f.height=t||e),X()}};for(let e of["sin","cos","atan2","hypot","tan","abs","ceil","round","floor","trunc","min","max","pow","sqrt","sign","exp"])W[e]=Math[e];function O(){s=!0,f="string"==typeof f?document.querySelector(f):f,W.setvar("CANVAS",f),m=f.getContext("2d"),W.WIDTH>0&&(p=!1),f.width=W.WIDTH,f.height=W.HEIGHT||W.WIDTH,f.parentNode||document.body.appendChild(f),f.style.display="block",p?(f.style.position="absolute",f.style.inset=0):u&&(f.style.margin="auto");let e=t.loop?t.loop:n;for(let t of Object.keys(C))e[t]&&W.listen(t,e[t]);for(let e of c)k(e);if(o(n,"resize",X),X(),t.tapEvents){let e=(e,t)=>[(e-f.offsetLeft)/g,(t-f.offsetTop)/g],t=/* @__PURE__ */new Map,a=(e,a,l)=>{let n={x:a,y:l,startX:a,startY:l,ts:performance.now()};return t.set(e,n),n},l=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},i=e=>e&&performance.now()-e.ts<=200,r=!1;o(f,"mousedown",t=>{t.preventDefault();let[l,n]=e(t.pageX,t.pageY);W.emit("tap",l,n,0),a(0,l,n),r=!0}),o(f,"mousemove",t=>{t.preventDefault();let[a,n]=[d,h]=e(t.pageX,t.pageY);r&&(W.emit("tapping",a,n,0),l(0,a,n))}),o(f,"mouseup",a=>{a.preventDefault();let l=t.get(0),[n,o]=e(a.pageX,a.pageY);i(l)&&W.emit("tapped",l.startX,l.startY,0),W.emit("untap",n,o,0),t.delete(0),r=!1}),o(f,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l.pageX,l.pageY);W.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),o(f,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,n]=e(a.pageX,a.pageY);W.emit("tapping",t,n,a.identifier+1),l(a.identifier+1,t,n)}});let s=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&W.emit("tapped",l.startX,l.startY,e),W.emit("untap",l.x,l.y,e),t.delete(e))};o(f,"touchend",s),o(f,"touchcancel",s),o(n,"blur",()=>{if(r=!1,0!==t.size)for(let[e,a]of t)W.emit("untap",a.x,a.y,e),t.delete(e)})}t.pauseOnBlur&&(o(n,"blur",()=>{y=null}),o(n,"focus",()=>{y||(b=performance.now(),y=requestAnimationFrame(B))})),W.emit("init"),b=performance.now(),y=requestAnimationFrame(B)}function B(e){let t=0,a=e-b;for(b=e,H+=a;H>=x;)W.emit("update",T*v),W.setvar("ELAPSED",W.ELAPSED+T*v),H-=x,t++;t&&(W.textalign("start","top"),W.emit("draw"),E++,(D+=x*t)+H>=1e3&&(W.setvar("FPS",E),E=0,D-=1e3)),y&&(y=requestAnimationFrame(B))}function X(){let e=n.innerWidth,a=n.innerHeight;p?(W.setvar("WIDTH",f.width=e),W.setvar("HEIGHT",f.height=a)):u&&(g=Math.min(e/W.WIDTH,a/W.HEIGHT),g=t.pixelart?Math.floor(g):g,f.style.width=W.WIDTH*g+"px",f.style.height=W.HEIGHT*g+"px"),W.setvar("CENTERX",W.WIDTH/2),W.setvar("CENTERY",W.HEIGHT/2),(!t.antialias||t.pixelart)&&(m.imageSmoothingEnabled=!1,f.style.imageRendering="pixelated"),W.emit("resized",g)}function Y(e,t,a,l,n){if(C[e])for(let i of C[e])i(t,a,l,n)}function k(e){let t=e(W,S,e.__conf);if("object"==typeof t)for(let[e,a]of Object.entries(t))W.setvar(e,a)}if(t.global){if(n.__litecanvas)throw"Cannot instantiate litecanvas globally twice";Object.assign(n,W),n.__litecanvas=W}return"loading"===document.readyState?o(n,"DOMContentLoaded",O):O(),W}})();
1
+ (()=>{var e=/* @__PURE__ */new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,r=.1,o=0,s=1,c=0,f=0,p=0,u=0,g=0,d=0,h=0,m=0,v=0,x=1,T=0,b=0,H=0)=>{let E=Math,y=2*E.PI,D=c*=500*y/44100/44100,w=l*=(1-a+2*a*E.random(a=[]))*y/44100,I=0,A=0,P=0,C=1,S=0,W=0,O=0,z=H<0?-1:1,B=y*z*H*2/44100,X=E.cos(B),Y=E.sin,k=Y(B)/4,G=1+k,_=-2*X/G,L=(1-k)/G,M=(1+z*X)/2/G,R=-(z+X)/G,N=0,j=0,F=0,$=0;for(n=44100*n+9,T*=44100,i*=44100,r*=44100,v*=44100,f*=500*y/85766121e6,h*=y/44100,p*=y/44100,u*=44100,g=44100*g|0,t*=globalThis.zzfxV||.3,z=n+T+i+r+v|0;P<z;a[P++]=O*t)++W%(100*m|0)||(O=o?1<o?2<o?3<o?Y(I*I):E.max(E.min(E.tan(I),1),-1):1-(2*I/y%2+2)%2:1-4*E.abs(E.round(I/y)-I/y):Y(I),O=(g?1-b+b*Y(y*P/g):1)*(O<0?-1:1)*E.abs(O)**s*(P<n?P/n:P<n+T?1-(P-n)/T*(1-x):P<n+T+i?x:P<z-v?(z-P-v)/r*x:0),O=v?O/2+(v>P?0:(P<z-v?1:(z-P)/v)*a[P-v|0]/2/t):O,H&&(O=$=M*N+R*(N=j)+M*(j=O)-L*F-_*(F=$))),I+=(B=(l+=c+=f)*E.cos(h*A++))+B*d*Y(P**5),C&&++C>u&&(l+=p,w+=p,C=0),!g||++S%g||(l=w,c=D,C=C||1);(t=e.createBuffer(1,z,44100)).getChannelData(0).set(a),(l=e.createBufferSource()).buffer=t,l.connect(e.destination),l.start()},a=["#18161c","#6a7799","#aec2c2","#f3eade","#f04f78","#fcf660","#2f328f","#4b80ca","#327345","#63c64d","#703075","#a56243"];globalThis.litecanvas=function(e={}){let l=globalThis,n=Math.PI,i=2*n,r=[.5,,1675,,.06,.2,1,1.8,,,637,.06],o=(e,t,a)=>e.addEventListener(t,a);e=Object.assign({fps:60,fullscreen:!0,width:null,height:null,autoscale:!0,pixelart:!1,antialias:!0,canvas:null,global:!0,loop:null,tapEvents:!0,pauseOnBlur:!0},e);let s=!1,c=[],f=e.canvas||document.createElement("canvas"),p=e.fullscreen,u=e.autoscale,g=1,d,h,m,v=1,x,T=1/e.fps,b=1e3*T,H=0,E,y=0,D=0,w="sans-serif",I="",A=32,P=Date.now(),C={init:!1,update:!1,draw:!1,resized:!1,tap:!1,untap:!1,tapping:!1,tapped:!1},S={settings:Object.assign({},e),colors:a},W={WIDTH:e.width,HEIGHT:e.height||e.width,CANVAS:null,ELAPSED:0,FPS:e.fps,CENTERX:null,CENTERY:null,PI:n,TWO_PI:i,HALF_PI:.5*n,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>n/180*e,rad2deg:e=>180/n*e,clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*Math.floor((e-t)/(a-t)),map(e,t,a,l,n,i=!1){let r=(e-t)/(a-t)*(n-l)+l;return i?W.clamp(r,l,n):r},norm:(e,t,a)=>W.map(e,t,a,0,1),rand:(e=0,t=1)=>(P=(1664525*P+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>W.floor(W.rand()*(t-e+1)+e),seed:e=>null==e?P:P=~~e,cls(e){null==e?m.clearRect(0,0,W.WIDTH,W.HEIGHT):W.rectfill(0,0,W.WIDTH,W.HEIGHT,e)},rect(e,t,a,l,n=0,i=null){m.beginPath(),m[i?"roundRect":"rect"](~~e,~~t,a,l,i),W.stroke(n)},rectfill(e,t,a,l,n=0,i=null){m.beginPath(),m[i?"roundRect":"rect"](~~e,~~t,a,l,i),W.fill(n)},circ(e,t,a,l){m.beginPath(),m.arc(~~e,~~t,a,0,i),m.closePath(),W.stroke(l)},circfill(e,t,a,l){m.beginPath(),m.arc(~~e,~~t,a,0,i),m.closePath(),W.fill(l)},line(e,t,a,l,n){m.beginPath(),m.moveTo(~~e,~~t),m.lineTo(~~a,~~l),W.stroke(n)},linewidth(e){m.lineWidth=e},linedash(e,t=0){m.setLineDash(Array.isArray(e)?e:[e]),m.lineDashOffset=t},text(e,t,a,l=3){m.font=`${I||""} ${A}px ${w}`,m.fillStyle=W.getcolor(l),m.fillText(a,~~e,~~t)},textfont(e){w=e},textsize(e){A=e},textstyle(e){I=e},textalign(e,t){e&&(m.textAlign=e),t&&(m.textBaseline=t)},textmetrics(e,t){m.font=`${I||""} ${t||A}px ${w}`;let a=m.measureText(e);return a.height=a.actualBoundingBoxAscent+a.actualBoundingBoxDescent,a},image(e,t,a){m.drawImage(a,~~e,~~t)},paint(e,t,a,l={}){let n=new OffscreenCanvas(e,t),i=m,r=l.scale||1;if(n.width=e*r,n.height=t*r,(m=n.getContext("2d")).scale(r,r),Array.isArray(a)){let e=0,t=0;for(let l of(m.imageSmoothingEnabled=!1,a)){for(let a of l)" "!==a&&"."!==a&&W.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(n,m);return m=i,n},ctx:e=>(e&&(m=e),m),push:()=>m.save(),pop:()=>m.restore(),translate:(e,t)=>m.translate(~~e,~~t),scale:(e,t)=>m.scale(e,t||e),rotate:e=>m.rotate(e),transform:(e,t,a,l,n,i,r=!0)=>m[r?"setTransform":"transform"](e,t,a,l,n,i),alpha(e){m.globalAlpha=W.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){m.fillStyle=W.getcolor(e),m.fill(t)},stroke(e,t){m.strokeStyle=W.getcolor(e),t?m.stroke(t):m.stroke()},cliprect(e,t,a,l){m.beginPath(),m.rect(e,t,a,l),m.clip()},clipcirc(e,t,a){m.beginPath(),m.arc(e,t,a,0,i),m.clip()},blendmode(e){m.globalCompositeOperation=e},sfx(e,a,l,n){(!navigator.userActivation||navigator.userActivation.hasBeenActive)&&(e=e||r,(a||l||n)&&((e=e.slice())[0]=(a||1)*(e[0]||1),e[1]=+n?n:e[1],e[10]=~~e[10]+~~l),t.apply(0,e))},volume(e){l.zzfxV=+e||1},colrect:(e,t,a,l,n,i,r,o)=>e<n+r&&e+a>n&&t<i+o&&t+l>i,colcirc:(e,t,a,l,n,i)=>(l-e)**2+(n-t)**2<=(a+i)**2,mousepos:()=>[d,h],timescale(e){v=e},use(e,t={}){e.__conf=t,s?Y(e):c.push(e)},listen:(e,t)=>(C[e]=C[e]||[],C[e].push(t),()=>{C[e]=C[e].filter(e=>t!==e)}),emit(e,t,a,l,n){X("before:"+e,t,a,l,n),X(e,t,a,l,n),X("after:"+e,t,a,l,n)},getcolor:e=>a[~~e%a.length],setvar(t,a){W[t]=a,e.global&&(l[t]=a)},resize(e,t){W.setvar("WIDTH",f.width=e),W.setvar("HEIGHT",f.height=t||e),B()}};for(let e of["sin","cos","atan2","hypot","tan","abs","ceil","round","floor","trunc","min","max","pow","sqrt","sign","exp"])W[e]=Math[e];function O(){s=!0,f="string"==typeof f?document.querySelector(f):f,W.setvar("CANVAS",f),m=f.getContext("2d"),W.WIDTH>0&&(p=!1),f.width=W.WIDTH,f.height=W.HEIGHT||W.WIDTH,f.parentNode||document.body.appendChild(f),f.style.display="block",p?(f.style.position="absolute",f.style.inset=0):u&&(f.style.margin="auto");let t=e.loop?e.loop:l;for(let e of Object.keys(C))t[e]&&W.listen(e,t[e]);for(let e of c)Y(e);if(o(l,"resize",B),B(),e.tapEvents){let e=(e,t)=>[(e-f.offsetLeft)/g,(t-f.offsetTop)/g],t=/* @__PURE__ */new Map,a=(e,a,l)=>{let n={x:a,y:l,startX:a,startY:l,ts:performance.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},i=e=>e&&performance.now()-e.ts<=200,r=!1;o(f,"mousedown",t=>{t.preventDefault();let[l,n]=e(t.pageX,t.pageY);W.emit("tap",l,n,0),a(0,l,n),r=!0}),o(f,"mousemove",t=>{t.preventDefault();let[a,l]=[d,h]=e(t.pageX,t.pageY);r&&(W.emit("tapping",a,l,0),n(0,a,l))}),o(f,"mouseup",a=>{a.preventDefault();let l=t.get(0),[n,o]=e(a.pageX,a.pageY);i(l)&&W.emit("tapped",l.startX,l.startY,0),W.emit("untap",n,o,0),t.delete(0),r=!1}),o(f,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l.pageX,l.pageY);W.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),o(f,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,l]=e(a.pageX,a.pageY);W.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&W.emit("tapped",l.startX,l.startY,e),W.emit("untap",l.x,l.y,e),t.delete(e))};o(f,"touchend",s),o(f,"touchcancel",s),o(l,"blur",()=>{if(r=!1,0!==t.size)for(let[e,a]of t)W.emit("untap",a.x,a.y,e),t.delete(e)})}e.pauseOnBlur&&(o(l,"blur",()=>{E=null}),o(l,"focus",()=>{E||(x=performance.now(),E=requestAnimationFrame(z))})),W.emit("init"),x=performance.now(),E=requestAnimationFrame(z)}function z(e){let t=0,a=e-x;for(x=e,H+=a;H>=b;)W.emit("update",T*v),W.setvar("ELAPSED",W.ELAPSED+T*v),H-=b,t++;t&&(W.textalign("start","top"),W.emit("draw"),y++,(D+=b*t)+H>=1e3&&(W.setvar("FPS",y),y=0,D-=1e3)),E&&(E=requestAnimationFrame(z))}function B(){let t=l.innerWidth,a=l.innerHeight;p?(W.setvar("WIDTH",f.width=t),W.setvar("HEIGHT",f.height=a)):u&&(g=Math.min(t/W.WIDTH,a/W.HEIGHT),g=e.pixelart?Math.floor(g):g,f.style.width=W.WIDTH*g+"px",f.style.height=W.HEIGHT*g+"px"),W.setvar("CENTERX",W.WIDTH/2),W.setvar("CENTERY",W.HEIGHT/2),(!e.antialias||e.pixelart)&&(m.imageSmoothingEnabled=!1,f.style.imageRendering="pixelated"),W.emit("resized",g)}function X(e,t,a,l,n){if(C[e])for(let i of C[e])i(t,a,l,n)}function Y(e){let t=e(W,S,e.__conf);if("object"==typeof t)for(let[e,a]of Object.entries(t))W.setvar(e,a)}if(e.global){if(l.__litecanvas)throw"Cannot instantiate litecanvas globally twice";Object.assign(l,W),l.__litecanvas=W}return"loading"===document.readyState?o(l,"DOMContentLoaded",O):O(),W}})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.53.0",
3
+ "version": "0.54.0",
4
4
  "description": "Lightweight HTML5 canvas engine suitable for small games and animations.",
5
5
  "license": "MIT",
6
6
  "author": "Luiz Bills <luizbills@pm.me>",
package/src/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { zzfx } from './zzfx.js'
2
2
  import { colors } from './palette.js'
3
- import { sounds } from './sounds.js'
4
3
  import './types.js'
5
4
 
6
5
  /**
@@ -13,6 +12,7 @@ export default function litecanvas(settings = {}) {
13
12
  const root = globalThis,
14
13
  PI = Math.PI,
15
14
  TWO_PI = PI * 2,
15
+ DEFAULT_SFX_SOUND = [0.5, , 1675, , 0.06, 0.2, 1, 1.8, , , 637, 0.06],
16
16
  /** @type {(elem:HTMLElement, evt:string, callback:(event:Event)=>void)=>void} */
17
17
  on = (elem, evt, callback) => elem.addEventListener(evt, callback),
18
18
  /** @type {LitecanvasOptions} */
@@ -97,7 +97,6 @@ export default function litecanvas(settings = {}) {
97
97
  _helpers = {
98
98
  settings: Object.assign({}, settings),
99
99
  colors,
100
- sounds,
101
100
  }
102
101
 
103
102
  /** @type {LitecanvasInstance} */
@@ -672,18 +671,17 @@ export default function litecanvas(settings = {}) {
672
671
 
673
672
  /** SOUND API */
674
673
  /**
675
- * Play a predefined sound or a ZzFX array of params.
676
- * By default has 4 predefined sounds.
674
+ * Play a sound made using ZzFX library.
675
+ * If the first argument is omitted, plays an default sound.
677
676
  *
678
- * @param {number|number[]} [sound=0] the sound index (from 0 to 3) or a ZzFX array of params
679
- * @param {number} [volume=1]
680
- * @param {number} [pitch=0]
681
- * @param {number} [randomness=null] an float value between 0 and 1
677
+ * @param {number|number[]} [sound] a ZzFX array of params
678
+ * @param {number} [volume] the volume factor
679
+ * @param {number} [pitch] a value to increment/decrement the pitch
680
+ * @param {number} [randomness] an float value between 0 and 1
682
681
  *
683
682
  * @see https://github.com/KilledByAPixel/ZzFX
684
- * @see https://github.com/litecanvas/game-engine/blob/main/src/sounds.js
685
683
  */
686
- sfx(sound = 0, volume = 1, pitch = 0, randomness = null) {
684
+ sfx(zzfxParams, volume, pitch, randomness) {
687
685
  if (
688
686
  navigator.userActivation &&
689
687
  !navigator.userActivation.hasBeenActive
@@ -691,17 +689,28 @@ export default function litecanvas(settings = {}) {
691
689
  return
692
690
  }
693
691
 
694
- let sample = Array.isArray(sound)
695
- ? sound
696
- : sounds[sound % sounds.length]
697
- if (volume !== 1 || pitch || randomness) {
698
- sample = sample.slice()
699
- sample[0] = (Number(volume) || 1) * (sample[0] || 1)
700
- sample[1] = randomness != null ? randomness : sample[1]
701
- sample[10] = ~~sample[10] + ~~pitch
692
+ // prettier-ignore
693
+ zzfxParams = zzfxParams || DEFAULT_SFX_SOUND
694
+
695
+ // if has other arguments, copy the sound to not change the original
696
+ if (volume || pitch || randomness) {
697
+ zzfxParams = zzfxParams.slice()
698
+ zzfxParams[0] = (volume || 1) * (zzfxParams[0] || 1)
699
+ zzfxParams[1] = +randomness ? randomness : zzfxParams[1]
700
+ zzfxParams[10] = ~~zzfxParams[10] + ~~pitch
702
701
  }
703
702
 
704
- zzfx.apply(0, sample)
703
+ zzfx.apply(0, zzfxParams)
704
+ },
705
+
706
+ /**
707
+ * Set the ZzFX's global volume.
708
+ * default: `0.3`
709
+ *
710
+ * @param {number} value
711
+ */
712
+ volume(value) {
713
+ root.zzfxV = +value || 1
705
714
  },
706
715
 
707
716
  /** UTILS API */
package/src/types.js CHANGED
@@ -44,7 +44,6 @@
44
44
  * @typedef LitecanvasPluginHelpers
45
45
  * @type {object}
46
46
  * @property {string[]} colors The instance color palette
47
- * @property {number[][]} sounds The instance ZzFX sounds
48
47
  * @property {LitecanvasOptions} settings An copy of this instance settings
49
48
  */
50
49
 
package/src/zzfx.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // ZzFXMicro - Zuper Zmall Zound Zynth - v1.3.0 by Frank Force | https://github.com/KilledByAPixel/ZzFX
2
+ const zzfxX = /** @__PURE__ */ new AudioContext()
2
3
  export const zzfx = (
3
4
  p = 1,
4
5
  k = 0.05,
@@ -107,5 +108,3 @@ export const zzfx = (
107
108
  b.connect(zzfxX.destination)
108
109
  b.start()
109
110
  }
110
-
111
- const zzfxX = /** @__PURE__ */ new AudioContext()
package/types/index.d.ts CHANGED
@@ -346,6 +346,7 @@ declare global {
346
346
  * @see https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics
347
347
  */
348
348
  function textmetrics(text: string, size?: number): TextMetrics
349
+
349
350
  /** IMAGE GRAPHICS API */
350
351
  /**
351
352
  * Draw an image
@@ -377,6 +378,7 @@ declare global {
377
378
  scale?: number
378
379
  }
379
380
  ): OffscreenCanvas
381
+
380
382
  /** ADVANCED GRAPHICS API */
381
383
  /**
382
384
  * Get or set the canvas context 2D
@@ -500,25 +502,33 @@ declare global {
500
502
  * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
501
503
  */
502
504
  function blendmode(value: string): void
505
+
503
506
  /** SOUND API */
504
507
  /**
505
- * Play a predefined sound or a ZzFX array of params.
506
- * By default has 4 predefined sounds.
508
+ * Play a sound made using ZzFX library.
509
+ * If the first argument is omitted, plays an default sound.
510
+ *
511
+ * @param {number|number[]} [sound] a ZzFX array of params
512
+ * @param {number} [volume] the volume factor
513
+ * @param {number} [pitch] a value to increment/decrement the pitch
514
+ * @param {number} [randomness] an float between 0 and 1
507
515
  *
508
- * @param {number|number[]} [sound=0] the sound index (from 0 to 3) or a ZzFX array of params
509
- * @param {number} [volume=1] the volume factor
510
- * @param {number} [pitch=0] a value to increment/decrement the pitch
511
- * @param {number} [randomness=null] an float between 0 and 1
512
- * @returns {AudioBufferSourceNode}
513
516
  * @see https://github.com/KilledByAPixel/ZzFX
514
- * @see https://github.com/litecanvas/game-engine/blob/main/src/sounds.js
515
517
  */
516
518
  function sfx(
517
- sound?: number | number[],
519
+ sound?: number[],
518
520
  volume?: number,
519
521
  pitch?: number,
520
522
  randomness?: number
521
- ): AudioBufferSourceNode
523
+ ): void
524
+ /**
525
+ * Set the ZzFX's global volume.
526
+ * default: `0.3`
527
+ *
528
+ * @param {number} value
529
+ */
530
+ function volume(value: number): void
531
+
522
532
  /** UTILS API */
523
533
  /**
524
534
  * Check a collision between two rectangles
package/types/types.d.ts CHANGED
@@ -488,23 +488,29 @@ type LitecanvasInstance = {
488
488
 
489
489
  /** SOUND API */
490
490
  /**
491
- * Play a predefined sound or a ZzFX array of params.
492
- * By default has 4 predefined sounds.
493
- *
494
- * @param {number|number[]} [sound=0] the sound index (from 0 to 3) or a ZzFX array of params
495
- * @param {number} [volume=1] the volume factor
496
- * @param {number} [pitch=0] a value to increment/decrement the pitch
497
- * @param {number} [randomness=null] an float between 0 and 1
498
- * @returns {AudioBufferSourceNode}
491
+ * Play a sound made using ZzFX library.
492
+ * If the first argument is omitted, plays an default sound.
493
+ *
494
+ * @param {number|number[]} [sound] a ZzFX array of params
495
+ * @param {number} [volume] the volume factor
496
+ * @param {number} [pitch] a value to increment/decrement the pitch
497
+ * @param {number} [randomness] an float between 0 and 1
498
+ *
499
499
  * @see https://github.com/KilledByAPixel/ZzFX
500
- * @see https://github.com/litecanvas/game-engine/blob/main/src/sounds.js
501
500
  */
502
501
  sfx(
503
- sound?: number | number[],
502
+ sound?: number[],
504
503
  volume?: number,
505
504
  pitch?: number,
506
505
  randomness?: number
507
- ): AudioBufferSourceNode
506
+ ): void
507
+ /**
508
+ * Set the ZzFX's global volume.
509
+ * default: `0.3`
510
+ *
511
+ * @param {number} value
512
+ */
513
+ volume(value: number): void
508
514
 
509
515
  /** UTILS API */
510
516
  /**
@@ -694,10 +700,6 @@ type LitecanvasPluginHelpers = {
694
700
  * The instance color palette (writable)
695
701
  */
696
702
  colors: string[]
697
- /**
698
- * The instance ZzFX sounds (writable)
699
- */
700
- sounds: number[][]
701
703
  /**
702
704
  * An instance settings/options (read-only)
703
705
  */
package/src/sounds.js DELETED
@@ -1,11 +0,0 @@
1
- // prettier-ignore
2
- export const sounds = [
3
- // 0 - pickup
4
- [0.5, , 1675, , 0.06, 0.2, 1, 1.8, , , 637, 0.06],
5
- // 1 - hit
6
- [0.7, , 820, , , , , 1.5, , 0.3, , 0.1, 1.6, , , 0.1, 0.2],
7
- // 2 - jump
8
- [0.7, , 360, 0.01, , 0.08, 1, 1.7, 12, 32, , , , , , , , 0.63, 0.02, , 99],
9
- // 3 - powerup
10
- [, , 300, 0.02, 0.1, , 1, 3.2, , , 100, 0.08, 0.1, , , , , 0.6, 0.25, 0.3],
11
- ]