tscratch 0.5.7 → 0.5.9
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/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -13
- package/dist/index.d.ts +73 -13
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var D=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var G=Object.prototype.hasOwnProperty;var U=(r,t)=>{for(var i in t)D(r,i,{get:t[i],enumerable:!0})},j=(r,t,i,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of $(t))!G.call(r,n)&&n!==i&&D(r,n,{get:()=>t[n],enumerable:!(e=H(t,n))||e.enumerable});return r};var J=r=>j(D({},"__esModule",{value:!0}),r);var Q={};U(Q,{Circle:()=>S,Engine:()=>b,ImageSprite:()=>M,Oval:()=>v,Pen:()=>C,Rectangle:()=>y,RegularPolygon:()=>P,Sprite:()=>l,Square:()=>w,Text:()=>B,canvas:()=>s,ctx:()=>h,default:()=>N,setAspectRatio:()=>X,setScale:()=>L});module.exports=J(Q);var s=document.getElementById("game-window")||document.createElement("canvas"),h=s.getContext("2d"),u=document.createElement("canvas"),o=u.getContext("2d");u.id="pen-canvas";var O=16/9,p;function L(r){p=r,s.width=O*p,s.height=p,u.width=O*p,u.height=p}function X(r){O=r,s.width=O*p,s.height=p,u.width=O*p,u.height=p}s.parentElement?.insertBefore(u,s);L(500);var l=class r{x;y;dir;scene;hidden;layer;cachedPath=null;pathDirty=!0;static collisionCanvas=null;static collisionCtx=null;refresh(){b.init().refresh()}invalidatePath(){this.pathDirty=!0,this.cachedPath=null}getCachedPath(){return(this.pathDirty||!this.cachedPath)&&(this.cachedPath=this.getPath(),this.pathDirty=!1),this.cachedPath}constructor(t){this.x=t?.x??0,this.y=t?.y??0,this.dir=t?.dir??0,this.scene=t?.scene??"main",this.hidden=t?.hidden??!1,this.layer=t?.layer??0,b.init().addSprite(this)}touching(t){let i=this.getBoundingBox(),e=t.getBoundingBox();if(!(Math.abs(i.x-e.x)<(i.width+e.width)/2&&Math.abs(i.y-e.y)<(i.height+e.height)/2))return!1;let a=i.x-i.width/2,m=i.y+i.height/2,f=i.x+i.width/2,x=i.y-i.height/2,W=e.x-e.width/2,k=e.y+e.height/2,I=e.x+e.width/2,A=e.y-e.height/2,T=Math.max(a,W),F=Math.min(x,A),z=Math.min(f,I),E=Math.max(m,k),g=z-T,d=E-F;if(g<=1||d<=1)return!1;r.collisionCanvas||(r.collisionCanvas=document.createElement("canvas"),r.collisionCtx=r.collisionCanvas.getContext("2d",{willReadFrequently:!0})),(r.collisionCanvas.width<g||r.collisionCanvas.height<d)&&(r.collisionCanvas.width=Math.max(g,r.collisionCanvas.width),r.collisionCanvas.height=Math.max(d,r.collisionCanvas.height));let c=r.collisionCtx;c.clearRect(0,0,g,d),c.save(),c.translate(this.x-T,d-this.y+F),c.rotate(this.toRadians(this.dir)),c.fillStyle="red",c.fill(this.getCachedPath()),c.restore();let Y=c.getImageData(0,0,g,d).data;c.clearRect(0,0,g,d),c.save(),c.translate(t.x-T,d-t.y+F),c.rotate(this.toRadians(t.dir)),c.fillStyle="blue",c.fill(t.getCachedPath()),c.restore();let q=c.getImageData(0,0,g,d).data;for(let R=3;R<Y.length;R+=4)if(Y[R]>0&&q[R]>0)return!0;return!1}toRadians(t){return t*Math.PI/180}toDegrees(t){return t*180/Math.PI}move(t){this.x+=t*Math.sin(this.toRadians(this.dir)),this.y+=t*Math.cos(this.toRadians(this.dir)),this.refresh()}turn(t){this.dir+=t,this.refresh()}point(t){this.dir=t,this.refresh()}pointTowards(t,i){this.dir=90-this.toDegrees(Math.atan2(i,t)),this.refresh()}setX(t){this.x=t,this.refresh()}setY(t){this.y=t,this.refresh()}goTo(t,i){this.x=t,this.y=i,this.refresh()}changeX(t){this.x+=t,this.refresh()}changeY(t){this.y+=t,this.refresh()}show(){this.hidden=!1,this.refresh()}hide(){this.hidden=!0,this.refresh()}goToLayer(t){this.layer=t,this.refresh()}changeLayer(t){this.layer+=t,this.refresh()}};var b=class r{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;deltaTime=1/this.maxFPS;lastFrame=performance.now();refreshScheduled=!1;animationFrameId=null;sounds=[];mouseX=0;mouseY=0;mouseDown=!1;mouseClicked=!1;keysPressed=new Set;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new r),this.instance}changeScene(t){this.sceneMap[t]||(this.sceneMap[t]={sprites:[],loop:null}),this.loopRunning=!1,this.currentScene=t,this.gameLoop=this.sceneMap[t].loop,this.setMaxFramesPerSecond(this.maxFPS)}setLoop(t,i){if(!this.sceneMap[t]){this.sceneMap[t]={sprites:[],loop:i},t===this.currentScene&&this.changeScene(t);return}this.sceneMap[t].loop=i,t===this.currentScene&&this.changeScene(t)}pauseLoop(){this.loopRunning=!1,this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}resumeLoop(){this.loopRunning=!0,this.setMaxFramesPerSecond(this.maxFPS)}addSprite(t){let{scene:i,layer:e}=t;if(!this.sceneMap[i]){this.sceneMap[i]={sprites:[t],loop:null};return}let n=this.sceneMap[i].sprites.findIndex(a=>a.layer>e);if(n===-1){this.sceneMap[i].sprites.push(t);return}this.sceneMap[i].sprites.splice(n,0,t),this.refresh()}removeSprite(t){let{scene:i}=t;this.sceneMap[i]&&(this.sceneMap[i].sprites=this.sceneMap[i].sprites.filter(e=>e!==t),this.refresh())}async setMaxFramesPerSecond(t){this.maxFPS=t;let i=this.gameLoop;if(!i)return;this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.loopRunning=!0;let e=1e3/t,n=0,a=async m=>{if(!this.loopRunning)return;let f=m-this.lastFrame;this.lastFrame=m,n+=f,n>=e&&(this.deltaTime=n/1e3,n=n%e,i&&await i()),this.animationFrameId=requestAnimationFrame(a)};this.lastFrame=performance.now(),this.animationFrameId=requestAnimationFrame(a)}refresh(){this.refreshScheduled||(this.refreshScheduled=!0,requestAnimationFrame(()=>{this.refreshScheduled=!1,h.clearRect(0,0,s.width,s.height),[...this.sceneMap[this.currentScene]?.sprites??[],...this.sceneMap["*"]?.sprites??[]].forEach(i=>{i.hidden||i.draw()})}))}async wait(t){return new Promise(i=>setTimeout(i,t))}async waitUntil(t){return new Promise(i=>{let e=()=>{t()?i():setTimeout(e,1e3/this.maxFPS)};e()})}hovering(t){let{mouseX:i,mouseY:e}=this,n=i+s.width/2,a=s.height/2-e,m=n-(t.x+s.width/2),f=a-(s.height/2-t.y),x=-this.toRadians(t.dir),W=m*Math.cos(x)-f*Math.sin(x),k=m*Math.sin(x)+f*Math.cos(x);return h.isPointInPath(t.getPath(),W,k)}keyPressed(t){return this.keysPressed.has(t)}playSound(t){let i=new Audio(t);return this.sounds.push(i),i.play(),i}stopSound(t){t.pause(),t.currentTime=0,this.sounds=this.sounds.filter(i=>i!==t)}stopAllSounds(){this.sounds.forEach(t=>{t.pause(),t.currentTime=0}),this.sounds=[]}pickRandom(t,i){return t>i&&([t,i]=[i,t]),Math.floor(Math.random()*(i-t+1)+t)}sin(t){return Math.sin(this.toRadians(t))}cos(t){return Math.cos(this.toRadians(t))}tan(t){return Math.tan(this.toRadians(t))}csc(t){return 1/Math.sin(this.toRadians(t))}sec(t){return 1/Math.cos(this.toRadians(t))}cot(t){return 1/Math.tan(this.toRadians(t))}asin(t){return this.toDegrees(Math.asin(t))}acos(t){return this.toDegrees(Math.acos(t))}acsc(t){return this.toDegrees(Math.asin(1/t))}asec(t){return this.toDegrees(Math.acos(1/t))}toRadians(t){return t*Math.PI/180}toDegrees(t){return t*180/Math.PI}constructor(){this.setMaxFramesPerSecond(24),u.addEventListener("mousemove",t=>{this.mouseX=t.clientX-u.offsetLeft-u.width/2,this.mouseY=-(t.clientY-u.offsetTop-u.height/2)}),u.addEventListener("mousedown",t=>{this.mouseDown=!0}),u.addEventListener("mouseup",t=>{this.mouseDown=!1}),u.addEventListener("click",t=>{this.mouseClicked=!0,setTimeout(()=>this.mouseClicked=!1,0)}),addEventListener("keydown",t=>{t.repeat||this.keysPressed.add(t.key)}),addEventListener("keyup",t=>{this.keysPressed.delete(t.key)})}};var y=class extends l{discriminant="rectangle";width;height;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:Math.hypot(this.width,this.height),height:Math.hypot(this.width,this.height)}}getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let i=t?o:h;i.save();let e=this.x+s.width/2,n=-this.y+s.height/2;i.translate(e,n),i.rotate(this.toRadians(this.dir));let a=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(a),this.outlineWidth&&i.stroke(a),i.restore()}setWidth(t){this.width=t,this.invalidatePath(),this.refresh()}setHeight(t){this.height=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.width=t?.width??50,this.height=t?.height??50,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var w=class extends l{discriminant="square";sideLength;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:Math.hypot(this.sideLength,this.sideLength),height:Math.hypot(this.sideLength,this.sideLength)}}getPath(){let t=new Path2D;return t.rect(-this.sideLength/2,-this.sideLength/2,this.sideLength,this.sideLength),t}draw(t){let i=t?o:h;i.save();let e=this.x+s.width/2,n=-this.y+s.height/2;i.translate(e,n),i.rotate(this.toRadians(this.dir));let a=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(a),this.outlineWidth&&i.stroke(a),i.restore()}setSideLength(t){this.sideLength=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.sideLength=t?.sideLength??50,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var v=class extends l{discriminant="circle";radX;radY;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:Math.hypot(this.radX*2,this.radY*2),height:Math.hypot(this.radX*2,this.radY*2)}}getPath(){let t=new Path2D;return t.ellipse(0,0,this.radX,this.radY,0,0,Math.PI*2),t}draw(t){let i=t?o:h;i.save();let e=this.x+s.width/2,n=-this.y+s.height/2;i.translate(e,n),i.rotate(this.toRadians(this.dir));let a=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(a),this.outlineWidth&&i.stroke(a),i.restore()}setRadX(t){this.radX=t,this.invalidatePath(),this.refresh()}setRadY(t){this.radY=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.radX=t?.radX??25,this.radY=t?.radY??25,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var S=class extends l{discriminant="circle";radius;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.radius*2,height:this.radius*2}}getPath(){let t=new Path2D;return t.ellipse(0,0,this.radius,this.radius,0,0,Math.PI*2),t}draw(t){let i=t?o:h;i.save();let e=this.x+s.width/2,n=-this.y+s.height/2;i.translate(e,n),i.rotate(this.toRadians(this.dir));let a=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(a),this.outlineWidth&&i.stroke(a),i.restore()}setRadius(t){this.radius=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.radius=t?.radius??25,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var P=class extends l{discriminant="regularpolygon";sides;radius;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.radius*2,height:this.radius*2}}getPath(){let t=new Path2D,i=2*Math.PI/this.sides;t.moveTo(this.radius,0);for(let e=1;e<this.sides;e++)t.lineTo(this.radius*Math.cos(i*e),this.radius*Math.sin(i*e));return t.closePath(),t}draw(t){let i=t?o:h;i.save();let e=this.x+s.width/2,n=-this.y+s.height/2;i.translate(e,n),i.rotate(this.toRadians(this.dir));let a=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(a),this.outlineWidth&&i.stroke(a),i.restore()}setSides(t){this.sides=t,this.invalidatePath(),this.refresh()}setRadius(t){this.radius=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.sides=t?.sides??5,this.radius=t?.radius??50,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var C=class extends l{discriminant="pen";drawing;size;color;getBoundingBox(){return{x:this.x,y:this.y,width:this.size,height:this.size}}getPath(){return new Path2D}draw(){}up(){this.drawing=!1}down(){this.drawing=!0}stamp(t){t.draw(!0)}eraseAll(){o.clearRect(0,0,s.width,s.height)}dot(){o.fillStyle=this.color,o.fillRect(this.x-this.size/2+s.width/2,-this.y-this.size/2+s.height/2,this.size,this.size)}drawLine(t,i){o.beginPath(),o.moveTo(t+s.width/2,-i+s.height/2),o.lineTo(this.x+s.width/2,-this.y+s.height/2),o.lineWidth=this.size,o.strokeStyle=this.color,o.stroke()}move(t){let i=this.x,e=this.y;this.x+=t*Math.sin(this.toRadians(this.dir)),this.y+=t*Math.cos(this.toRadians(this.dir)),this.drawing&&this.drawLine(i,e),this.refresh()}setX(t){let i=this.x,e=this.y;this.x=t,this.drawing&&this.drawLine(i,e),this.refresh()}setY(t){let i=this.x,e=this.y;this.y=t,this.drawing&&this.drawLine(i,e),this.refresh()}goTo(t,i){let e=this.x,n=this.y;this.x=t,this.y=i,this.drawing&&this.drawLine(e,n),this.refresh()}changeX(t){let i=this.x,e=this.y;this.x+=t,this.drawing&&this.drawLine(i,e),this.refresh()}changeY(t){let i=this.x,e=this.y;this.y+=t,this.drawing&&this.drawLine(i,e),this.refresh()}constructor(t){super(t),this.drawing=t?.drawing??!1,this.size=t?.size??5,this.color=t?.color??"black"}};var B=class extends l{discriminant="text";content;color;fontFamily;fontSize;align;baseline;font;getBoundingBox(){let t=h.measureText(this.content),i=t.width,e=t.actualBoundingBoxAscent+t.actualBoundingBoxDescent;return{x:this.x,y:this.y,width:i,height:e}}getPath(){let t=new Path2D;h.save(),h.font=this.font;let i=h.measureText(this.content),e=i.width,n=i.actualBoundingBoxAscent+i.actualBoundingBoxDescent;return h.restore(),t.rect(-e/2,-n/2,e,n),t}draw(t){let i=t?o:h;i.save();let e=this.x+s.width/2,n=-this.y+s.height/2;i.translate(e,n),i.rotate(this.toRadians(this.dir)),i.font=this.font,i.fillStyle=this.color,i.textAlign=this.align,i.textBaseline=this.baseline,i.fillText(this.content,0,0),i.restore()}setContent(t){this.content=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}setFontSize(t){this.fontSize=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.invalidatePath(),this.refresh()}setFontFamily(t){this.fontFamily=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.invalidatePath(),this.refresh()}setAlign(t){this.align=t,this.invalidatePath(),this.refresh()}setBaseline(t){this.baseline=t,this.invalidatePath(),this.refresh()}constructor(t){super(t),this.content=t?.content??"",this.color=t?.color??"black",this.fontFamily=t?.fontFamily??"Arial",this.fontSize=t?.fontSize??16,this.align=t?.align??"center",this.baseline=t?.baseline??"middle",this.font=`${this.fontSize}px ${this.fontFamily}`,this.draw()}};var M=class extends l{discriminant="imagesprite";src;width;height;outlineColor;outlineWidth;img;getBoundingBox(){return{x:this.x,y:this.y,width:this.width,height:this.height}}getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let i=t?o:h;i.save();let e=this.x+s.width/2,n=-this.y+s.height/2;i.translate(e,n),i.rotate(this.toRadians(this.dir)),i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height),this.outlineWidth&&i.stroke(this.getCachedPath()),i.restore()}setSrc(t){this.src=t,this.refresh()}setWidth(t){this.width=t,this.invalidatePath(),this.refresh()}setHeight(t){this.height=t,this.invalidatePath(),this.refresh()}constructor(t){super(t),this.src=t?.src??"",this.img=new Image,this.img.src=this.src,this.width=t?.width??this.img.width,this.height=t?.height??this.img.height,this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var K={Engine:b,Sprite:l,Rectangle:y,Square:w,Oval:v,Circle:S,RegularPolygon:P,Pen:C,Text:B,ImageSprite:M,setScale:L,setAspectRatio:X,canvas:s,ctx:h},N=K;0&&(module.exports={Circle,Engine,ImageSprite,Oval,Pen,Rectangle,RegularPolygon,Sprite,Square,Text,canvas,ctx,setAspectRatio,setScale});
|
|
1
|
+
"use strict";var Y=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var U=(n,t)=>{for(var i in t)Y(n,i,{get:t[i],enumerable:!0})},J=(n,t,i,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of G(t))!j.call(n,r)&&r!==i&&Y(n,r,{get:()=>t[r],enumerable:!(e=$(t,r))||e.enumerable});return n};var K=n=>J(Y({},"__esModule",{value:!0}),n);var Z={};U(Z,{Arc:()=>C,Circle:()=>S,CustomPolygon:()=>B,Engine:()=>b,ImageSprite:()=>R,Oval:()=>v,Pen:()=>O,Rectangle:()=>y,RegularPolygon:()=>P,Sprite:()=>l,Square:()=>w,Text:()=>M,canvas:()=>s,ctx:()=>o,default:()=>Q,setAspectRatio:()=>I,setScale:()=>L});module.exports=K(Z);var s=document.getElementById("game-window")||document.createElement("canvas"),o=s.getContext("2d"),u=document.createElement("canvas"),a=u.getContext("2d");u.id="pen-canvas";var W=16/9,d;function L(n){d=n,s.width=W*d,s.height=d,u.width=W*d,u.height=d}function I(n){W=n,s.width=W*d,s.height=d,u.width=W*d,u.height=d}s.parentElement?.insertBefore(u,s);L(500);var l=class n{x;y;dir;scene;hidden;layer;cachedPath=null;pathDirty=!0;static collisionCanvas=null;static collisionCtx=null;refresh(){b.init().refresh()}invalidatePath(){this.pathDirty=!0,this.cachedPath=null}getCachedPath(){return(this.pathDirty||!this.cachedPath)&&(this.cachedPath=this.getPath(),this.pathDirty=!1),this.cachedPath}constructor(t){Object.assign(this,t),b.init().addSprite(this)}clone(t){return this.create({x:this.x,y:this.y,dir:this.dir,scene:this.scene,layer:this.layer,hidden:this.hidden,...t})}touching(t){if(this.hidden||t.hidden)return!1;let i=this.getBoundingBox(),e=t.getBoundingBox();if(!(Math.abs(i.x-e.x)<(i.width+e.width)/2&&Math.abs(i.y-e.y)<(i.height+e.height)/2))return!1;let h=i.x-i.width/2,g=i.y+i.height/2,f=i.x+i.width/2,x=i.y-i.height/2,T=e.x-e.width/2,D=e.y+e.height/2,V=e.x+e.width/2,z=e.y-e.height/2,F=Math.max(h,T),X=Math.min(x,z),E=Math.min(f,V),q=Math.max(g,D),m=E-F,p=q-X;if(m<=1||p<=1)return!1;n.collisionCanvas||(n.collisionCanvas=document.createElement("canvas"),n.collisionCtx=n.collisionCanvas.getContext("2d",{willReadFrequently:!0})),(n.collisionCanvas.width<m||n.collisionCanvas.height<p)&&(n.collisionCanvas.width=Math.max(m,n.collisionCanvas.width),n.collisionCanvas.height=Math.max(p,n.collisionCanvas.height));let c=n.collisionCtx;c.clearRect(0,0,m,p),c.save(),c.translate(this.x-F,p-this.y+X),c.rotate(this.toRadians(this.dir)),c.fillStyle="red",c.fill(this.getCachedPath()),c.restore();let A=c.getImageData(0,0,m,p).data;c.clearRect(0,0,m,p),c.save(),c.translate(t.x-F,p-t.y+X),c.rotate(this.toRadians(t.dir)),c.fillStyle="blue",c.fill(t.getCachedPath()),c.restore();let H=c.getImageData(0,0,m,p).data;for(let k=3;k<A.length;k+=4)if(A[k]>0&&H[k]>0)return!0;return!1}toRadians(t){return t*Math.PI/180}toDegrees(t){return t*180/Math.PI}move(t){this.x+=t*Math.sin(this.toRadians(this.dir)),this.y+=t*Math.cos(this.toRadians(this.dir)),this.refresh()}turn(t){this.dir+=t,this.refresh()}point(t){this.dir=t,this.refresh()}pointTowards(t,i){this.dir=90-this.toDegrees(Math.atan2(i,t)),this.refresh()}setX(t){this.x=t,this.refresh()}setY(t){this.y=t,this.refresh()}goTo(t,i){this.x=t,this.y=i,this.refresh()}changeX(t){this.x+=t,this.refresh()}changeY(t){this.y+=t,this.refresh()}show(){this.hidden=!1,this.refresh()}hide(){this.hidden=!0,this.refresh()}goToLayer(t){this.layer=t,this.refresh()}changeLayer(t){this.layer+=t,this.refresh()}};var b=class n{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;deltaTime=1/this.maxFPS;lastFrame=performance.now();refreshScheduled=!1;animationFrameId=null;sounds=[];mouseX=0;mouseY=0;mouseDown=!1;mouseClicked=!1;keysPressed=new Set;currentScene="main";sceneMap=new Map;static init(){return this.instance||(this.instance=new n),this.instance}changeScene(t){this.sceneMap.get(t)||this.sceneMap.set(t,{sprites:[],loop:null}),this.loopRunning=!1,this.currentScene=t,this.gameLoop=this.sceneMap.get(t).loop,this.setMaxFramesPerSecond(this.maxFPS)}setLoop(t,i){if(!this.sceneMap.get(t)){this.sceneMap.set(t,{sprites:[],loop:i}),t===this.currentScene&&this.changeScene(t);return}this.sceneMap.get(t).loop=i,t===this.currentScene&&this.changeScene(t)}pauseLoop(){this.loopRunning=!1,this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}resumeLoop(){this.loopRunning=!0,this.setMaxFramesPerSecond(this.maxFPS)}addSprite(t){let{scene:i,layer:e}=t;if(!this.sceneMap.get(i)){this.sceneMap.set(i,{sprites:[t],loop:null});return}let r=this.sceneMap.get(i).sprites.findIndex(h=>h.layer>e);if(r===-1){this.sceneMap.get(i).sprites.push(t);return}this.sceneMap.get(i).sprites.splice(r,0,t),this.refresh()}removeSprite(t){let{scene:i}=t;this.sceneMap.get(i)&&(this.sceneMap.get(i).sprites=this.sceneMap.get(i).sprites.filter(e=>e!==t),this.refresh())}async setMaxFramesPerSecond(t){this.maxFPS=t;let i=this.gameLoop;if(!i)return;this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.loopRunning=!0;let e=1e3/t,r=0,h=async g=>{if(!this.loopRunning)return;let f=g-this.lastFrame;this.lastFrame=g,r+=f,r>=e&&(this.deltaTime=r/1e3,r=r%e,i&&await i()),this.animationFrameId=requestAnimationFrame(h)};this.lastFrame=performance.now(),this.animationFrameId=requestAnimationFrame(h)}refresh(){this.refreshScheduled||(this.refreshScheduled=!0,requestAnimationFrame(()=>{this.refreshScheduled=!1,o.clearRect(0,0,s.width,s.height),[...this.sceneMap.get(this.currentScene).sprites,...this.sceneMap.get("*").sprites].forEach(i=>{i.hidden||i.draw()})}))}async wait(t){return new Promise(i=>setTimeout(i,t))}async waitUntil(t){return new Promise(i=>{let e=()=>{t()?i():setTimeout(e,1e3/this.maxFPS)};e()})}hovering(t){let{mouseX:i,mouseY:e}=this,r=i+s.width/2,h=s.height/2-e,g=r-(t.x+s.width/2),f=h-(s.height/2-t.y),x=-this.toRadians(t.dir),T=g*Math.cos(x)-f*Math.sin(x),D=g*Math.sin(x)+f*Math.cos(x);return o.isPointInPath(t.getPath(),T,D)}keyPressed(t){return this.keysPressed.has(t)}playSound(t){let i=new Audio(t);return this.sounds.push(i),i.play(),i}stopSound(t){t.pause(),t.currentTime=0,this.sounds=this.sounds.filter(i=>i!==t)}stopAllSounds(){this.sounds.forEach(t=>{t.pause(),t.currentTime=0}),this.sounds=[]}pickRandom(t,i){return t>i&&([t,i]=[i,t]),Math.floor(Math.random()*(i-t+1)+t)}dotProduct(t){let[i,e]=t;switch(i.length){case 2:return i[0]*e[0]+i[1]*e[1];case 3:return i[0]*e[0]+i[1]*e[1]+i[2]*e[2];case 4:return i[0]*e[0]+i[1]*e[1]+i[2]*e[2]+i[3]*e[3]}}sin(t){return Math.sin(this.toRadians(t))}cos(t){return Math.cos(this.toRadians(t))}tan(t){return Math.tan(this.toRadians(t))}csc(t){return 1/Math.sin(this.toRadians(t))}sec(t){return 1/Math.cos(this.toRadians(t))}cot(t){return 1/Math.tan(this.toRadians(t))}asin(t){return this.toDegrees(Math.asin(t))}acos(t){return this.toDegrees(Math.acos(t))}acsc(t){return this.toDegrees(Math.asin(1/t))}asec(t){return this.toDegrees(Math.acos(1/t))}toRadians(t){return t*Math.PI/180}toDegrees(t){return t*180/Math.PI}constructor(){this.setMaxFramesPerSecond(24),u.addEventListener("mousemove",t=>{this.mouseX=t.clientX-u.offsetLeft-u.width/2,this.mouseY=-(t.clientY-u.offsetTop-u.height/2)}),u.addEventListener("mousedown",t=>{this.mouseDown=!0}),u.addEventListener("mouseup",t=>{this.mouseDown=!1}),u.addEventListener("click",t=>{this.mouseClicked=!0,setTimeout(()=>this.mouseClicked=!1,0)}),addEventListener("keydown",t=>{t.repeat||this.keysPressed.add(t.key)}),addEventListener("keyup",t=>{this.keysPressed.delete(t.key)})}};var y=class n extends l{discriminant="rectangle";width;height;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:Math.hypot(this.width,this.height),height:Math.hypot(this.width,this.height)}}getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir));let h=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(h),this.outlineWidth&&i.stroke(h),i.restore()}create(t){return new n(t)}setWidth(t){this.width=t,this.invalidatePath(),this.refresh()}setHeight(t){this.height=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.width=t?.width??50,this.height=t?.height??50,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var w=class n extends l{discriminant="square";sideLength;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:Math.hypot(this.sideLength,this.sideLength),height:Math.hypot(this.sideLength,this.sideLength)}}getPath(){let t=new Path2D;return t.rect(-this.sideLength/2,-this.sideLength/2,this.sideLength,this.sideLength),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir));let h=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(h),this.outlineWidth&&i.stroke(h),i.restore()}create(t){return new n(t)}setSideLength(t){this.sideLength=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.sideLength=t?.sideLength??50,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var v=class n extends l{discriminant="oval";radX;radY;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:Math.hypot(this.radX*2,this.radY*2),height:Math.hypot(this.radX*2,this.radY*2)}}getPath(){let t=new Path2D;return t.ellipse(0,0,this.radX,this.radY,0,0,Math.PI*2),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir));let h=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(h),this.outlineWidth&&i.stroke(h),i.restore()}create(t){return new n(t)}setRadX(t){this.radX=t,this.invalidatePath(),this.refresh()}setRadY(t){this.radY=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.radX=t?.radX??25,this.radY=t?.radY??25,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var S=class n extends l{discriminant="circle";radius;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.radius*2,height:this.radius*2}}getPath(){let t=new Path2D;return t.ellipse(0,0,this.radius,this.radius,0,0,Math.PI*2),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir));let h=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(h),this.outlineWidth&&i.stroke(h),i.restore()}create(t){return new n(t)}setRadius(t){this.radius=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.radius=t?.radius??25,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var C=class n extends l{discriminant="arc";radius;angle;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.radius*2,height:this.radius*2}}getPath(){let t=new Path2D;return t.arc(0,0,this.radius,this.toRadians(this.angle/2-90),this.toRadians(-this.angle/2-90)),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir));let h=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(h),this.outlineWidth&&i.stroke(h),i.restore()}create(t){return new n(t)}setRadius(t){this.radius=t,this.invalidatePath(),this.refresh()}setAngle(t){this.angle=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.radius=t?.radius??25,this.angle=t?.angle??270,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var P=class n extends l{discriminant="regularpolygon";sides;radius;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.radius*2,height:this.radius*2}}getPath(){let t=new Path2D,i=2*Math.PI/this.sides;t.moveTo(this.radius,0);for(let e=1;e<this.sides;e++)t.lineTo(this.radius*Math.cos(i*e),this.radius*Math.sin(i*e));return t.closePath(),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir));let h=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(h),this.outlineWidth&&i.stroke(h),i.restore()}create(t){return new n(t)}setSides(t){this.sides=t,this.invalidatePath(),this.refresh()}setRadius(t){this.radius=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.sides=t?.sides??5,this.radius=t?.radius??50,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var B=class n extends l{discriminant="custompolygon";vertices;color;outlineColor;outlineWidth;getBoundingBox(){let t=0;for(let i of this.vertices){let e=Math.hypot(i[0],i[1]);e>t&&(t=e)}return{x:this.x,y:this.y,width:t,height:t}}getPath(){let t=new Path2D,i=this.vertices;if(i.length<2)return t;t.moveTo(i[0][0],i[0][1]);for(let e=1;e<i.length;e++)t.lineTo(i[e][0],i[e][1]);return t.closePath(),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir));let h=this.getCachedPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(h),this.outlineWidth&&i.stroke(h),i.restore()}create(t){return new n(t)}setVertices(t){this.vertices=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.vertices=t?.vertices??[],this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var O=class n extends l{discriminant="pen";drawing;size;color;getBoundingBox(){return{x:this.x,y:this.y,width:this.size,height:this.size}}getPath(){return new Path2D}draw(){}create(t){return new n(t)}up(){this.drawing=!1}down(){this.drawing=!0}stamp(t){t.draw(!0)}eraseAll(){a.clearRect(0,0,s.width,s.height)}dot(){a.fillStyle=this.color,a.fillRect(this.x-this.size/2+s.width/2,-this.y-this.size/2+s.height/2,this.size,this.size)}drawLine(t,i){a.beginPath(),a.moveTo(t+s.width/2,-i+s.height/2),a.lineTo(this.x+s.width/2,-this.y+s.height/2),a.lineWidth=this.size,a.strokeStyle=this.color,a.stroke()}move(t){let i=this.x,e=this.y;this.x+=t*Math.sin(this.toRadians(this.dir)),this.y+=t*Math.cos(this.toRadians(this.dir)),this.drawing&&this.drawLine(i,e),this.refresh()}setX(t){let i=this.x,e=this.y;this.x=t,this.drawing&&this.drawLine(i,e),this.refresh()}setY(t){let i=this.x,e=this.y;this.y=t,this.drawing&&this.drawLine(i,e),this.refresh()}goTo(t,i){let e=this.x,r=this.y;this.x=t,this.y=i,this.drawing&&this.drawLine(e,r),this.refresh()}changeX(t){let i=this.x,e=this.y;this.x+=t,this.drawing&&this.drawLine(i,e),this.refresh()}changeY(t){let i=this.x,e=this.y;this.y+=t,this.drawing&&this.drawLine(i,e),this.refresh()}constructor(t){super(t),this.drawing=t?.drawing??!1,this.size=t?.size??5,this.color=t?.color??"black"}};var M=class n extends l{discriminant="text";content;color;fontFamily;fontSize;align;baseline;font;getBoundingBox(){let t=o.measureText(this.content),i=t.width,e=t.actualBoundingBoxAscent+t.actualBoundingBoxDescent;return{x:this.x,y:this.y,width:i,height:e}}getPath(){let t=new Path2D;o.save(),o.font=this.font;let i=o.measureText(this.content),e=i.width,r=i.actualBoundingBoxAscent+i.actualBoundingBoxDescent;return o.restore(),t.rect(-e/2,-r/2,e,r),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir)),i.font=this.font,i.fillStyle=this.color,i.textAlign=this.align,i.textBaseline=this.baseline,i.fillText(this.content,0,0),i.restore()}create(t){return new n(t)}setContent(t){this.content=t,this.invalidatePath(),this.refresh()}setColor(t){this.color=t,this.refresh()}setFontSize(t){this.fontSize=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.invalidatePath(),this.refresh()}setFontFamily(t){this.fontFamily=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.invalidatePath(),this.refresh()}setAlign(t){this.align=t,this.invalidatePath(),this.refresh()}setBaseline(t){this.baseline=t,this.invalidatePath(),this.refresh()}constructor(t){super(t),this.content=t?.content??"",this.color=t?.color??"black",this.fontFamily=t?.fontFamily??"Arial",this.fontSize=t?.fontSize??16,this.align=t?.align??"center",this.baseline=t?.baseline??"middle",this.font=`${this.fontSize}px ${this.fontFamily}`,this.draw()}};var R=class n extends l{discriminant="imagesprite";src;width;height;outlineColor;outlineWidth;img;getBoundingBox(){return{x:this.x,y:this.y,width:this.width,height:this.height}}getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let i=t?a:o;i.save();let e=this.x+s.width/2,r=-this.y+s.height/2;i.translate(e,r),i.rotate(this.toRadians(this.dir)),i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height),this.outlineWidth&&i.stroke(this.getCachedPath()),i.restore()}create(t){return new n(t)}setSrc(t){this.src=t,this.refresh()}setWidth(t){this.width=t,this.invalidatePath(),this.refresh()}setHeight(t){this.height=t,this.invalidatePath(),this.refresh()}constructor(t){super(t),this.src=t?.src??"",this.img=new Image,this.img.src=this.src,this.width=t?.width??this.img.width,this.height=t?.height??this.img.height,this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var N={Engine:b,Sprite:l,Rectangle:y,Square:w,Oval:v,Circle:S,Arc:C,RegularPolygon:P,CustomPolygon:B,Pen:O,Text:M,ImageSprite:R,setScale:L,setAspectRatio:I,canvas:s,ctx:o},Q=N;0&&(module.exports={Arc,Circle,CustomPolygon,Engine,ImageSprite,Oval,Pen,Rectangle,RegularPolygon,Sprite,Square,Text,canvas,ctx,setAspectRatio,setScale});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/canvas.ts","../src/Sprite.ts","../src/Engine.ts","../src/sprites/Rectangle.ts","../src/sprites/Square.ts","../src/sprites/Oval.ts","../src/sprites/Circle.ts","../src/sprites/RegularPolygon.ts","../src/sprites/Pen.ts","../src/sprites/Text.ts","../src/sprites/ImageSprite.ts"],"sourcesContent":["import Engine from './Engine.ts';\r\nimport Sprite, { type SpriteOptions } from './Sprite.ts';\r\nimport { setScale, setAspectRatio, canvas, ctx } from './canvas.ts';\r\n\r\nimport Rectangle, { type RectangleOptions } from './sprites/Rectangle.ts';\r\nimport Square, { type SquareOptions } from './sprites/Square.ts';\r\nimport Oval, { type OvalOptions } from './sprites/Oval.ts';\r\nimport Circle, { type CircleOptions } from './sprites/Circle.ts';\r\nimport RegularPolygon, { type RegularPolygonOptions } from './sprites/RegularPolygon.ts';\r\nimport Pen, { type PenOptions } from './sprites/Pen.ts';\r\nimport Text, { type TextOptions, type CanvasTextAlign, type CanvasTextBaseline } from './sprites/Text.ts';\r\nimport ImageSprite, { type ImageSpriteOptions } from './sprites/ImageSprite.ts';\r\n\r\nconst TScratch = {\r\n // Main\r\n Engine,\r\n Sprite,\r\n\r\n // Sprites\r\n Rectangle,\r\n Square,\r\n Oval,\r\n Circle,\r\n RegularPolygon,\r\n Pen,\r\n Text,\r\n ImageSprite,\r\n\r\n // Canvas\r\n setScale,\r\n setAspectRatio,\r\n canvas,\r\n ctx\r\n};\r\n\r\nexport default TScratch;\r\nexport {\r\n // Main\r\n Engine,\r\n Sprite,\r\n\r\n // Sprites\r\n Rectangle,\r\n Square,\r\n Oval,\r\n Circle,\r\n RegularPolygon,\r\n Pen,\r\n Text,\r\n ImageSprite,\r\n\r\n // Options\r\n type SpriteOptions,\r\n type RectangleOptions,\r\n type SquareOptions,\r\n type OvalOptions,\r\n type CircleOptions,\r\n type RegularPolygonOptions,\r\n type PenOptions,\r\n type TextOptions,\r\n type ImageSpriteOptions,\r\n\r\n // Other types\r\n type CanvasTextAlign,\r\n type CanvasTextBaseline,\r\n \r\n // Canvas\r\n setScale,\r\n setAspectRatio,\r\n canvas,\r\n ctx\r\n};","export const canvas = document.getElementById('game-window') as HTMLCanvasElement || document.createElement('canvas'); // For testing\r\nexport const ctx = canvas.getContext('2d')!;\r\n\r\nexport const penCanvas = document.createElement('canvas');\r\nexport const penCtx = penCanvas.getContext('2d')!;\r\npenCanvas.id = 'pen-canvas';\r\n\r\nlet ratio: number = 16 / 9;\r\nlet scale: number;\r\n\r\nexport function setScale(newScale: number) {\r\n scale = newScale;\r\n\r\n canvas.width = ratio * scale;\r\n canvas.height = scale;\r\n\r\n penCanvas.width = ratio * scale;\r\n penCanvas.height = scale;\r\n}\r\n\r\nexport function setAspectRatio(newAspectRatio: number) {\r\n ratio = newAspectRatio;\r\n\r\n canvas.width = ratio * scale;\r\n canvas.height = scale;\r\n\r\n penCanvas.width = ratio * scale;\r\n penCanvas.height = scale;\r\n}\r\n\r\ncanvas.parentElement?.insertBefore(penCanvas, canvas);\r\n\r\nsetScale(500);","import Engine from './Engine.ts';\r\n\r\nexport interface BoundingBox {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface SpriteOptions {\r\n x?: number;\r\n y?: number;\r\n dir?: number;\r\n scene?: string;\r\n hidden?: boolean;\r\n layer?: number;\r\n}\r\n\r\nexport default abstract class Sprite {\r\n\r\n public x: number;\r\n public y: number;\r\n public dir: number;\r\n public scene: string;\r\n public hidden: boolean;\r\n public layer: number;\r\n\r\n private cachedPath: Path2D | null = null;\r\n private pathDirty: boolean = true;\r\n\r\n // Reusable collision detection canvas\r\n private static collisionCanvas: HTMLCanvasElement | null = null;\r\n private static collisionCtx: CanvasRenderingContext2D | null = null;\r\n\r\n // Rendering\r\n\r\n public abstract getBoundingBox(): BoundingBox;\r\n public abstract getPath(): Path2D;\r\n public abstract draw(stamping?: boolean): void;\r\n\r\n protected refresh() {\r\n Engine.init().refresh();\r\n }\r\n\r\n protected invalidatePath() {\r\n this.pathDirty = true;\r\n this.cachedPath = null;\r\n }\r\n\r\n protected getCachedPath(): Path2D {\r\n if (this.pathDirty || !this.cachedPath) {\r\n this.cachedPath = this.getPath();\r\n this.pathDirty = false;\r\n }\r\n return this.cachedPath;\r\n }\r\n\r\n constructor(options?: SpriteOptions) {\r\n this.x = options?.x ?? 0;\r\n this.y = options?.y ?? 0;\r\n this.dir = options?.dir ?? 0;\r\n this.scene = options?.scene ?? 'main';\r\n this.hidden = options?.hidden ?? false;\r\n this.layer = options?.layer ?? 0;\r\n Engine.init().addSprite(this);\r\n }\r\n\r\n // Sensing\r\n\r\n public touching(sprite: Sprite): boolean {\r\n\r\n // AABB (bounding boxes)\r\n const bBox1 = this.getBoundingBox();\r\n const bBox2 = sprite.getBoundingBox();\r\n\r\n const aabbOverlap =\r\n Math.abs(bBox1.x - bBox2.x) < (bBox1.width + bBox2.width) / 2 &&\r\n Math.abs(bBox1.y - bBox2.y) < (bBox1.height + bBox2.height) / 2;\r\n\r\n if (!aabbOverlap) return false;\r\n\r\n // Image data (pixel perfect)\r\n\r\n // Compute intersection bounding box\r\n const b1Left = bBox1.x - bBox1.width / 2;\r\n const b1Top = bBox1.y + bBox1.height / 2;\r\n const b1Right = bBox1.x + bBox1.width / 2;\r\n const b1Bottom = bBox1.y - bBox1.height / 2;\r\n\r\n const b2Left = bBox2.x - bBox2.width / 2;\r\n const b2Top = bBox2.y + bBox2.height / 2;\r\n const b2Right = bBox2.x + bBox2.width / 2;\r\n const b2Bottom = bBox2.y - bBox2.height / 2;\r\n\r\n const xMin = Math.max(b1Left, b2Left);\r\n const yMin = Math.min(b1Bottom, b2Bottom);\r\n const xMax = Math.min(b1Right, b2Right);\r\n const yMax = Math.max(b1Top, b2Top);\r\n\r\n const width = xMax - xMin;\r\n const height = yMax - yMin;\r\n\r\n if (width <= 1 || height <= 1) return false;\r\n\r\n // Reuse or create offscreen canvas for collision detection\r\n if (!Sprite.collisionCanvas) {\r\n Sprite.collisionCanvas = document.createElement('canvas');\r\n Sprite.collisionCtx = Sprite.collisionCanvas.getContext('2d', { willReadFrequently: true })!;\r\n }\r\n\r\n // Resize if needed\r\n if (Sprite.collisionCanvas.width < width || Sprite.collisionCanvas.height < height) {\r\n Sprite.collisionCanvas.width = Math.max(width, Sprite.collisionCanvas.width);\r\n Sprite.collisionCanvas.height = Math.max(height, Sprite.collisionCanvas.height);\r\n }\r\n\r\n const ctx = Sprite.collisionCtx!;\r\n ctx.clearRect(0, 0, width, height);\r\n\r\n // Draw first sprite\r\n ctx.save();\r\n ctx.translate(this.x - xMin, height - this.y + yMin);\r\n ctx.rotate(this.toRadians(this.dir));\r\n ctx.fillStyle = 'red';\r\n ctx.fill(this.getCachedPath());\r\n ctx.restore();\r\n const img1 = ctx.getImageData(0, 0, width, height).data;\r\n\r\n // Draw second sprite\r\n ctx.clearRect(0, 0, width, height);\r\n ctx.save();\r\n ctx.translate(sprite.x - xMin, height - sprite.y + yMin);\r\n ctx.rotate(this.toRadians(sprite.dir));\r\n ctx.fillStyle = 'blue';\r\n ctx.fill(sprite.getCachedPath());\r\n ctx.restore();\r\n const img2 = ctx.getImageData(0, 0, width, height).data;\r\n\r\n // Check for overlapping non-transparent pixels\r\n for (let i = 3; i < img1.length; i += 4) // alpha channel\r\n if (img1[i]! > 0 && img2[i]! > 0) return true;\r\n\r\n return false;\r\n }\r\n\r\n // Helpers\r\n\r\n protected toRadians(deg: number) {\r\n return deg * Math.PI / 180;\r\n }\r\n\r\n protected toDegrees(rad: number) {\r\n return rad * 180 / Math.PI;\r\n }\r\n\r\n // Methods\r\n\r\n // Motion\r\n public move(steps: number) {\r\n this.x += steps * Math.sin(this.toRadians(this.dir));\r\n this.y += steps * Math.cos(this.toRadians(this.dir));\r\n this.refresh();\r\n }\r\n\r\n public turn(deg: number) {\r\n this.dir += deg;\r\n this.refresh();\r\n }\r\n\r\n public point(dir: number) {\r\n this.dir = dir;\r\n this.refresh();\r\n }\r\n\r\n public pointTowards(x: number, y: number) {\r\n this.dir = 90 - this.toDegrees(Math.atan2(y, x));\r\n this.refresh();\r\n }\r\n\r\n public setX(x: number) {\r\n this.x = x;\r\n this.refresh();\r\n }\r\n\r\n public setY(y: number) {\r\n this.y = y;\r\n this.refresh();\r\n }\r\n\r\n public goTo(x: number, y: number) {\r\n this.x = x;\r\n this.y = y;\r\n this.refresh();\r\n }\r\n\r\n public changeX(dX: number) {\r\n this.x += dX;\r\n this.refresh();\r\n }\r\n\r\n public changeY(dY: number) {\r\n this.y += dY;\r\n this.refresh();\r\n }\r\n\r\n // Looks\r\n\r\n public show() {\r\n this.hidden = false;\r\n this.refresh();\r\n }\r\n\r\n public hide() {\r\n this.hidden = true;\r\n this.refresh();\r\n }\r\n\r\n public goToLayer(layer: number) {\r\n this.layer = layer;\r\n this.refresh();\r\n }\r\n\r\n public changeLayer(dL: number) {\r\n this.layer += dL;\r\n this.refresh();\r\n }\r\n}","import { canvas, ctx, penCanvas } from './canvas.ts';\r\nimport Sprite from './Sprite.ts';\r\n\r\ntype GameLoop = (() => any) | (() => Promise<any>);\r\n\r\ntype SceneMap = {\r\n [scene: string]: {\r\n sprites: Sprite[];\r\n loop: GameLoop | null;\r\n };\r\n};\r\n\r\nexport default class Engine {\r\n\r\n private static instance: Engine;\r\n\r\n private loopRunning: boolean = false;\r\n public gameLoop: GameLoop | null = null;\r\n\r\n public maxFPS: number = 24;\r\n public deltaTime: number = 1 / this.maxFPS;\r\n private lastFrame: number = performance.now();\r\n private refreshScheduled: boolean = false;\r\n private animationFrameId: number | null = null;\r\n\r\n public sounds: HTMLAudioElement[] = [];\r\n\r\n public mouseX: number = 0;\r\n public mouseY: number = 0;\r\n\r\n public mouseDown: boolean = false;\r\n public mouseClicked: boolean = false;\r\n\r\n private keysPressed: Set<string> = new Set<string>();\r\n\r\n public currentScene: string = 'main';\r\n public sceneMap: SceneMap = {};\r\n\r\n // Singleton initialization\r\n\r\n public static init() {\r\n if (!this.instance)\r\n this.instance = new Engine();\r\n\r\n return this.instance;\r\n }\r\n\r\n // Change the scene\r\n\r\n public changeScene(scene: string) {\r\n if (!this.sceneMap[scene])\r\n this.sceneMap[scene] = { sprites: [], loop: null };\r\n\r\n this.loopRunning = false;\r\n this.currentScene = scene;\r\n this.gameLoop = this.sceneMap[scene].loop;\r\n this.setMaxFramesPerSecond(this.maxFPS); // Update the interval function\r\n }\r\n\r\n // Loops\r\n\r\n public setLoop(scene: string, loop: GameLoop) {\r\n if (!this.sceneMap[scene]) {\r\n this.sceneMap[scene] = { sprites: [], loop };\r\n if (scene === this.currentScene)\r\n this.changeScene(scene);\r\n return;\r\n }\r\n\r\n this.sceneMap[scene].loop = loop;\r\n if (scene === this.currentScene)\r\n this.changeScene(scene);\r\n }\r\n\r\n public pauseLoop() {\r\n this.loopRunning = false;\r\n if (this.animationFrameId !== null) {\r\n cancelAnimationFrame(this.animationFrameId);\r\n this.animationFrameId = null;\r\n }\r\n }\r\n\r\n public resumeLoop() {\r\n this.loopRunning = true;\r\n void this.setMaxFramesPerSecond(this.maxFPS);\r\n }\r\n\r\n // Internal\r\n\r\n public addSprite(sprite: Sprite) {\r\n const { scene, layer } = sprite;\r\n\r\n if (!this.sceneMap[scene]) {\r\n this.sceneMap[scene] = { sprites: [sprite], loop: null };\r\n return;\r\n }\r\n\r\n let targetIndex = this.sceneMap[scene].sprites.findIndex(s => s.layer > layer);\r\n if (targetIndex === -1) {\r\n this.sceneMap[scene].sprites.push(sprite);\r\n return;\r\n }\r\n\r\n this.sceneMap[scene].sprites.splice(targetIndex, 0, sprite);\r\n this.refresh();\r\n }\r\n\r\n public removeSprite(sprite: Sprite) {\r\n const { scene } = sprite;\r\n\r\n if (!this.sceneMap[scene]) return;\r\n\r\n this.sceneMap[scene].sprites = this.sceneMap[scene].sprites.filter(s => s !== sprite);\r\n this.refresh();\r\n }\r\n\r\n public async setMaxFramesPerSecond(maxFPS: number) {\r\n this.maxFPS = maxFPS;\r\n\r\n let loop = this.gameLoop;\r\n if (!loop) return;\r\n\r\n // Cancel existing animation frame if any\r\n if (this.animationFrameId !== null) {\r\n cancelAnimationFrame(this.animationFrameId);\r\n this.animationFrameId = null;\r\n }\r\n\r\n this.loopRunning = true;\r\n const frameInterval = 1000 / maxFPS;\r\n let accumulator = 0;\r\n\r\n const tick = async (currentTime: number) => {\r\n if (!this.loopRunning) return;\r\n\r\n const deltaTime = currentTime - this.lastFrame;\r\n this.lastFrame = currentTime;\r\n accumulator += deltaTime;\r\n\r\n // Fixed timestep: only run loop when enough time has passed\r\n if (accumulator >= frameInterval) {\r\n this.deltaTime = accumulator / 1000;\r\n accumulator = accumulator % frameInterval;\r\n\r\n if (loop) await loop();\r\n }\r\n\r\n this.animationFrameId = requestAnimationFrame(tick);\r\n };\r\n\r\n this.lastFrame = performance.now();\r\n this.animationFrameId = requestAnimationFrame(tick);\r\n }\r\n\r\n public refresh() {\r\n if (this.refreshScheduled) return;\r\n this.refreshScheduled = true;\r\n\r\n requestAnimationFrame(() => {\r\n this.refreshScheduled = false;\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n const sprites = [\r\n ...(this.sceneMap[this.currentScene]?.sprites ?? []),\r\n ...(this.sceneMap['*']?.sprites ?? [])\r\n ];\r\n sprites.forEach(sprite => {\r\n if (!sprite.hidden)\r\n sprite.draw();\r\n });\r\n });\r\n }\r\n\r\n // Wait functions\r\n\r\n public async wait(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n\r\n public async waitUntil(conditionGetter: () => boolean): Promise<void> {\r\n return new Promise(resolve => {\r\n const check = () => {\r\n if (conditionGetter()) resolve();\r\n else setTimeout(check, 1000 / this.maxFPS);\r\n }\r\n check();\r\n });\r\n }\r\n\r\n // Events\r\n\r\n public hovering(sprite: Sprite) {\r\n const { mouseX, mouseY } = this;\r\n\r\n const canvasMouseX = mouseX + canvas.width / 2;\r\n const canvasMouseY = canvas.height / 2 - mouseY;\r\n\r\n // Mouse relative to sprite center\r\n const localX = canvasMouseX - (sprite.x + canvas.width / 2);\r\n const localY = canvasMouseY - (canvas.height / 2 - sprite.y);\r\n\r\n // Rotate mouse point by -dir to align with the path's local coordinates\r\n const angle = -this.toRadians(sprite.dir);\r\n const rotatedX = localX * Math.cos(angle) - localY * Math.sin(angle);\r\n const rotatedY = localX * Math.sin(angle) + localY * Math.cos(angle);\r\n\r\n return ctx.isPointInPath(sprite.getPath(), rotatedX, rotatedY);\r\n }\r\n\r\n public keyPressed(key: string) {\r\n return this.keysPressed.has(key);\r\n }\r\n\r\n // Sound\r\n\r\n public playSound(src: string) {\r\n const audio = new Audio(src);\r\n this.sounds.push(audio);\r\n\r\n audio.play();\r\n\r\n return audio;\r\n }\r\n\r\n public stopSound(sound: HTMLAudioElement) {\r\n sound.pause();\r\n sound.currentTime = 0;\r\n this.sounds = this.sounds.filter(s => s !== sound);\r\n }\r\n\r\n public stopAllSounds() {\r\n this.sounds.forEach(sound => {\r\n sound.pause();\r\n sound.currentTime = 0;\r\n });\r\n this.sounds = [];\r\n }\r\n\r\n // Math\r\n\r\n public pickRandom(min: number, max: number) {\r\n if (min > max)\r\n [min, max] = [max, min];\r\n return Math.floor(Math.random() * (max - min + 1) + min);\r\n }\r\n\r\n // Trigonometric functions\r\n public sin(deg: number) {\r\n return Math.sin(this.toRadians(deg));\r\n }\r\n\r\n public cos(deg: number) {\r\n return Math.cos(this.toRadians(deg));\r\n }\r\n\r\n public tan(deg: number) {\r\n return Math.tan(this.toRadians(deg));\r\n }\r\n\r\n public csc(deg: number) {\r\n return 1 / Math.sin(this.toRadians(deg));\r\n }\r\n\r\n public sec(deg: number) {\r\n return 1 / Math.cos(this.toRadians(deg));\r\n }\r\n\r\n public cot(deg: number) {\r\n return 1 / Math.tan(this.toRadians(deg));\r\n }\r\n\r\n // Inverse Trigonometric functions\r\n public asin(val: number) {\r\n return this.toDegrees(Math.asin(val));\r\n }\r\n\r\n public acos(val: number) {\r\n return this.toDegrees(Math.acos(val));\r\n }\r\n\r\n public acsc(val: number) {\r\n return this.toDegrees(Math.asin(1 / val));\r\n }\r\n\r\n public asec(val: number) {\r\n return this.toDegrees(Math.acos(1 / val));\r\n }\r\n\r\n // Helpers\r\n\r\n public toRadians(deg: number) {\r\n return deg * Math.PI / 180;\r\n }\r\n\r\n public toDegrees(rad: number) {\r\n return rad * 180 / Math.PI;\r\n }\r\n\r\n // Private constructor\r\n\r\n private constructor() {\r\n void this.setMaxFramesPerSecond(24);\r\n\r\n // Events\r\n\r\n // Mouse\r\n penCanvas.addEventListener('mousemove', e => {\r\n this.mouseX = e.clientX - penCanvas.offsetLeft - penCanvas.width / 2;\r\n this.mouseY = -(e.clientY - penCanvas.offsetTop - penCanvas.height / 2);\r\n });\r\n penCanvas.addEventListener('mousedown', e => {\r\n this.mouseDown = true;\r\n });\r\n penCanvas.addEventListener('mouseup', e => {\r\n this.mouseDown = false;\r\n });\r\n penCanvas.addEventListener('click', e => {\r\n this.mouseClicked = true;\r\n setTimeout(() => this.mouseClicked = false, 0);\r\n });\r\n\r\n // Keys\r\n addEventListener('keydown', e => {\r\n if (e.repeat) return;\r\n this.keysPressed.add(e.key);\r\n });\r\n\r\n addEventListener('keyup', e => {\r\n this.keysPressed.delete(e.key);\r\n });\r\n }\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { ctx, canvas, penCtx } from '../canvas.ts';\r\n\r\nexport interface RectangleOptions extends SpriteOptions {\r\n width?: number;\r\n height?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Rectangle extends Sprite {\r\n\r\n public discriminant = 'rectangle';\r\n\r\n public width: number;\r\n public height: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: Math.hypot(this.width, this.height),\r\n height: Math.hypot(this.width, this.height)\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.rect(\r\n -this.width / 2,\r\n -this.height / 2,\r\n this.width,\r\n this.height\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public setWidth(width: number) {\r\n this.width = width;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: RectangleOptions) {\r\n super(options);\r\n this.width = options?.width ?? 50;\r\n this.height = options?.height ?? 50;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { ctx, canvas, penCtx } from '../canvas.ts';\r\n\r\nexport interface SquareOptions extends SpriteOptions {\r\n sideLength?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Square extends Sprite {\r\n\r\n public discriminant = 'square';\r\n\r\n public sideLength: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: Math.hypot(this.sideLength, this.sideLength),\r\n height: Math.hypot(this.sideLength, this.sideLength)\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.rect(\r\n -this.sideLength / 2,\r\n -this.sideLength / 2,\r\n this.sideLength,\r\n this.sideLength\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public setSideLength(sideLength: number) {\r\n this.sideLength = sideLength;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: SquareOptions) {\r\n super(options);\r\n this.sideLength = options?.sideLength ?? 50;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface OvalOptions extends SpriteOptions {\r\n radX?: number;\r\n radY?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Oval extends Sprite {\r\n\r\n public discriminant = 'circle';\r\n\r\n public radX: number;\r\n public radY: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: Math.hypot(this.radX * 2, this.radY * 2),\r\n height: Math.hypot(this.radX * 2, this.radY * 2)\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.ellipse(\r\n 0, 0,\r\n this.radX,\r\n this.radY,\r\n 0, 0,\r\n Math.PI * 2\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public setRadX(radX: number) {\r\n this.radX = radX;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setRadY(radY: number) {\r\n this.radY = radY;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: OvalOptions) {\r\n super(options);\r\n this.radX = options?.radX ?? 25;\r\n this.radY = options?.radY ?? 25;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface CircleOptions extends SpriteOptions {\r\n radius?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Circle extends Sprite {\r\n\r\n public discriminant = 'circle';\r\n\r\n public radius: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.radius * 2,\r\n height: this.radius * 2\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.ellipse(\r\n 0, 0,\r\n this.radius,\r\n this.radius,\r\n 0, 0,\r\n Math.PI * 2\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: CircleOptions) {\r\n super(options);\r\n this.radius = options?.radius ?? 25;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface RegularPolygonOptions extends SpriteOptions {\r\n sides?: number;\r\n radius?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n}\r\n\r\nexport default class RegularPolygon extends Sprite {\r\n\r\n public discriminant = 'regularpolygon';\r\n\r\n public sides: number;\r\n public radius: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.radius * 2,\r\n height: this.radius * 2\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n const step = (2 * Math.PI) / this.sides;\r\n path.moveTo(this.radius, 0);\r\n for (let i = 1; i < this.sides; i++) {\r\n path.lineTo(this.radius * Math.cos(step * i), this.radius * Math.sin(step * i));\r\n }\r\n path.closePath();\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean) {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n\r\n c.translate(cX, cY);\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public setSides(sides: number) {\r\n this.sides = sides;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: RegularPolygonOptions) {\r\n super(options);\r\n this.sides = options?.sides ?? 5;\r\n this.radius = options?.radius ?? 50;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import { canvas, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface PenOptions extends SpriteOptions {\r\n drawing?: boolean;\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\nexport default class Pen extends Sprite {\r\n\r\n public discriminant = 'pen';\r\n\r\n public drawing: boolean;\r\n public size: number;\r\n public color: string;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.size,\r\n height: this.size\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n return new Path2D();\r\n }\r\n public draw() {}\r\n\r\n public up() {\r\n this.drawing = false;\r\n }\r\n\r\n public down() {\r\n this.drawing = true;\r\n }\r\n\r\n public stamp(sprite: Sprite) {\r\n sprite.draw(true);\r\n }\r\n\r\n public eraseAll() {\r\n penCtx.clearRect(0, 0, canvas.width, canvas.height);\r\n }\r\n\r\n public dot() {\r\n penCtx.fillStyle = this.color;\r\n penCtx.fillRect(\r\n this.x - this.size / 2 + canvas.width / 2,\r\n -this.y - this.size / 2 + canvas.height / 2,\r\n this.size,\r\n this.size\r\n );\r\n }\r\n\r\n private drawLine(lastX: number, lastY: number) {\r\n penCtx.beginPath();\r\n\r\n penCtx.moveTo(lastX + canvas.width / 2, -lastY + canvas.height / 2);\r\n penCtx.lineTo(this.x + canvas.width / 2, -this.y + canvas.height / 2);\r\n\r\n penCtx.lineWidth = this.size;\r\n penCtx.strokeStyle = this.color;\r\n penCtx.stroke();\r\n }\r\n\r\n // Overriding methods to include drawing\r\n\r\n public override move(steps: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.x += steps * Math.sin(this.toRadians(this.dir));\r\n this.y += steps * Math.cos(this.toRadians(this.dir));\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override setX(x: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.x = x;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override setY(y: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.y = y;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override goTo(x: number, y: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.x = x;\r\n this.y = y;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override changeX(dX: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.x += dX;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override changeY(dY: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.y += dY;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n // Constructor\r\n\r\n constructor(options?: PenOptions) {\r\n super(options);\r\n this.drawing = options?.drawing ?? false;\r\n this.size = options?.size ?? 5;\r\n this.color = options?.color ?? 'black';\r\n }\r\n\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport type CanvasTextAlign =\r\n | 'left'\r\n | 'right'\r\n | 'center'\r\n | 'start'\r\n | 'end';\r\n\r\nexport type CanvasTextBaseline =\r\n | 'top'\r\n | 'hanging'\r\n | 'middle'\r\n | 'alphabetic'\r\n | 'ideographic'\r\n | 'bottom';\r\n\r\nexport interface TextOptions extends SpriteOptions {\r\n content?: string;\r\n color?: string;\r\n fontFamily?: string;\r\n fontSize?: number;\r\n align?: CanvasTextAlign;\r\n baseline?: CanvasTextBaseline;\r\n}\r\n\r\nexport default class Text extends Sprite {\r\n\r\n public discriminant = 'text';\r\n\r\n public content: string;\r\n public color: string;\r\n public fontFamily: string;\r\n public fontSize: number;\r\n public align: CanvasTextAlign;\r\n public baseline: CanvasTextBaseline;\r\n\r\n private font: string;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n const metrics = ctx.measureText(this.content);\r\n const width = metrics.width;\r\n const height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width, height\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n ctx.save();\r\n \r\n ctx.font = this.font;\r\n\r\n const metrics = ctx.measureText(this.content);\r\n const width = metrics.width;\r\n const height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n\r\n ctx.restore();\r\n\r\n path.rect(-width / 2, -height / 2, width, height);\r\n\r\n return path\r\n }\r\n\r\n public draw(stamping?: boolean) {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n c.font = this.font;\r\n c.fillStyle = this.color;\r\n c.textAlign = this.align;\r\n c.textBaseline = this.baseline;\r\n\r\n c.fillText(this.content, 0, 0);\r\n\r\n c.restore();\r\n }\r\n\r\n // Methods\r\n\r\n public setContent(content: string) {\r\n this.content = content;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n public setFontSize(fontSize: number) {\r\n this.fontSize = fontSize;\r\n this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setFontFamily(fontFamily: string) {\r\n this.fontFamily = fontFamily;\r\n this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setAlign(align: CanvasTextAlign) {\r\n this.align = align;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setBaseline(baseline: CanvasTextBaseline) {\r\n this.baseline = baseline;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n // Constructor\r\n\r\n constructor(options?: TextOptions) {\r\n super(options);\r\n\r\n this.content = options?.content ?? '';\r\n this.color = options?.color ?? 'black';\r\n this.fontFamily = options?.fontFamily ?? 'Arial';\r\n this.fontSize = options?.fontSize ?? 16;\r\n this.align = options?.align ?? 'center';\r\n this.baseline = options?.baseline ?? 'middle';\r\n\r\n this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n\r\n this.draw();\r\n }\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface ImageSpriteOptions extends SpriteOptions {\r\n src?: string;\r\n width: number;\r\n height: number;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class ImageSprite extends Sprite {\r\n\r\n public discriminant = 'imagesprite';\r\n\r\n public src: string;\r\n public width: number;\r\n public height: number;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n protected img: HTMLImageElement;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.width,\r\n height: this.height\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.rect(\r\n -this.width / 2,\r\n -this.height / 2,\r\n this.width,\r\n this.height\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean) {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.drawImage(\r\n this.img,\r\n 0, 0,\r\n this.img.width,\r\n this.img.height,\r\n -this.width / 2,\r\n -this.height / 2,\r\n this.width, this.height\r\n );\r\n if (this.outlineWidth)\r\n c.stroke(this.getCachedPath());\r\n\r\n c.restore();\r\n }\r\n\r\n // Methods\r\n\r\n public setSrc(src: string) {\r\n this.src = src;\r\n this.refresh();\r\n }\r\n\r\n public setWidth(width: number) {\r\n this.width = width;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n // Constructor\r\n\r\n constructor(options?: ImageSpriteOptions) {\r\n super(options);\r\n\r\n this.src = options?.src ?? '';\r\n this.img = new Image();\r\n this.img.src = this.src;\r\n\r\n this.width = options?.width ?? this.img.width;\r\n this.height = options?.height ?? this.img.height;\r\n\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n \r\n this.draw();\r\n }\r\n}"],"mappings":"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","names":["index_exports","__export","Circle","Engine","ImageSprite","Oval","Pen","Rectangle","RegularPolygon","Sprite","Square","Text","canvas","ctx","index_default","setAspectRatio","setScale","__toCommonJS","canvas","ctx","penCanvas","penCtx","ratio","scale","setScale","newScale","setAspectRatio","newAspectRatio","Sprite","_Sprite","Engine","options","sprite","bBox1","bBox2","b1Left","b1Top","b1Right","b1Bottom","b2Left","b2Top","b2Right","b2Bottom","xMin","yMin","xMax","yMax","width","height","ctx","img1","img2","i","deg","rad","steps","dir","x","y","dX","dY","layer","dL","Engine","_Engine","scene","loop","sprite","layer","targetIndex","s","maxFPS","frameInterval","accumulator","tick","currentTime","deltaTime","ctx","canvas","ms","resolve","conditionGetter","check","mouseX","mouseY","canvasMouseX","canvasMouseY","localX","localY","angle","rotatedX","rotatedY","key","src","audio","sound","min","max","deg","val","rad","penCanvas","e","Rectangle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","width","height","color","options","Square","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","sideLength","color","options","Oval","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radX","radY","color","options","Circle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radius","color","options","RegularPolygon","Sprite","path","step","i","stamping","c","penCtx","ctx","cX","canvas","cY","sides","radius","color","options","Pen","Sprite","sprite","penCtx","canvas","lastX","lastY","steps","x","y","dX","dY","options","Text","Sprite","metrics","ctx","width","height","path","stamping","c","penCtx","cX","canvas","cY","content","color","fontSize","fontFamily","align","baseline","options","ImageSprite","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","src","width","height","options","TScratch","Engine","Sprite","Rectangle","Square","Oval","Circle","RegularPolygon","Pen","Text","ImageSprite","setScale","setAspectRatio","canvas","ctx","index_default"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/canvas.ts","../src/Sprite.ts","../src/Engine.ts","../src/sprites/Rectangle.ts","../src/sprites/Square.ts","../src/sprites/Oval.ts","../src/sprites/Circle.ts","../src/sprites/Arc.ts","../src/sprites/RegularPolygon.ts","../src/sprites/CustomPolygon.ts","../src/sprites/Pen.ts","../src/sprites/Text.ts","../src/sprites/ImageSprite.ts"],"sourcesContent":["import Engine from './Engine.ts';\r\nimport Sprite, { type SpriteOptions } from './Sprite.ts';\r\nimport { setScale, setAspectRatio, canvas, ctx } from './canvas.ts';\r\n\r\nimport Rectangle, { type RectangleOptions } from './sprites/Rectangle.ts';\r\nimport Square, { type SquareOptions } from './sprites/Square.ts';\r\nimport Oval, { type OvalOptions } from './sprites/Oval.ts';\r\nimport Circle, { type CircleOptions } from './sprites/Circle.ts';\r\nimport Arc, { type ArcOptions } from './sprites/Arc.ts';\r\nimport RegularPolygon, { type RegularPolygonOptions } from './sprites/RegularPolygon.ts';\r\nimport CustomPolygon, { type CustomPolygonOptions } from './sprites/CustomPolygon.ts';\r\nimport Pen, { type PenOptions } from './sprites/Pen.ts';\r\nimport Text, { type TextOptions, type CanvasTextAlign, type CanvasTextBaseline } from './sprites/Text.ts';\r\nimport ImageSprite, { type ImageSpriteOptions } from './sprites/ImageSprite.ts';\r\n\r\nimport type { Vec2, Vec3, Vec4 } from './types/Vectors.ts';\r\n\r\nconst TScratch = {\r\n // Main\r\n Engine,\r\n Sprite,\r\n\r\n // Sprites\r\n Rectangle,\r\n Square,\r\n Oval,\r\n Circle,\r\n Arc,\r\n RegularPolygon,\r\n CustomPolygon,\r\n Pen,\r\n Text,\r\n ImageSprite,\r\n\r\n // Canvas\r\n setScale,\r\n setAspectRatio,\r\n canvas,\r\n ctx\r\n};\r\n\r\nexport default TScratch;\r\nexport {\r\n // Main\r\n Engine,\r\n Sprite,\r\n\r\n // Sprites\r\n Rectangle,\r\n Square,\r\n Oval,\r\n Circle,\r\n Arc,\r\n RegularPolygon,\r\n CustomPolygon,\r\n Pen,\r\n Text,\r\n ImageSprite,\r\n\r\n // Options\r\n type SpriteOptions,\r\n type RectangleOptions,\r\n type SquareOptions,\r\n type OvalOptions,\r\n type CircleOptions,\r\n type ArcOptions,\r\n type RegularPolygonOptions,\r\n type CustomPolygonOptions,\r\n type PenOptions,\r\n type TextOptions,\r\n type ImageSpriteOptions,\r\n\r\n // Other types\r\n type CanvasTextAlign,\r\n type CanvasTextBaseline,\r\n type Vec2,\r\n type Vec3,\r\n type Vec4,\r\n \r\n // Canvas\r\n setScale,\r\n setAspectRatio,\r\n canvas,\r\n ctx\r\n};","export const canvas = document.getElementById('game-window') as HTMLCanvasElement || document.createElement('canvas'); // For testing\r\nexport const ctx = canvas.getContext('2d')!;\r\n\r\nexport const penCanvas = document.createElement('canvas');\r\nexport const penCtx = penCanvas.getContext('2d')!;\r\npenCanvas.id = 'pen-canvas';\r\n\r\nlet ratio: number = 16 / 9;\r\nlet scale: number;\r\n\r\nexport function setScale(newScale: number) {\r\n scale = newScale;\r\n\r\n canvas.width = ratio * scale;\r\n canvas.height = scale;\r\n\r\n penCanvas.width = ratio * scale;\r\n penCanvas.height = scale;\r\n}\r\n\r\nexport function setAspectRatio(newAspectRatio: number) {\r\n ratio = newAspectRatio;\r\n\r\n canvas.width = ratio * scale;\r\n canvas.height = scale;\r\n\r\n penCanvas.width = ratio * scale;\r\n penCanvas.height = scale;\r\n}\r\n\r\ncanvas.parentElement?.insertBefore(penCanvas, canvas);\r\n\r\nsetScale(500);","import Engine from './Engine.ts';\r\n\r\nexport interface BoundingBox {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface SpriteOptions {\r\n x: number;\r\n y: number;\r\n dir: number;\r\n scene: string;\r\n hidden: boolean;\r\n layer: number;\r\n}\r\n\r\nexport default abstract class Sprite {\r\n\r\n public x!: number;\r\n public y!: number;\r\n public dir!: number;\r\n public scene!: string;\r\n public hidden!: boolean;\r\n public layer!: number;\r\n\r\n private cachedPath: Path2D | null = null;\r\n private pathDirty: boolean = true;\r\n\r\n // Reusable collision detection canvas\r\n private static collisionCanvas: HTMLCanvasElement | null = null;\r\n private static collisionCtx: CanvasRenderingContext2D | null = null;\r\n\r\n // Rendering\r\n\r\n public abstract getBoundingBox(): BoundingBox;\r\n public abstract getPath(): Path2D;\r\n public abstract draw(stamping?: boolean): void;\r\n protected abstract create(options?: SpriteOptions): this;\r\n\r\n protected refresh() {\r\n Engine.init().refresh();\r\n }\r\n\r\n protected invalidatePath() {\r\n this.pathDirty = true;\r\n this.cachedPath = null;\r\n }\r\n\r\n protected getCachedPath(): Path2D {\r\n if (this.pathDirty || !this.cachedPath) {\r\n this.cachedPath = this.getPath();\r\n this.pathDirty = false;\r\n }\r\n return this.cachedPath;\r\n }\r\n\r\n constructor(options?: SpriteOptions) {\r\n Object.assign(this, options);\r\n Engine.init().addSprite(this);\r\n }\r\n\r\n public clone(options?: SpriteOptions): this {\r\n return this.create({\r\n x: this.x,\r\n y: this.y,\r\n dir: this.dir,\r\n scene: this.scene,\r\n layer: this.layer,\r\n hidden: this.hidden,\r\n ...options\r\n });\r\n }\r\n\r\n // Sensing\r\n\r\n public touching(sprite: Sprite): boolean {\r\n\r\n // Return if hidden\r\n if (this.hidden || sprite.hidden) return false;\r\n\r\n // AABB (bounding boxes)\r\n const bBox1 = this.getBoundingBox();\r\n const bBox2 = sprite.getBoundingBox();\r\n\r\n const aabbOverlap =\r\n Math.abs(bBox1.x - bBox2.x) < (bBox1.width + bBox2.width) / 2 &&\r\n Math.abs(bBox1.y - bBox2.y) < (bBox1.height + bBox2.height) / 2;\r\n\r\n if (!aabbOverlap) return false;\r\n\r\n // Image data (pixel perfect)\r\n\r\n // Compute intersection bounding box\r\n const b1Left = bBox1.x - bBox1.width / 2;\r\n const b1Top = bBox1.y + bBox1.height / 2;\r\n const b1Right = bBox1.x + bBox1.width / 2;\r\n const b1Bottom = bBox1.y - bBox1.height / 2;\r\n\r\n const b2Left = bBox2.x - bBox2.width / 2;\r\n const b2Top = bBox2.y + bBox2.height / 2;\r\n const b2Right = bBox2.x + bBox2.width / 2;\r\n const b2Bottom = bBox2.y - bBox2.height / 2;\r\n\r\n const xMin = Math.max(b1Left, b2Left);\r\n const yMin = Math.min(b1Bottom, b2Bottom);\r\n const xMax = Math.min(b1Right, b2Right);\r\n const yMax = Math.max(b1Top, b2Top);\r\n\r\n const width = xMax - xMin;\r\n const height = yMax - yMin;\r\n\r\n if (width <= 1 || height <= 1) return false;\r\n\r\n // Reuse or create offscreen canvas for collision detection\r\n if (!Sprite.collisionCanvas) {\r\n Sprite.collisionCanvas = document.createElement('canvas');\r\n Sprite.collisionCtx = Sprite.collisionCanvas.getContext('2d', { willReadFrequently: true })!;\r\n }\r\n\r\n // Resize if needed\r\n if (Sprite.collisionCanvas.width < width || Sprite.collisionCanvas.height < height) {\r\n Sprite.collisionCanvas.width = Math.max(width, Sprite.collisionCanvas.width);\r\n Sprite.collisionCanvas.height = Math.max(height, Sprite.collisionCanvas.height);\r\n }\r\n\r\n const ctx = Sprite.collisionCtx!;\r\n ctx.clearRect(0, 0, width, height);\r\n\r\n // Draw first sprite\r\n ctx.save();\r\n ctx.translate(this.x - xMin, height - this.y + yMin);\r\n ctx.rotate(this.toRadians(this.dir));\r\n ctx.fillStyle = 'red';\r\n ctx.fill(this.getCachedPath());\r\n ctx.restore();\r\n const img1 = ctx.getImageData(0, 0, width, height).data;\r\n\r\n // Draw second sprite\r\n ctx.clearRect(0, 0, width, height);\r\n ctx.save();\r\n ctx.translate(sprite.x - xMin, height - sprite.y + yMin);\r\n ctx.rotate(this.toRadians(sprite.dir));\r\n ctx.fillStyle = 'blue';\r\n ctx.fill(sprite.getCachedPath());\r\n ctx.restore();\r\n const img2 = ctx.getImageData(0, 0, width, height).data;\r\n\r\n // Check for overlapping non-transparent pixels\r\n for (let i = 3; i < img1.length; i += 4) // alpha channel\r\n if (img1[i]! > 0 && img2[i]! > 0) return true;\r\n\r\n return false;\r\n }\r\n\r\n // Helpers\r\n\r\n protected toRadians(deg: number) {\r\n return deg * Math.PI / 180;\r\n }\r\n\r\n protected toDegrees(rad: number) {\r\n return rad * 180 / Math.PI;\r\n }\r\n\r\n // Methods\r\n\r\n // Motion\r\n public move(steps: number) {\r\n this.x += steps * Math.sin(this.toRadians(this.dir));\r\n this.y += steps * Math.cos(this.toRadians(this.dir));\r\n this.refresh();\r\n }\r\n\r\n public turn(deg: number) {\r\n this.dir += deg;\r\n this.refresh();\r\n }\r\n\r\n public point(dir: number) {\r\n this.dir = dir;\r\n this.refresh();\r\n }\r\n\r\n public pointTowards(x: number, y: number) {\r\n this.dir = 90 - this.toDegrees(Math.atan2(y, x));\r\n this.refresh();\r\n }\r\n\r\n public setX(x: number) {\r\n this.x = x;\r\n this.refresh();\r\n }\r\n\r\n public setY(y: number) {\r\n this.y = y;\r\n this.refresh();\r\n }\r\n\r\n public goTo(x: number, y: number) {\r\n this.x = x;\r\n this.y = y;\r\n this.refresh();\r\n }\r\n\r\n public changeX(dX: number) {\r\n this.x += dX;\r\n this.refresh();\r\n }\r\n\r\n public changeY(dY: number) {\r\n this.y += dY;\r\n this.refresh();\r\n }\r\n\r\n // Looks\r\n\r\n public show() {\r\n this.hidden = false;\r\n this.refresh();\r\n }\r\n\r\n public hide() {\r\n this.hidden = true;\r\n this.refresh();\r\n }\r\n\r\n public goToLayer(layer: number) {\r\n this.layer = layer;\r\n this.refresh();\r\n }\r\n\r\n public changeLayer(dL: number) {\r\n this.layer += dL;\r\n this.refresh();\r\n }\r\n}","import { canvas, ctx, penCanvas } from './canvas.ts';\r\nimport Sprite from './Sprite.ts';\r\nimport type { Vec2, Vec3, Vec4 } from './types/Vectors.ts';\r\n\r\ntype GameLoop = (() => any) | (() => Promise<any>);\r\n\r\ntype SceneMap = Map<string, {\r\n sprites: Sprite[];\r\n loop: GameLoop | null;\r\n}>\r\n\r\nexport default class Engine {\r\n\r\n private static instance: Engine;\r\n\r\n private loopRunning: boolean = false;\r\n public gameLoop: GameLoop | null = null;\r\n\r\n public maxFPS: number = 24;\r\n public deltaTime: number = 1 / this.maxFPS;\r\n private lastFrame: number = performance.now();\r\n private refreshScheduled: boolean = false;\r\n private animationFrameId: number | null = null;\r\n\r\n public sounds: HTMLAudioElement[] = [];\r\n\r\n public mouseX: number = 0;\r\n public mouseY: number = 0;\r\n\r\n public mouseDown: boolean = false;\r\n public mouseClicked: boolean = false;\r\n\r\n private keysPressed: Set<string> = new Set<string>();\r\n\r\n public currentScene: string = 'main';\r\n public sceneMap: SceneMap = new Map();\r\n\r\n // Singleton initialization\r\n\r\n public static init() {\r\n if (!this.instance)\r\n this.instance = new Engine();\r\n\r\n return this.instance;\r\n }\r\n\r\n // Change the scene\r\n\r\n public changeScene(scene: string) {\r\n if (!this.sceneMap.get(scene))\r\n this.sceneMap.set(scene, { sprites: [], loop: null });\r\n\r\n this.loopRunning = false;\r\n this.currentScene = scene;\r\n this.gameLoop = this.sceneMap.get(scene)!.loop;\r\n this.setMaxFramesPerSecond(this.maxFPS); // Update the interval function\r\n }\r\n\r\n // Loops\r\n\r\n public setLoop(scene: string, loop: GameLoop) {\r\n if (!this.sceneMap.get(scene)) {\r\n this.sceneMap.set(scene, { sprites: [], loop });\r\n if (scene === this.currentScene)\r\n this.changeScene(scene);\r\n return;\r\n }\r\n\r\n this.sceneMap.get(scene)!.loop = loop;\r\n if (scene === this.currentScene)\r\n this.changeScene(scene);\r\n }\r\n\r\n public pauseLoop() {\r\n this.loopRunning = false;\r\n if (this.animationFrameId !== null) {\r\n cancelAnimationFrame(this.animationFrameId);\r\n this.animationFrameId = null;\r\n }\r\n }\r\n\r\n public resumeLoop() {\r\n this.loopRunning = true;\r\n void this.setMaxFramesPerSecond(this.maxFPS);\r\n }\r\n\r\n // Internal\r\n\r\n public addSprite(sprite: Sprite) {\r\n const { scene, layer } = sprite;\r\n\r\n if (!this.sceneMap.get(scene)) {\r\n this.sceneMap.set(scene, { sprites: [sprite], loop: null });\r\n return;\r\n }\r\n\r\n let targetIndex = this.sceneMap.get(scene)!.sprites.findIndex(s => s.layer > layer);\r\n if (targetIndex === -1) {\r\n this.sceneMap.get(scene)!.sprites.push(sprite);\r\n return;\r\n }\r\n\r\n this.sceneMap.get(scene)!.sprites.splice(targetIndex, 0, sprite);\r\n this.refresh();\r\n }\r\n\r\n public removeSprite(sprite: Sprite) {\r\n const { scene } = sprite;\r\n\r\n if (!this.sceneMap.get(scene)) return;\r\n\r\n this.sceneMap.get(scene)!.sprites = this.sceneMap.get(scene)!.sprites.filter(s => s !== sprite);\r\n this.refresh();\r\n }\r\n\r\n public async setMaxFramesPerSecond(maxFPS: number) {\r\n this.maxFPS = maxFPS;\r\n\r\n let loop = this.gameLoop;\r\n if (!loop) return;\r\n\r\n // Cancel existing animation frame if any\r\n if (this.animationFrameId !== null) {\r\n cancelAnimationFrame(this.animationFrameId);\r\n this.animationFrameId = null;\r\n }\r\n\r\n this.loopRunning = true;\r\n const frameInterval = 1000 / maxFPS;\r\n let accumulator = 0;\r\n\r\n const tick = async (currentTime: number) => {\r\n if (!this.loopRunning) return;\r\n\r\n const deltaTime = currentTime - this.lastFrame;\r\n this.lastFrame = currentTime;\r\n accumulator += deltaTime;\r\n\r\n // Fixed timestep: only run loop when enough time has passed\r\n if (accumulator >= frameInterval) {\r\n this.deltaTime = accumulator / 1000;\r\n accumulator = accumulator % frameInterval;\r\n\r\n if (loop) await loop();\r\n }\r\n\r\n this.animationFrameId = requestAnimationFrame(tick);\r\n };\r\n\r\n this.lastFrame = performance.now();\r\n this.animationFrameId = requestAnimationFrame(tick);\r\n }\r\n\r\n public refresh() {\r\n if (this.refreshScheduled) return;\r\n this.refreshScheduled = true;\r\n\r\n requestAnimationFrame(() => {\r\n this.refreshScheduled = false;\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n const sprites = [\r\n ...this.sceneMap.get(this.currentScene)!.sprites,\r\n ...this.sceneMap.get('*')!.sprites\r\n ];\r\n sprites.forEach(sprite => {\r\n if (!sprite.hidden)\r\n sprite.draw();\r\n });\r\n });\r\n }\r\n\r\n // Wait functions\r\n\r\n public async wait(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n\r\n public async waitUntil(conditionGetter: () => boolean): Promise<void> {\r\n return new Promise(resolve => {\r\n const check = () => {\r\n if (conditionGetter()) resolve();\r\n else setTimeout(check, 1000 / this.maxFPS);\r\n }\r\n check();\r\n });\r\n }\r\n\r\n // Events\r\n\r\n public hovering(sprite: Sprite) {\r\n const { mouseX, mouseY } = this;\r\n\r\n const canvasMouseX = mouseX + canvas.width / 2;\r\n const canvasMouseY = canvas.height / 2 - mouseY;\r\n\r\n // Mouse relative to sprite center\r\n const localX = canvasMouseX - (sprite.x + canvas.width / 2);\r\n const localY = canvasMouseY - (canvas.height / 2 - sprite.y);\r\n\r\n // Rotate mouse point by -dir to align with the path's local coordinates\r\n const angle = -this.toRadians(sprite.dir);\r\n const rotatedX = localX * Math.cos(angle) - localY * Math.sin(angle);\r\n const rotatedY = localX * Math.sin(angle) + localY * Math.cos(angle);\r\n\r\n return ctx.isPointInPath(sprite.getPath(), rotatedX, rotatedY);\r\n }\r\n\r\n public keyPressed(key: string) {\r\n return this.keysPressed.has(key);\r\n }\r\n\r\n // Sound\r\n\r\n public playSound(src: string) {\r\n const audio = new Audio(src);\r\n this.sounds.push(audio);\r\n\r\n audio.play();\r\n\r\n return audio;\r\n }\r\n\r\n public stopSound(sound: HTMLAudioElement) {\r\n sound.pause();\r\n sound.currentTime = 0;\r\n this.sounds = this.sounds.filter(s => s !== sound);\r\n }\r\n\r\n public stopAllSounds() {\r\n this.sounds.forEach(sound => {\r\n sound.pause();\r\n sound.currentTime = 0;\r\n });\r\n this.sounds = [];\r\n }\r\n\r\n // Math\r\n\r\n public pickRandom(min: number, max: number) {\r\n if (min > max)\r\n [min, max] = [max, min];\r\n return Math.floor(Math.random() * (max - min + 1) + min);\r\n }\r\n\r\n public dotProduct(vectors: [Vec2, Vec2] | [Vec3, Vec3] | [Vec4, Vec4]) {\r\n const [a, b] = vectors;\r\n\r\n switch (a.length) {\r\n case 2: return a[0] * b[0] + a[1] * b[1];\r\n case 3: return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]!;\r\n case 4: return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]! + a[3] * b[3]!; // TypeScript doesn't narrow down the types on b\r\n }\r\n }\r\n\r\n // Trigonometric functions\r\n public sin(deg: number) {\r\n return Math.sin(this.toRadians(deg));\r\n }\r\n\r\n public cos(deg: number) {\r\n return Math.cos(this.toRadians(deg));\r\n }\r\n\r\n public tan(deg: number) {\r\n return Math.tan(this.toRadians(deg));\r\n }\r\n\r\n public csc(deg: number) {\r\n return 1 / Math.sin(this.toRadians(deg));\r\n }\r\n\r\n public sec(deg: number) {\r\n return 1 / Math.cos(this.toRadians(deg));\r\n }\r\n\r\n public cot(deg: number) {\r\n return 1 / Math.tan(this.toRadians(deg));\r\n }\r\n\r\n // Inverse Trigonometric functions\r\n public asin(val: number) {\r\n return this.toDegrees(Math.asin(val));\r\n }\r\n\r\n public acos(val: number) {\r\n return this.toDegrees(Math.acos(val));\r\n }\r\n\r\n public acsc(val: number) {\r\n return this.toDegrees(Math.asin(1 / val));\r\n }\r\n\r\n public asec(val: number) {\r\n return this.toDegrees(Math.acos(1 / val));\r\n }\r\n\r\n // Helpers\r\n\r\n public toRadians(deg: number) {\r\n return deg * Math.PI / 180;\r\n }\r\n\r\n public toDegrees(rad: number) {\r\n return rad * 180 / Math.PI;\r\n }\r\n\r\n // Private constructor\r\n\r\n private constructor() {\r\n void this.setMaxFramesPerSecond(24);\r\n\r\n // Events\r\n\r\n // Mouse\r\n penCanvas.addEventListener('mousemove', e => {\r\n this.mouseX = e.clientX - penCanvas.offsetLeft - penCanvas.width / 2;\r\n this.mouseY = -(e.clientY - penCanvas.offsetTop - penCanvas.height / 2);\r\n });\r\n penCanvas.addEventListener('mousedown', e => {\r\n this.mouseDown = true;\r\n });\r\n penCanvas.addEventListener('mouseup', e => {\r\n this.mouseDown = false;\r\n });\r\n penCanvas.addEventListener('click', e => {\r\n this.mouseClicked = true;\r\n setTimeout(() => this.mouseClicked = false, 0);\r\n });\r\n\r\n // Keys\r\n addEventListener('keydown', e => {\r\n if (e.repeat) return;\r\n this.keysPressed.add(e.key);\r\n });\r\n\r\n addEventListener('keyup', e => {\r\n this.keysPressed.delete(e.key);\r\n });\r\n }\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { ctx, canvas, penCtx } from '../canvas.ts';\r\n\r\nexport interface RectangleOptions extends SpriteOptions {\r\n width?: number;\r\n height?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Rectangle extends Sprite {\r\n\r\n public discriminant = 'rectangle';\r\n\r\n public width: number;\r\n public height: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: Math.hypot(this.width, this.height),\r\n height: Math.hypot(this.width, this.height)\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.rect(\r\n -this.width / 2,\r\n -this.height / 2,\r\n this.width,\r\n this.height\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: RectangleOptions): this {\r\n return new Rectangle(options) as this;\r\n }\r\n\r\n public setWidth(width: number) {\r\n this.width = width;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: RectangleOptions) {\r\n super(options);\r\n this.width = options?.width ?? 50;\r\n this.height = options?.height ?? 50;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { ctx, canvas, penCtx } from '../canvas.ts';\r\n\r\nexport interface SquareOptions extends SpriteOptions {\r\n sideLength?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Square extends Sprite {\r\n\r\n public discriminant = 'square';\r\n\r\n public sideLength: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: Math.hypot(this.sideLength, this.sideLength),\r\n height: Math.hypot(this.sideLength, this.sideLength)\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.rect(\r\n -this.sideLength / 2,\r\n -this.sideLength / 2,\r\n this.sideLength,\r\n this.sideLength\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: SquareOptions): this {\r\n return new Square(options) as this;\r\n }\r\n\r\n public setSideLength(sideLength: number) {\r\n this.sideLength = sideLength;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: SquareOptions) {\r\n super(options);\r\n this.sideLength = options?.sideLength ?? 50;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface OvalOptions extends SpriteOptions {\r\n radX?: number;\r\n radY?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Oval extends Sprite {\r\n\r\n public discriminant = 'oval';\r\n\r\n public radX: number;\r\n public radY: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: Math.hypot(this.radX * 2, this.radY * 2),\r\n height: Math.hypot(this.radX * 2, this.radY * 2)\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.ellipse(\r\n 0, 0,\r\n this.radX,\r\n this.radY,\r\n 0, 0,\r\n Math.PI * 2\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: OvalOptions): this {\r\n return new Oval(options) as this;\r\n }\r\n\r\n public setRadX(radX: number) {\r\n this.radX = radX;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setRadY(radY: number) {\r\n this.radY = radY;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: OvalOptions) {\r\n super(options);\r\n this.radX = options?.radX ?? 25;\r\n this.radY = options?.radY ?? 25;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface CircleOptions extends SpriteOptions {\r\n radius?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Circle extends Sprite {\r\n\r\n public discriminant = 'circle';\r\n\r\n public radius: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.radius * 2,\r\n height: this.radius * 2\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.ellipse(\r\n 0, 0,\r\n this.radius,\r\n this.radius,\r\n 0, 0,\r\n Math.PI * 2\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: CircleOptions): this {\r\n return new Circle(options) as this;\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: CircleOptions) {\r\n super(options);\r\n this.radius = options?.radius ?? 25;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface ArcOptions extends SpriteOptions {\r\n radius?: number;\r\n angle?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class Arc extends Sprite {\r\n\r\n public discriminant = 'arc';\r\n\r\n public radius: number;\r\n public angle: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.radius * 2,\r\n height: this.radius * 2\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.arc(\r\n 0, 0,\r\n this.radius,\r\n this.toRadians(this.angle / 2 - 90),\r\n this.toRadians(-this.angle / 2 - 90)\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: ArcOptions): this {\r\n return new Arc(options) as this;\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setAngle(angle: number) {\r\n this.angle = angle;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: ArcOptions) {\r\n super(options);\r\n\r\n this.radius = options?.radius ?? 25;\r\n this.angle = options?.angle ?? 270;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n\r\n this.draw();\r\n }\r\n\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface RegularPolygonOptions extends SpriteOptions {\r\n sides?: number;\r\n radius?: number;\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n}\r\n\r\nexport default class RegularPolygon extends Sprite {\r\n\r\n public discriminant = 'regularpolygon';\r\n\r\n public sides: number;\r\n public radius: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.radius * 2,\r\n height: this.radius * 2\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n const step = (2 * Math.PI) / this.sides;\r\n path.moveTo(this.radius, 0);\r\n for (let i = 1; i < this.sides; i++) {\r\n path.lineTo(this.radius * Math.cos(step * i), this.radius * Math.sin(step * i));\r\n }\r\n path.closePath();\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean) {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n\r\n c.translate(cX, cY);\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: RegularPolygonOptions): this {\r\n return new RegularPolygon(options) as this;\r\n }\r\n\r\n public setSides(sides: number) {\r\n this.sides = sides;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: RegularPolygonOptions) {\r\n super(options);\r\n this.sides = options?.sides ?? 5;\r\n this.radius = options?.radius ?? 50;\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n this.draw();\r\n }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport type { Vec2 } from '../types/Vectors.ts';\r\n\r\nexport interface CustomPolygonOptions extends SpriteOptions {\r\n vertices?: Vec2[];\r\n color?: string;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class CustomPolygon extends Sprite {\r\n\r\n public discriminant = 'custompolygon';\r\n\r\n public vertices: Vec2[];\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n\r\n let furthestVertexSize = 0;\r\n\r\n for (const v of this.vertices) {\r\n\r\n const size = Math.hypot(v[0], v[1]);\r\n\r\n if (size > furthestVertexSize)\r\n furthestVertexSize = size;\r\n }\r\n\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: furthestVertexSize,\r\n height: furthestVertexSize\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n const vertices = this.vertices;\r\n\r\n if (vertices.length < 2) return path;\r\n\r\n path.moveTo(vertices[0]![0], vertices[0]![1]);\r\n\r\n for (let i = 1; i < vertices.length; i++)\r\n path.lineTo(vertices[i]![0], vertices[i]![1]);\r\n\r\n path.closePath();\r\n\r\n return path;\r\n }\r\n\r\n public draw(stamping?: boolean): void {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n const path = this.getCachedPath();\r\n\r\n c.fillStyle = this.color;\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.fill(path)\r\n if (this.outlineWidth)\r\n c.stroke(path);\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: CustomPolygonOptions): this {\r\n return new CustomPolygon(options) as this;\r\n }\r\n\r\n public setVertices(vertices: Vec2[]) {\r\n this.vertices = vertices;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n constructor(options?: CustomPolygonOptions) {\r\n super(options);\r\n\r\n this.vertices = options?.vertices ?? [];\r\n this.color = options?.color ?? 'black';\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n\r\n this.draw();\r\n }\r\n\r\n}","import { canvas, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface PenOptions extends SpriteOptions {\r\n drawing?: boolean;\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\nexport default class Pen extends Sprite {\r\n\r\n public discriminant = 'pen';\r\n\r\n public drawing: boolean;\r\n public size: number;\r\n public color: string;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.size,\r\n height: this.size\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n return new Path2D();\r\n }\r\n public draw() {}\r\n\r\n public create(options?: PenOptions): this {\r\n return new Pen(options) as this;\r\n }\r\n\r\n public up() {\r\n this.drawing = false;\r\n }\r\n\r\n public down() {\r\n this.drawing = true;\r\n }\r\n\r\n public stamp(sprite: Sprite) {\r\n sprite.draw(true);\r\n }\r\n\r\n public eraseAll() {\r\n penCtx.clearRect(0, 0, canvas.width, canvas.height);\r\n }\r\n\r\n public dot() {\r\n penCtx.fillStyle = this.color;\r\n penCtx.fillRect(\r\n this.x - this.size / 2 + canvas.width / 2,\r\n -this.y - this.size / 2 + canvas.height / 2,\r\n this.size,\r\n this.size\r\n );\r\n }\r\n\r\n private drawLine(lastX: number, lastY: number) {\r\n penCtx.beginPath();\r\n\r\n penCtx.moveTo(lastX + canvas.width / 2, -lastY + canvas.height / 2);\r\n penCtx.lineTo(this.x + canvas.width / 2, -this.y + canvas.height / 2);\r\n\r\n penCtx.lineWidth = this.size;\r\n penCtx.strokeStyle = this.color;\r\n penCtx.stroke();\r\n }\r\n\r\n // Overriding methods to include drawing\r\n\r\n public override move(steps: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.x += steps * Math.sin(this.toRadians(this.dir));\r\n this.y += steps * Math.cos(this.toRadians(this.dir));\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override setX(x: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.x = x;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override setY(y: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.y = y;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override goTo(x: number, y: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.x = x;\r\n this.y = y;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override changeX(dX: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.x += dX;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n public override changeY(dY: number) {\r\n const lastX = this.x;\r\n const lastY = this.y;\r\n\r\n this.y += dY;\r\n if (this.drawing)\r\n this.drawLine(lastX, lastY);\r\n this.refresh();\r\n }\r\n\r\n // Constructor\r\n\r\n constructor(options?: PenOptions) {\r\n super(options);\r\n this.drawing = options?.drawing ?? false;\r\n this.size = options?.size ?? 5;\r\n this.color = options?.color ?? 'black';\r\n }\r\n\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport type CanvasTextAlign =\r\n | 'left'\r\n | 'right'\r\n | 'center'\r\n | 'start'\r\n | 'end';\r\n\r\nexport type CanvasTextBaseline =\r\n | 'top'\r\n | 'hanging'\r\n | 'middle'\r\n | 'alphabetic'\r\n | 'ideographic'\r\n | 'bottom';\r\n\r\nexport interface TextOptions extends SpriteOptions {\r\n content?: string;\r\n color?: string;\r\n fontFamily?: string;\r\n fontSize?: number;\r\n align?: CanvasTextAlign;\r\n baseline?: CanvasTextBaseline;\r\n}\r\n\r\nexport default class Text extends Sprite {\r\n\r\n public discriminant = 'text';\r\n\r\n public content: string;\r\n public color: string;\r\n public fontFamily: string;\r\n public fontSize: number;\r\n public align: CanvasTextAlign;\r\n public baseline: CanvasTextBaseline;\r\n\r\n private font: string;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n const metrics = ctx.measureText(this.content);\r\n const width = metrics.width;\r\n const height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width, height\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n ctx.save();\r\n \r\n ctx.font = this.font;\r\n\r\n const metrics = ctx.measureText(this.content);\r\n const width = metrics.width;\r\n const height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n\r\n ctx.restore();\r\n\r\n path.rect(-width / 2, -height / 2, width, height);\r\n\r\n return path\r\n }\r\n\r\n public override draw(stamping?: boolean) {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n c.font = this.font;\r\n c.fillStyle = this.color;\r\n c.textAlign = this.align;\r\n c.textBaseline = this.baseline;\r\n\r\n c.fillText(this.content, 0, 0);\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: TextOptions): this {\r\n return new Text(options) as this;\r\n }\r\n\r\n // Methods\r\n\r\n public setContent(content: string) {\r\n this.content = content;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setColor(color: string) {\r\n this.color = color;\r\n this.refresh();\r\n }\r\n\r\n public setFontSize(fontSize: number) {\r\n this.fontSize = fontSize;\r\n this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setFontFamily(fontFamily: string) {\r\n this.fontFamily = fontFamily;\r\n this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setAlign(align: CanvasTextAlign) {\r\n this.align = align;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setBaseline(baseline: CanvasTextBaseline) {\r\n this.baseline = baseline;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n // Constructor\r\n\r\n constructor(options?: TextOptions) {\r\n super(options);\r\n\r\n this.content = options?.content ?? '';\r\n this.color = options?.color ?? 'black';\r\n this.fontFamily = options?.fontFamily ?? 'Arial';\r\n this.fontSize = options?.fontSize ?? 16;\r\n this.align = options?.align ?? 'center';\r\n this.baseline = options?.baseline ?? 'middle';\r\n\r\n this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n\r\n this.draw();\r\n }\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface ImageSpriteOptions extends SpriteOptions {\r\n src?: string;\r\n width: number;\r\n height: number;\r\n outlineColor?: string;\r\n outlineWidth?: number;\r\n};\r\n\r\nexport default class ImageSprite extends Sprite {\r\n\r\n public discriminant = 'imagesprite';\r\n\r\n public src: string;\r\n public width: number;\r\n public height: number;\r\n public outlineColor: string;\r\n public outlineWidth: number;\r\n\r\n protected img: HTMLImageElement;\r\n\r\n public getBoundingBox(): BoundingBox {\r\n return {\r\n x: this.x,\r\n y: this.y,\r\n width: this.width,\r\n height: this.height\r\n };\r\n }\r\n\r\n public getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n path.rect(\r\n -this.width / 2,\r\n -this.height / 2,\r\n this.width,\r\n this.height\r\n );\r\n\r\n return path;\r\n }\r\n\r\n public override draw(stamping?: boolean) {\r\n const c = stamping ? penCtx : ctx;\r\n\r\n c.save();\r\n\r\n const cX = this.x + canvas.width / 2;\r\n const cY = -this.y + canvas.height / 2;\r\n c.translate(cX, cY);\r\n\r\n c.rotate(this.toRadians(this.dir));\r\n\r\n c.strokeStyle = this.outlineColor;\r\n c.lineWidth = this.outlineWidth;\r\n c.drawImage(\r\n this.img,\r\n 0, 0,\r\n this.img.width,\r\n this.img.height,\r\n -this.width / 2,\r\n -this.height / 2,\r\n this.width, this.height\r\n );\r\n if (this.outlineWidth)\r\n c.stroke(this.getCachedPath());\r\n\r\n c.restore();\r\n }\r\n\r\n public create(options?: ImageSpriteOptions): this {\r\n return new ImageSprite(options) as this;\r\n }\r\n\r\n // Methods\r\n\r\n public setSrc(src: string) {\r\n this.src = src;\r\n this.refresh();\r\n }\r\n\r\n public setWidth(width: number) {\r\n this.width = width;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\r\n this.invalidatePath();\r\n this.refresh();\r\n }\r\n\r\n // Constructor\r\n\r\n constructor(options?: ImageSpriteOptions) {\r\n super(options);\r\n\r\n this.src = options?.src ?? '';\r\n this.img = new Image();\r\n this.img.src = this.src;\r\n\r\n this.width = options?.width ?? this.img.width;\r\n this.height = options?.height ?? this.img.height;\r\n\r\n this.outlineColor = options?.outlineColor ?? 'black';\r\n this.outlineWidth = options?.outlineWidth ?? 0;\r\n \r\n this.draw();\r\n }\r\n}"],"mappings":"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","names":["index_exports","__export","Arc","Circle","CustomPolygon","Engine","ImageSprite","Oval","Pen","Rectangle","RegularPolygon","Sprite","Square","Text","canvas","ctx","index_default","setAspectRatio","setScale","__toCommonJS","canvas","ctx","penCanvas","penCtx","ratio","scale","setScale","newScale","setAspectRatio","newAspectRatio","Sprite","_Sprite","Engine","options","sprite","bBox1","bBox2","b1Left","b1Top","b1Right","b1Bottom","b2Left","b2Top","b2Right","b2Bottom","xMin","yMin","xMax","yMax","width","height","ctx","img1","img2","i","deg","rad","steps","dir","x","y","dX","dY","layer","dL","Engine","_Engine","scene","loop","sprite","layer","targetIndex","s","maxFPS","frameInterval","accumulator","tick","currentTime","deltaTime","ctx","canvas","ms","resolve","conditionGetter","check","mouseX","mouseY","canvasMouseX","canvasMouseY","localX","localY","angle","rotatedX","rotatedY","key","src","audio","sound","min","max","vectors","a","b","deg","val","rad","penCanvas","e","Rectangle","_Rectangle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","options","width","height","color","Square","_Square","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","options","sideLength","color","Oval","_Oval","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","options","radX","radY","color","Circle","_Circle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","options","radius","color","Arc","_Arc","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","options","radius","angle","color","RegularPolygon","_RegularPolygon","Sprite","path","step","i","stamping","c","penCtx","ctx","cX","canvas","cY","options","sides","radius","color","CustomPolygon","_CustomPolygon","Sprite","furthestVertexSize","v","size","path","vertices","i","stamping","c","penCtx","ctx","cX","canvas","cY","options","color","Pen","_Pen","Sprite","options","sprite","penCtx","canvas","lastX","lastY","steps","x","y","dX","dY","Text","_Text","Sprite","metrics","ctx","width","height","path","stamping","c","penCtx","cX","canvas","cY","options","content","color","fontSize","fontFamily","align","baseline","ImageSprite","_ImageSprite","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","options","src","width","height","TScratch","Engine","Sprite","Rectangle","Square","Oval","Circle","Arc","RegularPolygon","CustomPolygon","Pen","Text","ImageSprite","setScale","setAspectRatio","canvas","ctx","index_default"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -5,12 +5,12 @@ interface BoundingBox {
|
|
|
5
5
|
height: number;
|
|
6
6
|
}
|
|
7
7
|
interface SpriteOptions {
|
|
8
|
-
x
|
|
9
|
-
y
|
|
10
|
-
dir
|
|
11
|
-
scene
|
|
12
|
-
hidden
|
|
13
|
-
layer
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
dir: number;
|
|
11
|
+
scene: string;
|
|
12
|
+
hidden: boolean;
|
|
13
|
+
layer: number;
|
|
14
14
|
}
|
|
15
15
|
declare abstract class Sprite {
|
|
16
16
|
x: number;
|
|
@@ -26,10 +26,12 @@ declare abstract class Sprite {
|
|
|
26
26
|
abstract getBoundingBox(): BoundingBox;
|
|
27
27
|
abstract getPath(): Path2D;
|
|
28
28
|
abstract draw(stamping?: boolean): void;
|
|
29
|
+
protected abstract create(options?: SpriteOptions): this;
|
|
29
30
|
protected refresh(): void;
|
|
30
31
|
protected invalidatePath(): void;
|
|
31
32
|
protected getCachedPath(): Path2D;
|
|
32
33
|
constructor(options?: SpriteOptions);
|
|
34
|
+
clone(options?: SpriteOptions): this;
|
|
33
35
|
touching(sprite: Sprite): boolean;
|
|
34
36
|
protected toRadians(deg: number): number;
|
|
35
37
|
protected toDegrees(rad: number): number;
|
|
@@ -48,13 +50,15 @@ declare abstract class Sprite {
|
|
|
48
50
|
changeLayer(dL: number): void;
|
|
49
51
|
}
|
|
50
52
|
|
|
53
|
+
type Vec2 = [number, number];
|
|
54
|
+
type Vec3 = [number, number, number];
|
|
55
|
+
type Vec4 = [number, number, number, number];
|
|
56
|
+
|
|
51
57
|
type GameLoop = (() => any) | (() => Promise<any>);
|
|
52
|
-
type SceneMap = {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
+
type SceneMap = Map<string, {
|
|
59
|
+
sprites: Sprite[];
|
|
60
|
+
loop: GameLoop | null;
|
|
61
|
+
}>;
|
|
58
62
|
declare class Engine {
|
|
59
63
|
private static instance;
|
|
60
64
|
private loopRunning;
|
|
@@ -89,6 +93,7 @@ declare class Engine {
|
|
|
89
93
|
stopSound(sound: HTMLAudioElement): void;
|
|
90
94
|
stopAllSounds(): void;
|
|
91
95
|
pickRandom(min: number, max: number): number;
|
|
96
|
+
dotProduct(vectors: [Vec2, Vec2] | [Vec3, Vec3] | [Vec4, Vec4]): number;
|
|
92
97
|
sin(deg: number): number;
|
|
93
98
|
cos(deg: number): number;
|
|
94
99
|
tan(deg: number): number;
|
|
@@ -126,6 +131,7 @@ declare class Rectangle extends Sprite {
|
|
|
126
131
|
getBoundingBox(): BoundingBox;
|
|
127
132
|
getPath(): Path2D;
|
|
128
133
|
draw(stamping?: boolean): void;
|
|
134
|
+
create(options?: RectangleOptions): this;
|
|
129
135
|
setWidth(width: number): void;
|
|
130
136
|
setHeight(height: number): void;
|
|
131
137
|
setColor(color: string): void;
|
|
@@ -147,6 +153,7 @@ declare class Square extends Sprite {
|
|
|
147
153
|
getBoundingBox(): BoundingBox;
|
|
148
154
|
getPath(): Path2D;
|
|
149
155
|
draw(stamping?: boolean): void;
|
|
156
|
+
create(options?: SquareOptions): this;
|
|
150
157
|
setSideLength(sideLength: number): void;
|
|
151
158
|
setColor(color: string): void;
|
|
152
159
|
constructor(options?: SquareOptions);
|
|
@@ -169,6 +176,7 @@ declare class Oval extends Sprite {
|
|
|
169
176
|
getBoundingBox(): BoundingBox;
|
|
170
177
|
getPath(): Path2D;
|
|
171
178
|
draw(stamping?: boolean): void;
|
|
179
|
+
create(options?: OvalOptions): this;
|
|
172
180
|
setRadX(radX: number): void;
|
|
173
181
|
setRadY(radY: number): void;
|
|
174
182
|
setColor(color: string): void;
|
|
@@ -190,11 +198,36 @@ declare class Circle extends Sprite {
|
|
|
190
198
|
getBoundingBox(): BoundingBox;
|
|
191
199
|
getPath(): Path2D;
|
|
192
200
|
draw(stamping?: boolean): void;
|
|
201
|
+
create(options?: CircleOptions): this;
|
|
193
202
|
setRadius(radius: number): void;
|
|
194
203
|
setColor(color: string): void;
|
|
195
204
|
constructor(options?: CircleOptions);
|
|
196
205
|
}
|
|
197
206
|
|
|
207
|
+
interface ArcOptions extends SpriteOptions {
|
|
208
|
+
radius?: number;
|
|
209
|
+
angle?: number;
|
|
210
|
+
color?: string;
|
|
211
|
+
outlineColor?: string;
|
|
212
|
+
outlineWidth?: number;
|
|
213
|
+
}
|
|
214
|
+
declare class Arc extends Sprite {
|
|
215
|
+
discriminant: string;
|
|
216
|
+
radius: number;
|
|
217
|
+
angle: number;
|
|
218
|
+
color: string;
|
|
219
|
+
outlineColor: string;
|
|
220
|
+
outlineWidth: number;
|
|
221
|
+
getBoundingBox(): BoundingBox;
|
|
222
|
+
getPath(): Path2D;
|
|
223
|
+
draw(stamping?: boolean): void;
|
|
224
|
+
create(options?: ArcOptions): this;
|
|
225
|
+
setRadius(radius: number): void;
|
|
226
|
+
setAngle(angle: number): void;
|
|
227
|
+
setColor(color: string): void;
|
|
228
|
+
constructor(options?: ArcOptions);
|
|
229
|
+
}
|
|
230
|
+
|
|
198
231
|
interface RegularPolygonOptions extends SpriteOptions {
|
|
199
232
|
sides?: number;
|
|
200
233
|
radius?: number;
|
|
@@ -212,12 +245,34 @@ declare class RegularPolygon extends Sprite {
|
|
|
212
245
|
getBoundingBox(): BoundingBox;
|
|
213
246
|
getPath(): Path2D;
|
|
214
247
|
draw(stamping?: boolean): void;
|
|
248
|
+
create(options?: RegularPolygonOptions): this;
|
|
215
249
|
setSides(sides: number): void;
|
|
216
250
|
setRadius(radius: number): void;
|
|
217
251
|
setColor(color: string): void;
|
|
218
252
|
constructor(options?: RegularPolygonOptions);
|
|
219
253
|
}
|
|
220
254
|
|
|
255
|
+
interface CustomPolygonOptions extends SpriteOptions {
|
|
256
|
+
vertices?: Vec2[];
|
|
257
|
+
color?: string;
|
|
258
|
+
outlineColor?: string;
|
|
259
|
+
outlineWidth?: number;
|
|
260
|
+
}
|
|
261
|
+
declare class CustomPolygon extends Sprite {
|
|
262
|
+
discriminant: string;
|
|
263
|
+
vertices: Vec2[];
|
|
264
|
+
color: string;
|
|
265
|
+
outlineColor: string;
|
|
266
|
+
outlineWidth: number;
|
|
267
|
+
getBoundingBox(): BoundingBox;
|
|
268
|
+
getPath(): Path2D;
|
|
269
|
+
draw(stamping?: boolean): void;
|
|
270
|
+
create(options?: CustomPolygonOptions): this;
|
|
271
|
+
setVertices(vertices: Vec2[]): void;
|
|
272
|
+
setColor(color: string): void;
|
|
273
|
+
constructor(options?: CustomPolygonOptions);
|
|
274
|
+
}
|
|
275
|
+
|
|
221
276
|
interface PenOptions extends SpriteOptions {
|
|
222
277
|
drawing?: boolean;
|
|
223
278
|
size?: number;
|
|
@@ -231,6 +286,7 @@ declare class Pen extends Sprite {
|
|
|
231
286
|
getBoundingBox(): BoundingBox;
|
|
232
287
|
getPath(): Path2D;
|
|
233
288
|
draw(): void;
|
|
289
|
+
create(options?: PenOptions): this;
|
|
234
290
|
up(): void;
|
|
235
291
|
down(): void;
|
|
236
292
|
stamp(sprite: Sprite): void;
|
|
@@ -268,6 +324,7 @@ declare class Text extends Sprite {
|
|
|
268
324
|
getBoundingBox(): BoundingBox;
|
|
269
325
|
getPath(): Path2D;
|
|
270
326
|
draw(stamping?: boolean): void;
|
|
327
|
+
create(options?: TextOptions): this;
|
|
271
328
|
setContent(content: string): void;
|
|
272
329
|
setColor(color: string): void;
|
|
273
330
|
setFontSize(fontSize: number): void;
|
|
@@ -295,6 +352,7 @@ declare class ImageSprite extends Sprite {
|
|
|
295
352
|
getBoundingBox(): BoundingBox;
|
|
296
353
|
getPath(): Path2D;
|
|
297
354
|
draw(stamping?: boolean): void;
|
|
355
|
+
create(options?: ImageSpriteOptions): this;
|
|
298
356
|
setSrc(src: string): void;
|
|
299
357
|
setWidth(width: number): void;
|
|
300
358
|
setHeight(height: number): void;
|
|
@@ -308,7 +366,9 @@ declare const TScratch: {
|
|
|
308
366
|
Square: typeof Square;
|
|
309
367
|
Oval: typeof Oval;
|
|
310
368
|
Circle: typeof Circle;
|
|
369
|
+
Arc: typeof Arc;
|
|
311
370
|
RegularPolygon: typeof RegularPolygon;
|
|
371
|
+
CustomPolygon: typeof CustomPolygon;
|
|
312
372
|
Pen: typeof Pen;
|
|
313
373
|
Text: typeof Text;
|
|
314
374
|
ImageSprite: typeof ImageSprite;
|
|
@@ -318,4 +378,4 @@ declare const TScratch: {
|
|
|
318
378
|
ctx: CanvasRenderingContext2D;
|
|
319
379
|
};
|
|
320
380
|
|
|
321
|
-
export { type CanvasTextAlign, type CanvasTextBaseline, Circle, type CircleOptions, Engine, ImageSprite, type ImageSpriteOptions, Oval, type OvalOptions, Pen, type PenOptions, Rectangle, type RectangleOptions, RegularPolygon, type RegularPolygonOptions, Sprite, type SpriteOptions, Square, type SquareOptions, Text, type TextOptions, canvas, ctx, TScratch as default, setAspectRatio, setScale };
|
|
381
|
+
export { Arc, type ArcOptions, type CanvasTextAlign, type CanvasTextBaseline, Circle, type CircleOptions, CustomPolygon, type CustomPolygonOptions, Engine, ImageSprite, type ImageSpriteOptions, Oval, type OvalOptions, Pen, type PenOptions, Rectangle, type RectangleOptions, RegularPolygon, type RegularPolygonOptions, Sprite, type SpriteOptions, Square, type SquareOptions, Text, type TextOptions, type Vec2, type Vec3, type Vec4, canvas, ctx, TScratch as default, setAspectRatio, setScale };
|