litecanvas 0.78.1 → 0.79.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/dist/dist.dev.js CHANGED
@@ -50,7 +50,7 @@
50
50
  animate: true
51
51
  };
52
52
  settings = Object.assign(defaults, settings);
53
- let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 18, _rng_seed = Date.now(), _global = settings.global, _events = {
53
+ let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _global = settings.global, _events = {
54
54
  init: null,
55
55
  update: null,
56
56
  draw: null,
@@ -907,27 +907,6 @@
907
907
  root[key] = value;
908
908
  }
909
909
  },
910
- /**
911
- * Resizes the game canvas and emit the "resized" event
912
- *
913
- * @param {number} width
914
- * @param {number} height
915
- */
916
- resize(width, height) {
917
- DEV: assert(
918
- isFinite(width) && width > 0,
919
- "resize: 1st param must be a number"
920
- );
921
- DEV: assert(
922
- isFinite(height) && height > 0,
923
- "resize: 2nd param must be a number"
924
- );
925
- instance.setvar("WIDTH", _canvas.width = width);
926
- instance.setvar("HEIGHT", _canvas.height = height);
927
- instance.setvar("CENTERX", instance.WIDTH / 2);
928
- instance.setvar("CENTERY", instance.HEIGHT / 2);
929
- onResize();
930
- },
931
910
  /**
932
911
  * The scale of the game's delta time (dt).
933
912
  * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.
@@ -985,7 +964,7 @@
985
964
  loadPlugin(callback, config);
986
965
  }
987
966
  if (settings.autoscale) {
988
- on(root, "resize", onResize);
967
+ on(root, "resize", resizeCanvas);
989
968
  }
990
969
  if (settings.tapEvents) {
991
970
  const _getXY = (pageX, pageY) => [
@@ -1154,28 +1133,27 @@
1154
1133
  _rafid = raf(drawFrame);
1155
1134
  }
1156
1135
  function drawFrame(now) {
1157
- if (_animated) {
1158
- _rafid = raf(drawFrame);
1159
- }
1160
1136
  let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
1161
1137
  _lastFrameTime = now;
1162
- if (frameTime > _deltaTime * 30) {
1163
- console.warn("skipping too long frame");
1164
- } else {
1165
- _accumulated += frameTime;
1166
- if (!_animated) {
1167
- _accumulated = _deltaTime;
1138
+ if (_animated) {
1139
+ _rafid = raf(drawFrame);
1140
+ if (frameTime > 0.3) {
1141
+ return console.warn("skipping too long frame");
1168
1142
  }
1169
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
1143
+ _accumulated += frameTime;
1144
+ while (_accumulated >= _deltaTime) {
1170
1145
  instance.emit("update", _deltaTime * _timeScale);
1171
1146
  instance.setvar(
1172
1147
  "ELAPSED",
1173
1148
  instance.ELAPSED + _deltaTime * _timeScale
1174
1149
  );
1175
1150
  updated++;
1151
+ _accumulated -= _deltaTime;
1176
1152
  }
1153
+ } else {
1154
+ updated = 1;
1177
1155
  }
1178
- if (updated || !_animated) {
1156
+ if (updated) {
1179
1157
  instance.textalign("start", "top");
1180
1158
  instance.emit("draw");
1181
1159
  }
@@ -1186,47 +1164,47 @@
1186
1164
  _canvas && _canvas.tagName === "CANVAS",
1187
1165
  "Invalid canvas element"
1188
1166
  );
1189
- DEV: assert(
1190
- null == instance.WIDTH || instance.WIDTH > 0,
1191
- `Litecanvas' "width" option should be null or a positive number`
1192
- );
1193
- DEV: assert(
1194
- null == instance.HEIGHT || instance.HEIGHT > 0,
1195
- `Litecanvas' "width" option should be null or a positive number`
1196
- );
1197
- DEV: assert(
1198
- null == instance.HEIGHT || instance.WIDTH > 0 && instance.HEIGHT > 0,
1199
- `Litecanvas' "width" is required when "heigth" is passed`
1200
- );
1201
1167
  instance.setvar("CANVAS", _canvas);
1202
1168
  _ctx = _canvas.getContext("2d");
1203
1169
  on(_canvas, "click", () => root.focus());
1204
1170
  _canvas.style = "";
1205
- if (!instance.WIDTH) {
1206
- instance.WIDTH = root.innerWidth;
1207
- instance.HEIGHT = root.innerHeight;
1208
- }
1209
- instance.resize(instance.WIDTH, instance.HEIGHT, false);
1171
+ resizeCanvas();
1210
1172
  if (!_canvas.parentNode) document.body.appendChild(_canvas);
1211
1173
  }
1212
- function onResize() {
1213
- const styles = _canvas.style;
1174
+ function resizeCanvas() {
1175
+ DEV: assert(
1176
+ null == settings.width || isFinite(settings.width) && settings.width > 0,
1177
+ `Litecanvas' option "width" should be a positive number when defined`
1178
+ );
1179
+ DEV: assert(
1180
+ null == settings.height || isFinite(settings.height) && settings.height > 0,
1181
+ `Litecanvas' option "height" should be a positive number when defined`
1182
+ );
1183
+ DEV: assert(
1184
+ null == settings.height || settings.width > 0 && settings.height > 0,
1185
+ `Litecanvas' option "width" is required when the option "height" is defined`
1186
+ );
1187
+ const width = settings.width || root.innerWidth, height = settings.height || settings.width || root.innerHeight;
1188
+ instance.setvar("WIDTH", _canvas.width = width);
1189
+ instance.setvar("HEIGHT", _canvas.height = height);
1190
+ instance.setvar("CENTERX", instance.WIDTH / 2);
1191
+ instance.setvar("CENTERY", instance.HEIGHT / 2);
1214
1192
  if (settings.autoscale) {
1215
- if (!styles.display) {
1216
- styles.display = "block";
1217
- styles.margin = "auto";
1193
+ if (!_canvas.style.display) {
1194
+ _canvas.style.display = "block";
1195
+ _canvas.style.margin = "auto";
1218
1196
  }
1219
1197
  _scale = math.min(
1220
1198
  root.innerWidth / instance.WIDTH,
1221
1199
  root.innerHeight / instance.HEIGHT
1222
1200
  );
1223
1201
  _scale = (settings.pixelart ? ~~_scale : _scale) || 1;
1224
- styles.width = instance.WIDTH * _scale + "px";
1225
- styles.height = instance.HEIGHT * _scale + "px";
1202
+ _canvas.style.width = instance.WIDTH * _scale + "px";
1203
+ _canvas.style.height = instance.HEIGHT * _scale + "px";
1226
1204
  }
1227
1205
  if (!settings.antialias || settings.pixelart) {
1228
1206
  _ctx.imageSmoothingEnabled = false;
1229
- styles.imageRendering = "pixelated";
1207
+ _canvas.style.imageRendering = "pixelated";
1230
1208
  }
1231
1209
  instance.emit("resized", _scale);
1232
1210
  if (!_animated) {
package/dist/dist.js CHANGED
@@ -45,7 +45,7 @@
45
45
  animate: true
46
46
  };
47
47
  settings = Object.assign(defaults, settings);
48
- let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 18, _rng_seed = Date.now(), _global = settings.global, _events = {
48
+ let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _global = settings.global, _events = {
49
49
  init: null,
50
50
  update: null,
51
51
  draw: null,
@@ -650,19 +650,6 @@
650
650
  root[key] = value;
651
651
  }
652
652
  },
653
- /**
654
- * Resizes the game canvas and emit the "resized" event
655
- *
656
- * @param {number} width
657
- * @param {number} height
658
- */
659
- resize(width, height) {
660
- instance.setvar("WIDTH", _canvas.width = width);
661
- instance.setvar("HEIGHT", _canvas.height = height);
662
- instance.setvar("CENTERX", instance.WIDTH / 2);
663
- instance.setvar("CENTERY", instance.HEIGHT / 2);
664
- onResize();
665
- },
666
653
  /**
667
654
  * The scale of the game's delta time (dt).
668
655
  * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.
@@ -712,7 +699,7 @@
712
699
  loadPlugin(callback, config);
713
700
  }
714
701
  if (settings.autoscale) {
715
- on(root, "resize", onResize);
702
+ on(root, "resize", resizeCanvas);
716
703
  }
717
704
  if (settings.tapEvents) {
718
705
  const _getXY = (pageX, pageY) => [
@@ -873,27 +860,27 @@
873
860
  _rafid = raf(drawFrame);
874
861
  }
875
862
  function drawFrame(now) {
876
- if (_animated) {
877
- _rafid = raf(drawFrame);
878
- }
879
863
  let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
880
864
  _lastFrameTime = now;
881
- if (frameTime > _deltaTime * 30) {
882
- } else {
883
- _accumulated += frameTime;
884
- if (!_animated) {
885
- _accumulated = _deltaTime;
865
+ if (_animated) {
866
+ _rafid = raf(drawFrame);
867
+ if (frameTime > 0.3) {
868
+ return void 0;
886
869
  }
887
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
870
+ _accumulated += frameTime;
871
+ while (_accumulated >= _deltaTime) {
888
872
  instance.emit("update", _deltaTime * _timeScale);
889
873
  instance.setvar(
890
874
  "ELAPSED",
891
875
  instance.ELAPSED + _deltaTime * _timeScale
892
876
  );
893
877
  updated++;
878
+ _accumulated -= _deltaTime;
894
879
  }
880
+ } else {
881
+ updated = 1;
895
882
  }
896
- if (updated || !_animated) {
883
+ if (updated) {
897
884
  instance.textalign("start", "top");
898
885
  instance.emit("draw");
899
886
  }
@@ -904,31 +891,31 @@
904
891
  _ctx = _canvas.getContext("2d");
905
892
  on(_canvas, "click", () => root.focus());
906
893
  _canvas.style = "";
907
- if (!instance.WIDTH) {
908
- instance.WIDTH = root.innerWidth;
909
- instance.HEIGHT = root.innerHeight;
910
- }
911
- instance.resize(instance.WIDTH, instance.HEIGHT, false);
894
+ resizeCanvas();
912
895
  if (!_canvas.parentNode) document.body.appendChild(_canvas);
913
896
  }
914
- function onResize() {
915
- const styles = _canvas.style;
897
+ function resizeCanvas() {
898
+ const width = settings.width || root.innerWidth, height = settings.height || settings.width || root.innerHeight;
899
+ instance.setvar("WIDTH", _canvas.width = width);
900
+ instance.setvar("HEIGHT", _canvas.height = height);
901
+ instance.setvar("CENTERX", instance.WIDTH / 2);
902
+ instance.setvar("CENTERY", instance.HEIGHT / 2);
916
903
  if (settings.autoscale) {
917
- if (!styles.display) {
918
- styles.display = "block";
919
- styles.margin = "auto";
904
+ if (!_canvas.style.display) {
905
+ _canvas.style.display = "block";
906
+ _canvas.style.margin = "auto";
920
907
  }
921
908
  _scale = math.min(
922
909
  root.innerWidth / instance.WIDTH,
923
910
  root.innerHeight / instance.HEIGHT
924
911
  );
925
912
  _scale = (settings.pixelart ? ~~_scale : _scale) || 1;
926
- styles.width = instance.WIDTH * _scale + "px";
927
- styles.height = instance.HEIGHT * _scale + "px";
913
+ _canvas.style.width = instance.WIDTH * _scale + "px";
914
+ _canvas.style.height = instance.HEIGHT * _scale + "px";
928
915
  }
929
916
  if (!settings.antialias || settings.pixelart) {
930
917
  _ctx.imageSmoothingEnabled = false;
931
- styles.imageRendering = "pixelated";
918
+ _canvas.style.imageRendering = "pixelated";
932
919
  }
933
920
  instance.emit("resized", _scale);
934
921
  if (!_animated) {
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,r=.1,o=0,s=1,c=0,f=0,d=0,u=0,p=0,g=0,h=0,m=0,E=0,v=1,b=0,w=0,x=0)=>{let T=Math,y=2*T.PI,H=c*=500*y/44100/44100,I=l*=(1-a+2*a*T.random(a=[]))*y/44100,S=0,D=0,k=0,A=1,C=0,X=0,z=0,N=x<0?-1:1,P=y*N*x*2/44100,L=T.cos(P),O=T.sin,Y=O(P)/4,F=1+Y,W=-2*L/F,G=(1-Y)/F,M=(1+N*L)/2/F,R=-(N+L)/F,B=0,U=0,q=0,V=0;for(n=44100*n+9,b*=44100,i*=44100,r*=44100,E*=44100,f*=500*y/85766121e6,h*=y/44100,d*=y/44100,u*=44100,p=44100*p|0,t*=.3*(globalThis.zzfxV||1),N=n+b+i+r+E|0;k<N;a[k++]=z*t)++X%(100*m|0)||(z=o?1<o?2<o?3<o?O(S*S):T.max(T.min(T.tan(S),1),-1):1-(2*S/y%2+2)%2:1-4*T.abs(T.round(S/y)-S/y):O(S),z=(p?1-w+w*O(y*k/p):1)*(z<0?-1:1)*T.abs(z)**s*(k<n?k/n:k<n+b?1-(k-n)/b*(1-v):k<n+b+i?v:k<N-E?(N-k-E)/r*v:0),z=E?z/2+(E>k?0:(k<N-E?1:(N-k)/E)*a[k-E|0]/2/t):z,x&&(z=V=M*B+R*(B=U)+M*(U=z)-G*q-W*(q=V))),S+=(P=(l+=c+=f)*T.cos(h*D++))+P*g*O(k**5),A&&++A>u&&(l+=d,I+=d,A=0),!p||++C%p||(l=I,c=H,A=A||1);(t=e.createBuffer(1,N,44100)).getChannelData(0).set(a),(l=e.createBufferSource()).buffer=t,l.connect(e.destination),l.start()},a=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(e={}){let l=globalThis,n=Math,i=n.PI,r=2*i,o=requestAnimationFrame,s=[],c=(e,t,a)=>{e.addEventListener(t,a,!1),s.push(()=>e.removeEventListener(t,a,!1))};e=Object.assign({width:null,height:null,autoscale:!0,pixelart:!1,antialias:!1,canvas:null,global:!0,loop:null,pauseOnBlur:!0,tapEvents:!0,keyboardEvents:!0,animate:!0},e);let f=!1,d=[],u=e.canvas||document.createElement("canvas"),p=e.animate,g=1,h,m=.5,E=1,v,b=1/60,w=0,x,T="sans-serif",y=18,H=Date.now(),I=e.global,S={init:null,update:null,draw:null,resized:null,tap:null,untap:null,tapping:null,tapped:null},D={settings:Object.assign({},e),colors:a},k={WIDTH:e.width,HEIGHT:e.height||e.width,CANVAS:null,ELAPSED:0,CENTERX:0,CENTERY:0,MOUSEX:-1,MOUSEY:-1,DEFAULT_SFX:[.5,,1675,,.06,.2,1,1.8,,,637,.06],TWO_PI:r,HALF_PI:i/2,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>i/180*e,rad2deg:e=>180/i*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let r=(e-t)/(a-t)*(n-l)+l;return i?k.clamp(r,l,n):r},norm:(e,t,a)=>k.map(e,t,a,0,1),rand:(e=0,t=1)=>(H=(1664525*H+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(k.rand(e,t+1)),seed:e=>null==e?H:H=~~e,cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):k.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,l,n,i=null){h.beginPath(),h[i?"roundRect":"rect"](~~e-m,~~t-m,~~a+2*m,~~l+2*m,i),k.stroke(n)},rectfill(e,t,a,l,n,i=null){h.beginPath(),h[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),k.fill(n)},circ(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,r),k.stroke(l)},circfill(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,r),k.fill(l)},line(e,t,a,l,n){h.beginPath();let i=.5*(0!==m&&~~e==~~a),r=.5*(0!==m&&~~t==~~l);h.moveTo(~~e+i,~~t+r),h.lineTo(~~a+i,~~l+r),k.stroke(n)},linewidth(e){h.lineWidth=~~e,m=.5*(~~e%2!=0)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,l=3,n="normal"){h.font=`${n} ${y}px ${T}`,h.fillStyle=k.getcolor(l),h.fillText(a,~~e,~~t)},textfont(e){T=e},textsize(e){y=e},textalign(e,t){e&&(h.textAlign=e),t&&(h.textBaseline=t)},image(e,t,a){h.drawImage(a,~~e,~~t)},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,r=h;if(n.width=e*i,n.height=t*i,(h=n.getContext("2d")).scale(i,i),a.push){let e=0,t=0;for(let l of(h.imageSmoothingEnabled=!1,a)){for(let a of l)" "!==a&&"."!==a&&k.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(h);return h=r,n},ctx:e=>(e&&(h=e),h),push:()=>h.save(),pop:()=>h.restore(),translate:(e,t)=>h.translate(~~e,~~t),scale:(e,t)=>h.scale(e,t||e),rotate:e=>h.rotate(e),alpha(e){h.globalAlpha=k.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){h.fillStyle=k.getcolor(e),t?h.fill(t):h.fill()},stroke(e,t){h.strokeStyle=k.getcolor(e),t?h.stroke(t):h.stroke()},clip(e){h.clip(e)},sfx:(e,a=0,n=1)=>!(l.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||k.DEFAULT_SFX,(0!==a||1!==n)&&((e=e.slice())[0]=n*(e[0]||1),e[10]=~~e[10]+a),t.apply(0,e),e),volume(e){l.zzfxV=e},use(e,t={}){f?N(e,t):d.push([e,t])},listen:(e,t)=>(S[e]=S[e]||new Set,S[e].add(t),()=>S[e].delete(t)),emit(e,t,a,l,n){f&&(z("before:"+e,t,a,l,n),z(e,t,a,l,n),z("after:"+e,t,a,l,n))},getcolor:e=>a[~~e%a.length],setvar(e,t){k[e]=t,I&&(l[e]=t)},resize(e,t){k.setvar("WIDTH",u.width=e),k.setvar("HEIGHT",u.height=t),k.setvar("CENTERX",k.WIDTH/2),k.setvar("CENTERY",k.HEIGHT/2),X()},timescale(e){E=e},setfps(e){b=1/~~e},quit(){for(let e of(cancelAnimationFrame(x),k.emit("quit"),S=[],s))e();if(I){for(let e in k)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))k[e]=n[e];function A(){f=!0;let t=e.loop?e.loop:l;for(let e in S)t[e]&&k.listen(e,t[e]);for(let[e,t]of d)N(e,t);if(e.autoscale&&c(l,"resize",X),e.tapEvents){let e=(e,t)=>[(e-u.offsetLeft)/g,(t-u.offsetTop)/g],t=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<=300,r=e=>e.preventDefault(),o=!1;c(u,"mousedown",t=>{if(0===t.button){r(t);let[l,n]=e(t.pageX,t.pageY);k.emit("tap",l,n,0),a(0,l,n),o=!0}}),c(u,"mouseup",a=>{if(0===a.button){r(a);let l=t.get(0),[n,s]=e(a.pageX,a.pageY);i(l)&&k.emit("tapped",l.startX,l.startY,0),k.emit("untap",n,s,0),t.delete(0),o=!1}}),c(u,"mousemove",t=>{r(t);let[a,l]=e(t.pageX,t.pageY);k.setvar("MOUSEX",a),k.setvar("MOUSEY",l),o&&(k.emit("tapping",a,l,0),n(0,a,l))}),c(u,"touchstart",t=>{for(let l of(r(t),t.changedTouches)){let[t,n]=e(l.pageX,l.pageY);k.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),c(u,"touchmove",t=>{for(let a of(r(t),t.changedTouches)){let[t,l]=e(a.pageX,a.pageY);k.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{r(e);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)&&k.emit("tapped",l.startX,l.startY,e),k.emit("untap",l.x,l.y,e),t.delete(e))};c(u,"touchend",s),c(u,"touchcancel",s),c(l,"blur",()=>{for(let[e,a]of(o=!1,t))k.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=e=>e.toLowerCase(),t=new Set,a=new Set,n=(t,a)=>a?t.has("space"===e(a)?" ":e(a)):t.size>0;c(l,"keydown",l=>{t.has(e(l.key))||(t.add(e(l.key)),a.add(e(l.key)))}),c(l,"keyup",a=>{t.delete(e(a.key))}),c(l,"blur",()=>t.clear()),k.listen("after:draw",()=>a.clear()),k.setvar("iskeydown",e=>n(t,e)),k.setvar("iskeypressed",e=>n(a,e))}e.pauseOnBlur&&(c(l,"blur",()=>{x=cancelAnimationFrame(x)}),c(l,"focus",()=>{x||(x=o(C))})),k.emit("init",k),v=performance.now(),x=o(C)}function C(e){p&&(x=o(C));let t=0,a=(e-v)/1e3;if(v=e,a>30*b);else for(w+=a,p||(w=b);w>=b;w-=b)k.emit("update",b*E),k.setvar("ELAPSED",k.ELAPSED+b*E),t++;(t||!p)&&(k.textalign("start","top"),k.emit("draw"))}function X(){let t=u.style;e.autoscale&&(t.display||(t.display="block",t.margin="auto"),g=n.min(l.innerWidth/k.WIDTH,l.innerHeight/k.HEIGHT),g=(e.pixelart?~~g:g)||1,t.width=k.WIDTH*g+"px",t.height=k.HEIGHT*g+"px"),(!e.antialias||e.pixelart)&&(h.imageSmoothingEnabled=!1,t.imageRendering="pixelated"),k.emit("resized",g),p||o(C)}function z(e,t,a,l,n){if(S[e])for(let i of S[e])i(t,a,l,n)}function N(e,t){let a=e(k,D,t);for(let e in a)k.setvar(e,a[e])}if(I){if(l.ENGINE)throw"two global litecanvas detected";Object.assign(l,k),l.ENGINE=k}return u="string"==typeof u?document.querySelector(u):u,k.setvar("CANVAS",u),h=u.getContext("2d"),c(u,"click",()=>l.focus()),u.style="",k.WIDTH||(k.WIDTH=l.innerWidth,k.HEIGHT=l.innerHeight),k.resize(k.WIDTH,k.HEIGHT,!1),u.parentNode||document.body.appendChild(u),"loading"===document.readyState?c(l,"DOMContentLoaded",()=>o(A)):o(A),k}})();
1
+ (()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,r=.1,o=0,s=1,c=0,f=0,d=0,u=0,p=0,h=0,g=0,m=0,v=0,E=1,b=0,w=0,x=0)=>{let y=Math,T=2*y.PI,S=c*=500*T/44100/44100,k=l*=(1-a+2*a*y.random(a=[]))*T/44100,A=0,I=0,H=0,D=1,C=0,X=0,N=0,P=x<0?-1:1,L=T*P*x*2/44100,O=y.cos(L),Y=y.sin,z=Y(L)/4,F=1+z,G=-2*O/F,M=(1-z)/F,R=(1+P*O)/2/F,W=-(P+O)/F,B=0,U=0,q=0,V=0;for(n=44100*n+9,b*=44100,i*=44100,r*=44100,v*=44100,f*=500*T/85766121e6,g*=T/44100,d*=T/44100,u*=44100,p=44100*p|0,t*=.3*(globalThis.zzfxV||1),P=n+b+i+r+v|0;H<P;a[H++]=N*t)++X%(100*m|0)||(N=o?1<o?2<o?3<o?Y(A*A):y.max(y.min(y.tan(A),1),-1):1-(2*A/T%2+2)%2:1-4*y.abs(y.round(A/T)-A/T):Y(A),N=(p?1-w+w*Y(T*H/p):1)*(N<0?-1:1)*y.abs(N)**s*(H<n?H/n:H<n+b?1-(H-n)/b*(1-E):H<n+b+i?E:H<P-v?(P-H-v)/r*E:0),N=v?N/2+(v>H?0:(H<P-v?1:(P-H)/v)*a[H-v|0]/2/t):N,x&&(N=V=R*B+W*(B=U)+R*(U=N)-M*q-G*(q=V))),A+=(L=(l+=c+=f)*y.cos(g*I++))+L*h*Y(H**5),D&&++D>u&&(l+=d,k+=d,D=0),!p||++C%p||(l=k,c=S,D=D||1);(t=e.createBuffer(1,P,44100)).getChannelData(0).set(a),(l=e.createBufferSource()).buffer=t,l.connect(e.destination),l.start()},a=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(e={}){let l=globalThis,n=Math,i=n.PI,r=2*i,o=requestAnimationFrame,s=[],c=(e,t,a)=>{e.addEventListener(t,a,!1),s.push(()=>e.removeEventListener(t,a,!1))};e=Object.assign({width:null,height:null,autoscale:!0,pixelart:!1,antialias:!1,canvas:null,global:!0,loop:null,pauseOnBlur:!0,tapEvents:!0,keyboardEvents:!0,animate:!0},e);let f=!1,d=[],u=e.canvas||document.createElement("canvas"),p=e.animate,h=1,g,m=.5,v=1,E,b=1/60,w=0,x,y="sans-serif",T=20,S=Date.now(),k=e.global,A={init:null,update:null,draw:null,resized:null,tap:null,untap:null,tapping:null,tapped:null},I={settings:Object.assign({},e),colors:a},H={WIDTH:e.width,HEIGHT:e.height||e.width,CANVAS:null,ELAPSED:0,CENTERX:0,CENTERY:0,MOUSEX:-1,MOUSEY:-1,DEFAULT_SFX:[.5,,1675,,.06,.2,1,1.8,,,637,.06],TWO_PI:r,HALF_PI:i/2,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>i/180*e,rad2deg:e=>180/i*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let r=(e-t)/(a-t)*(n-l)+l;return i?H.clamp(r,l,n):r},norm:(e,t,a)=>H.map(e,t,a,0,1),rand:(e=0,t=1)=>(S=(1664525*S+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(H.rand(e,t+1)),seed:e=>null==e?S:S=~~e,cls(e){null==e?g.clearRect(0,0,g.canvas.width,g.canvas.height):H.rectfill(0,0,g.canvas.width,g.canvas.height,e)},rect(e,t,a,l,n,i=null){g.beginPath(),g[i?"roundRect":"rect"](~~e-m,~~t-m,~~a+2*m,~~l+2*m,i),H.stroke(n)},rectfill(e,t,a,l,n,i=null){g.beginPath(),g[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),H.fill(n)},circ(e,t,a,l){g.beginPath(),g.arc(~~e,~~t,~~a,0,r),H.stroke(l)},circfill(e,t,a,l){g.beginPath(),g.arc(~~e,~~t,~~a,0,r),H.fill(l)},line(e,t,a,l,n){g.beginPath();let i=.5*(0!==m&&~~e==~~a),r=.5*(0!==m&&~~t==~~l);g.moveTo(~~e+i,~~t+r),g.lineTo(~~a+i,~~l+r),H.stroke(n)},linewidth(e){g.lineWidth=~~e,m=.5*(~~e%2!=0)},linedash(e,t=0){g.setLineDash(e),g.lineDashOffset=t},text(e,t,a,l=3,n="normal"){g.font=`${n} ${T}px ${y}`,g.fillStyle=H.getcolor(l),g.fillText(a,~~e,~~t)},textfont(e){y=e},textsize(e){T=e},textalign(e,t){e&&(g.textAlign=e),t&&(g.textBaseline=t)},image(e,t,a){g.drawImage(a,~~e,~~t)},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,r=g;if(n.width=e*i,n.height=t*i,(g=n.getContext("2d")).scale(i,i),a.push){let e=0,t=0;for(let l of(g.imageSmoothingEnabled=!1,a)){for(let a of l)" "!==a&&"."!==a&&H.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(g);return g=r,n},ctx:e=>(e&&(g=e),g),push:()=>g.save(),pop:()=>g.restore(),translate:(e,t)=>g.translate(~~e,~~t),scale:(e,t)=>g.scale(e,t||e),rotate:e=>g.rotate(e),alpha(e){g.globalAlpha=H.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){g.fillStyle=H.getcolor(e),t?g.fill(t):g.fill()},stroke(e,t){g.strokeStyle=H.getcolor(e),t?g.stroke(t):g.stroke()},clip(e){g.clip(e)},sfx:(e,a=0,n=1)=>!(l.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||H.DEFAULT_SFX,(0!==a||1!==n)&&((e=e.slice())[0]=n*(e[0]||1),e[10]=~~e[10]+a),t.apply(0,e),e),volume(e){l.zzfxV=e},use(e,t={}){f?P(e,t):d.push([e,t])},listen:(e,t)=>(A[e]=A[e]||new Set,A[e].add(t),()=>A[e].delete(t)),emit(e,t,a,l,n){f&&(N("before:"+e,t,a,l,n),N(e,t,a,l,n),N("after:"+e,t,a,l,n))},getcolor:e=>a[~~e%a.length],setvar(e,t){H[e]=t,k&&(l[e]=t)},timescale(e){v=e},setfps(e){b=1/~~e},quit(){for(let e of(cancelAnimationFrame(x),H.emit("quit"),A=[],s))e();if(k){for(let e in H)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))H[e]=n[e];function D(){f=!0;let t=e.loop?e.loop:l;for(let e in A)t[e]&&H.listen(e,t[e]);for(let[e,t]of d)P(e,t);if(e.autoscale&&c(l,"resize",X),e.tapEvents){let e=(e,t)=>[(e-u.offsetLeft)/h,(t-u.offsetTop)/h],t=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<=300,r=e=>e.preventDefault(),o=!1;c(u,"mousedown",t=>{if(0===t.button){r(t);let[l,n]=e(t.pageX,t.pageY);H.emit("tap",l,n,0),a(0,l,n),o=!0}}),c(u,"mouseup",a=>{if(0===a.button){r(a);let l=t.get(0),[n,s]=e(a.pageX,a.pageY);i(l)&&H.emit("tapped",l.startX,l.startY,0),H.emit("untap",n,s,0),t.delete(0),o=!1}}),c(u,"mousemove",t=>{r(t);let[a,l]=e(t.pageX,t.pageY);H.setvar("MOUSEX",a),H.setvar("MOUSEY",l),o&&(H.emit("tapping",a,l,0),n(0,a,l))}),c(u,"touchstart",t=>{for(let l of(r(t),t.changedTouches)){let[t,n]=e(l.pageX,l.pageY);H.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),c(u,"touchmove",t=>{for(let a of(r(t),t.changedTouches)){let[t,l]=e(a.pageX,a.pageY);H.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{r(e);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)&&H.emit("tapped",l.startX,l.startY,e),H.emit("untap",l.x,l.y,e),t.delete(e))};c(u,"touchend",s),c(u,"touchcancel",s),c(l,"blur",()=>{for(let[e,a]of(o=!1,t))H.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=e=>e.toLowerCase(),t=new Set,a=new Set,n=(t,a)=>a?t.has("space"===e(a)?" ":e(a)):t.size>0;c(l,"keydown",l=>{t.has(e(l.key))||(t.add(e(l.key)),a.add(e(l.key)))}),c(l,"keyup",a=>{t.delete(e(a.key))}),c(l,"blur",()=>t.clear()),H.listen("after:draw",()=>a.clear()),H.setvar("iskeydown",e=>n(t,e)),H.setvar("iskeypressed",e=>n(a,e))}e.pauseOnBlur&&(c(l,"blur",()=>{x=cancelAnimationFrame(x)}),c(l,"focus",()=>{x||(x=o(C))})),H.emit("init",H),E=performance.now(),x=o(C)}function C(e){let t=0,a=(e-E)/1e3;if(E=e,p){if(x=o(C),a>.3)return;for(w+=a;w>=b;)H.emit("update",b*v),H.setvar("ELAPSED",H.ELAPSED+b*v),t++,w-=b}else t=1;t&&(H.textalign("start","top"),H.emit("draw"))}function X(){let t=e.width||l.innerWidth,a=e.height||e.width||l.innerHeight;H.setvar("WIDTH",u.width=t),H.setvar("HEIGHT",u.height=a),H.setvar("CENTERX",H.WIDTH/2),H.setvar("CENTERY",H.HEIGHT/2),e.autoscale&&(u.style.display||(u.style.display="block",u.style.margin="auto"),h=n.min(l.innerWidth/H.WIDTH,l.innerHeight/H.HEIGHT),h=(e.pixelart?~~h:h)||1,u.style.width=H.WIDTH*h+"px",u.style.height=H.HEIGHT*h+"px"),(!e.antialias||e.pixelart)&&(g.imageSmoothingEnabled=!1,u.style.imageRendering="pixelated"),H.emit("resized",h),p||o(C)}function N(e,t,a,l,n){if(A[e])for(let i of A[e])i(t,a,l,n)}function P(e,t){let a=e(H,I,t);for(let e in a)H.setvar(e,a[e])}if(k){if(l.ENGINE)throw"two global litecanvas detected";Object.assign(l,H),l.ENGINE=H}return u="string"==typeof u?document.querySelector(u):u,H.setvar("CANVAS",u),g=u.getContext("2d"),c(u,"click",()=>l.focus()),u.style="",X(),u.parentNode||document.body.appendChild(u),"loading"===document.readyState?c(l,"DOMContentLoaded",()=>o(D)):o(D),H}})();
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.78.1",
3
+ "version": "0.79.0",
4
4
  "description": "Lightweight HTML5 canvas game engine suitable for small projects and creative coding. Inspired by PICO-8 and P5/Processing.",
5
5
  "license": "MIT",
6
6
  "author": "Luiz Bills <luizbills@pm.me>",
7
7
  "contributors": [],
8
8
  "devDependencies": {
9
- "@swc/core": "^1.11.9",
9
+ "@swc/core": "^1.11.13",
10
10
  "ava": "^6.2.0",
11
11
  "esbuild": "^0.25.1",
12
12
  "gzip-size": "^7.0.0",
package/src/index.js CHANGED
@@ -71,7 +71,7 @@ export default function litecanvas(settings = {}) {
71
71
  /** @type {string} */
72
72
  _fontFamily = 'sans-serif',
73
73
  /** @type {number} */
74
- _fontSize = 18,
74
+ _fontSize = 20,
75
75
  /** @type {number} */
76
76
  _rng_seed = Date.now(),
77
77
  /** @type {boolean} */
@@ -1078,31 +1078,6 @@ export default function litecanvas(settings = {}) {
1078
1078
  }
1079
1079
  },
1080
1080
 
1081
- /**
1082
- * Resizes the game canvas and emit the "resized" event
1083
- *
1084
- * @param {number} width
1085
- * @param {number} height
1086
- */
1087
- resize(width, height) {
1088
- DEV: assert(
1089
- isFinite(width) && width > 0,
1090
- 'resize: 1st param must be a number'
1091
- )
1092
- DEV: assert(
1093
- isFinite(height) && height > 0,
1094
- 'resize: 2nd param must be a number'
1095
- )
1096
-
1097
- instance.setvar('WIDTH', (_canvas.width = width))
1098
- instance.setvar('HEIGHT', (_canvas.height = height))
1099
-
1100
- instance.setvar('CENTERX', instance.WIDTH / 2)
1101
- instance.setvar('CENTERY', instance.HEIGHT / 2)
1102
-
1103
- onResize()
1104
- },
1105
-
1106
1081
  /**
1107
1082
  * The scale of the game's delta time (dt).
1108
1083
  * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.
@@ -1183,7 +1158,7 @@ export default function litecanvas(settings = {}) {
1183
1158
 
1184
1159
  // listen window resize event when "autoscale" is enabled
1185
1160
  if (settings.autoscale) {
1186
- on(root, 'resize', onResize)
1161
+ on(root, 'resize', resizeCanvas)
1187
1162
  }
1188
1163
 
1189
1164
  // default mouse/touch handlers
@@ -1404,36 +1379,40 @@ export default function litecanvas(settings = {}) {
1404
1379
  * @param {DOMHighResTimeStamp} now
1405
1380
  */
1406
1381
  function drawFrame(now) {
1407
- if (_animated) {
1408
- _rafid = raf(drawFrame)
1409
- }
1410
-
1411
1382
  let updated = 0,
1412
1383
  frameTime = (now - _lastFrameTime) / 1000
1413
1384
 
1414
1385
  _lastFrameTime = now
1415
1386
 
1416
- if (frameTime > _deltaTime * 30) {
1417
- console.warn('skipping too long frame')
1418
- } else {
1419
- _accumulated += frameTime
1387
+ if (_animated) {
1388
+ // request the next frame
1389
+ _rafid = raf(drawFrame)
1420
1390
 
1421
- if (!_animated) {
1422
- _accumulated = _deltaTime
1391
+ if (frameTime > 0.3) {
1392
+ return console.warn('skipping too long frame')
1423
1393
  }
1424
1394
 
1425
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
1395
+ _accumulated += frameTime
1396
+
1397
+ while (_accumulated >= _deltaTime) {
1426
1398
  instance.emit('update', _deltaTime * _timeScale)
1427
1399
  instance.setvar(
1428
1400
  'ELAPSED',
1429
1401
  instance.ELAPSED + _deltaTime * _timeScale
1430
1402
  )
1431
1403
  updated++
1404
+ _accumulated -= _deltaTime
1432
1405
  }
1406
+ } else {
1407
+ // when the canvas is not animated
1408
+ // we for one frame when a redraw is triggered
1409
+ updated = 1
1433
1410
  }
1434
1411
 
1435
- if (updated || !_animated) {
1436
- instance.textalign('start', 'top') // default values for textAlign & textBaseline
1412
+ if (updated) {
1413
+ // always set default values for
1414
+ // _ctx.textAlign and _ctx.textBaseline before draw
1415
+ instance.textalign('start', 'top')
1437
1416
  instance.emit('draw')
1438
1417
  }
1439
1418
  }
@@ -1449,19 +1428,6 @@ export default function litecanvas(settings = {}) {
1449
1428
  _canvas && _canvas.tagName === 'CANVAS',
1450
1429
  'Invalid canvas element'
1451
1430
  )
1452
- DEV: assert(
1453
- null == instance.WIDTH || instance.WIDTH > 0,
1454
- 'Litecanvas\' "width" option should be null or a positive number'
1455
- )
1456
- DEV: assert(
1457
- null == instance.HEIGHT || instance.HEIGHT > 0,
1458
- 'Litecanvas\' "width" option should be null or a positive number'
1459
- )
1460
- DEV: assert(
1461
- null == instance.HEIGHT ||
1462
- (instance.WIDTH > 0 && instance.HEIGHT > 0),
1463
- 'Litecanvas\' "width" is required when "heigth" is passed'
1464
- )
1465
1431
 
1466
1432
  instance.setvar('CANVAS', _canvas)
1467
1433
  _ctx = _canvas.getContext('2d')
@@ -1470,24 +1436,41 @@ export default function litecanvas(settings = {}) {
1470
1436
 
1471
1437
  _canvas.style = ''
1472
1438
 
1473
- // If width is not set, the canvas will have the size of the page width.
1474
- if (!instance.WIDTH) {
1475
- instance.WIDTH = root.innerWidth
1476
- instance.HEIGHT = root.innerHeight
1477
- }
1478
-
1479
- instance.resize(instance.WIDTH, instance.HEIGHT, false)
1439
+ resizeCanvas()
1480
1440
 
1481
1441
  if (!_canvas.parentNode) document.body.appendChild(_canvas)
1482
1442
  }
1483
1443
 
1484
- function onResize() {
1485
- const styles = _canvas.style
1444
+ function resizeCanvas() {
1445
+ DEV: assert(
1446
+ null == settings.width ||
1447
+ (isFinite(settings.width) && settings.width > 0),
1448
+ 'Litecanvas\' option "width" should be a positive number when defined'
1449
+ )
1450
+ DEV: assert(
1451
+ null == settings.height ||
1452
+ (isFinite(settings.height) && settings.height > 0),
1453
+ 'Litecanvas\' option "height" should be a positive number when defined'
1454
+ )
1455
+ DEV: assert(
1456
+ null == settings.height ||
1457
+ (settings.width > 0 && settings.height > 0),
1458
+ 'Litecanvas\' option "width" is required when the option "height" is defined'
1459
+ )
1460
+
1461
+ const width = settings.width || root.innerWidth,
1462
+ height = settings.height || settings.width || root.innerHeight
1463
+
1464
+ instance.setvar('WIDTH', (_canvas.width = width))
1465
+ instance.setvar('HEIGHT', (_canvas.height = height))
1466
+
1467
+ instance.setvar('CENTERX', instance.WIDTH / 2)
1468
+ instance.setvar('CENTERY', instance.HEIGHT / 2)
1486
1469
 
1487
1470
  if (settings.autoscale) {
1488
- if (!styles.display) {
1489
- styles.display = 'block'
1490
- styles.margin = 'auto'
1471
+ if (!_canvas.style.display) {
1472
+ _canvas.style.display = 'block'
1473
+ _canvas.style.margin = 'auto'
1491
1474
  }
1492
1475
 
1493
1476
  _scale = math.min(
@@ -1496,16 +1479,17 @@ export default function litecanvas(settings = {}) {
1496
1479
  )
1497
1480
  _scale = (settings.pixelart ? ~~_scale : _scale) || 1
1498
1481
 
1499
- styles.width = instance.WIDTH * _scale + 'px'
1500
- styles.height = instance.HEIGHT * _scale + 'px'
1482
+ _canvas.style.width = instance.WIDTH * _scale + 'px'
1483
+ _canvas.style.height = instance.HEIGHT * _scale + 'px'
1501
1484
  }
1502
1485
 
1503
1486
  // restore canvas image rendering properties
1504
1487
  if (!settings.antialias || settings.pixelart) {
1505
1488
  _ctx.imageSmoothingEnabled = false
1506
- styles.imageRendering = 'pixelated'
1489
+ _canvas.style.imageRendering = 'pixelated'
1507
1490
  }
1508
1491
 
1492
+ // trigger "resized" event
1509
1493
  instance.emit('resized', _scale)
1510
1494
 
1511
1495
  // force redraw
package/types/index.d.ts CHANGED
@@ -588,13 +588,6 @@ declare global {
588
588
  * @param value
589
589
  */
590
590
  function setvar(key: string, value: any): void
591
- /**
592
- * Resizes the game canvas and emit the "resized" event
593
- *
594
- * @param width
595
- * @param height
596
- */
597
- function resize(width: number, height: number): void
598
591
  /**
599
592
  * The scale of the game's delta time (dt).
600
593
  * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.
package/types/types.d.ts CHANGED
@@ -560,13 +560,6 @@ type LitecanvasInstance = {
560
560
  * @param value
561
561
  */
562
562
  setvar(key: string, value: any): void
563
- /**
564
- * Resizes the game canvas and emit the "resized" event
565
- *
566
- * @param width
567
- * @param height
568
- */
569
- resize(width: number, height: number): void
570
563
  /**
571
564
  * The scale of the game's delta time (dt).
572
565
  * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.