tscratch 0.4.9 → 0.5.1
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 +32 -6
- package/dist/index.d.ts +32 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var O=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var A=(a,t)=>{for(var e in t)O(a,e,{get:t[e],enumerable:!0})},X=(a,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of T(t))!D.call(a,r)&&r!==e&&O(a,r,{get:()=>t[r],enumerable:!(s=L(t,r))||s.enumerable});return a};var Y=a=>X(O({},"__esModule",{value:!0}),a);var z={};A(z,{Circle:()=>f,Engine:()=>p,ImageSprite:()=>S,Oval:()=>g,Pen:()=>y,Rectangle:()=>b,RegularPolygon:()=>x,Sprite:()=>l,Square:()=>m,Text:()=>w,canvas:()=>i,ctx:()=>n,default:()=>I,setAspectRatio:()=>W,setScale:()=>M});module.exports=Y(z);var i=document.getElementById("game-window")||document.createElement("canvas"),n=i.getContext("2d"),c=document.createElement("canvas"),h=c.getContext("2d");c.id="pen-canvas";var P=16/9,u;function M(a){u=a,i.width=P*u,i.height=u,c.width=P*u,c.height=u}function W(a){P=a,i.width=P*u,i.height=u,c.width=P*u,c.height=u}i.parentElement?.insertBefore(c,i);M(500);var l=class{x;y;dir;scene;hidden;layer;refresh(){p.init().refresh()}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,p.init().addSprite(this)}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,e){this.dir=90-this.toDegrees(Math.atan2(e,t)),this.refresh()}setX(t){this.x=t,this.refresh()}setY(t){this.y=t,this.refresh()}goTo(t,e){this.x=t,this.y=e,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 p=class a{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;sounds=[];mouseX=0;mouseY=0;mouseDown=!1;mouseClicked=!1;keysPressed=new Set;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new a),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,e){if(!this.sceneMap[t]){this.sceneMap[t]={sprites:[],loop:e},t===this.currentScene&&this.changeScene(t);return}this.sceneMap[t].loop=e,t===this.currentScene&&this.changeScene(t)}addSprite(t){let{scene:e,layer:s}=t;if(!this.sceneMap[e]){this.sceneMap[e]={sprites:[t],loop:null};return}let r=this.sceneMap[e].sprites.findIndex(o=>o.layer>s);if(r===-1){this.sceneMap[e].sprites.push(t);return}this.sceneMap[e].sprites.splice(r,0,t),this.refresh()}removeSprite(t){let{scene:e}=t;this.sceneMap[e]&&(this.sceneMap[e].sprites=this.sceneMap[e].sprites.filter(s=>s!==t),this.refresh())}async setMaxFramesPerSecond(t){this.maxFPS=t;let e=this.gameLoop;if(e)for(this.loopRunning=!0;this.loopRunning;)await e(),await this.wait(1e3/t)}refresh(){n.clearRect(0,0,i.width,i.height),this.sceneMap[this.currentScene]?.sprites.forEach(t=>{t.hidden||t.draw()})}async wait(t){return new Promise(e=>setTimeout(e,t))}async waitUntil(t){return new Promise(e=>{let s=()=>{t()?e():setTimeout(s,1e3/this.maxFPS)};s()})}isHovered(t){let{mouseX:e,mouseY:s}=this,r=e+i.width/2,o=i.height/2-s,v=r-(t.x+i.width/2),C=o-(i.height/2-t.y),d=-this.toRadians(t.dir),R=v*Math.cos(d)-C*Math.sin(d),k=v*Math.sin(d)+C*Math.cos(d);return n.isPointInPath(t.getPath(),R,k)}isKeyPressed(t){return this.keysPressed.has(t)}playSound(t){let e=new Audio(t);return this.sounds.push(e),e.play(),e}stopSound(t){t.pause(),t.currentTime=0,this.sounds=this.sounds.filter(e=>e!==t)}stopAllSounds(){this.sounds.forEach(t=>{t.pause(),t.currentTime=0}),this.sounds=[]}pickRandom(t,e){return t>e&&([t,e]=[e,t]),Math.floor(Math.random()*(e-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),c.addEventListener("mousemove",t=>{this.mouseX=t.clientX-c.offsetLeft-c.width/2,this.mouseY=-(t.clientY-c.offsetTop-c.height/2)}),c.addEventListener("mousedown",t=>{this.mouseDown=!0}),c.addEventListener("mouseup",t=>{this.mouseDown=!1}),c.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 b=class extends l{width;height;color;outlineColor;outlineWidth;getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let e=t?h:n;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir));let o=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(o),this.outlineWidth&&e.stroke(o),e.restore()}setWidth(t){this.width=t,this.refresh()}setHeight(t){this.height=t,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 m=class extends l{sideLength;color;outlineColor;outlineWidth;getPath(){let t=new Path2D;return t.rect(-this.sideLength/2,-this.sideLength/2,this.sideLength,this.sideLength),t}draw(t){let e=t?h:n;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir));let o=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(o),this.outlineWidth&&e.stroke(o),e.restore()}setSideLength(t){this.sideLength=t,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 g=class extends l{radA;radB;color;outlineColor;outlineWidth;getPath(){let t=new Path2D;return t.ellipse(0,0,this.radA,this.radB,0,0,Math.PI*2),t}draw(t){let e=t?h:n;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir));let o=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(o),this.outlineWidth&&e.stroke(o),e.restore()}setRadA(t){this.radA=t,this.refresh()}setRadB(t){this.radB=t,this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.radA=t?.radA??25,this.radB=t?.radB??25,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var f=class extends l{radius;color;outlineColor;outlineWidth;getPath(){let t=new Path2D;return t.ellipse(0,0,this.radius,this.radius,0,0,Math.PI*2),t}draw(t){let e=t?h:n;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir));let o=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(o),this.outlineWidth&&e.stroke(o),e.restore()}setRadius(t){this.radius=t,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 x=class extends l{sides;radius;color;outlineColor;outlineWidth;getPath(){let t=new Path2D,e=Math.PI*2/this.sides,s=this.toRadians(this.dir),r=this.radius;for(let o=0;o<this.sides;o++){let v=o*e-Math.PI/2+s,C=r*Math.cos(v),d=-r*Math.sin(v);o===0?t.moveTo(C,d):t.lineTo(C,d)}return t.closePath(),t}draw(t){let e=t?h:n;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r);let o=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(o),this.outlineWidth&&e.stroke(o),e.restore()}setSides(t){this.sides=t,this.refresh()}setRadius(t){this.radius=t,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 y=class extends l{drawing;size;color;getPath(){return new Path2D}draw(){}up(){this.drawing=!1}down(){this.drawing=!0}stamp(t){t.draw(!0)}ereaseAll(){h.clearRect(0,0,i.width,i.height)}dot(){h.fillStyle=this.color,h.fillRect(this.x-this.size/2+i.width/2,-this.y-this.size/2+i.height/2,this.size,this.size)}drawLine(t,e){h.beginPath(),h.moveTo(t+i.width/2,-e+i.height/2),h.lineTo(this.x+i.width/2,-this.y+i.height/2),h.lineWidth=this.size,h.strokeStyle=this.color,h.stroke()}move(t){let e=this.x,s=this.y;this.x+=t*Math.sin(this.toRadians(this.dir)),this.y+=t*Math.cos(this.toRadians(this.dir)),this.drawing&&this.drawLine(e,s),this.refresh()}setX(t){let e=this.x,s=this.y;this.x=t,this.drawing&&this.drawLine(e,s),this.refresh()}setY(t){let e=this.x,s=this.y;this.y=t,this.drawing&&this.drawLine(e,s),this.refresh()}goTo(t,e){let s=this.x,r=this.y;this.x=t,this.y=e,this.drawing&&this.drawLine(s,r),this.refresh()}changeX(t){let e=this.x,s=this.y;this.x+=t,this.drawing&&this.drawLine(e,s),this.refresh()}changeY(t){let e=this.x,s=this.y;this.y+=t,this.drawing&&this.drawLine(e,s),this.refresh()}constructor(t){super(t),this.drawing=t?.drawing??!1,this.size=t?.size??5,this.color=t?.color??"black"}};var w=class extends l{content;color;fontFamily;fontSize;align;baseline;font;getPath(){let t=new Path2D;n.save(),n.font=this.font;let e=n.measureText(this.content),s=e.width,r=e.actualBoundingBoxAscent+e.actualBoundingBoxDescent;return n.restore(),t.rect(-s/2,-r/2,s,r),t}draw(t){let e=t?h:n;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir)),e.font=this.font,e.fillStyle=this.color,e.textAlign=this.align,e.textBaseline=this.baseline,e.fillText(this.content,0,0),e.restore()}setContent(t){this.content=t,this.refresh()}setColor(t){this.color=t,this.refresh()}setFontSize(t){this.fontSize=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.refresh()}setFontFamily(t){this.fontFamily=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.refresh()}setAlign(t){this.align=t,this.refresh()}setBaseline(t){this.baseline=t,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 S=class extends l{src;width;height;outlineColor;outlineWidth;img;getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let e=t?h:n;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir)),e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height),this.outlineWidth&&e.stroke(this.getPath()),e.restore()}setSrc(t){this.src=t,this.refresh()}setWidth(t){this.width=t,this.refresh()}setHeight(t){this.height=t,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 B={Engine:p,Sprite:l,Rectangle:b,Square:m,Oval:g,Circle:f,RegularPolygon:x,Pen:y,Text:w,ImageSprite:S,setScale:M,setAspectRatio:W,canvas:i,ctx:n},I=B;0&&(module.exports={Circle,Engine,ImageSprite,Oval,Pen,Rectangle,RegularPolygon,Sprite,Square,Text,canvas,ctx,setAspectRatio,setScale});
|
|
1
|
+
"use strict";var D=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var U=(a,t)=>{for(var i in t)D(a,i,{get:t[i],enumerable:!0})},j=(a,t,i,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of G(t))!K.call(a,n)&&n!==i&&D(a,n,{get:()=>t[n],enumerable:!(e=q(t,n))||e.enumerable});return a};var J=a=>j(D({},"__esModule",{value:!0}),a);var V={};U(V,{Circle:()=>w,Engine:()=>b,ImageSprite:()=>C,Oval:()=>y,Pen:()=>v,Rectangle:()=>f,RegularPolygon:()=>S,Sprite:()=>l,Square:()=>x,Text:()=>B,canvas:()=>s,ctx:()=>h,default:()=>Q,setAspectRatio:()=>I,setScale:()=>W});module.exports=J(V);var s=document.getElementById("game-window")||document.createElement("canvas"),h=s.getContext("2d"),c=document.createElement("canvas"),o=c.getContext("2d");c.id="pen-canvas";var O=16/9,d;function W(a){d=a,s.width=O*d,s.height=d,c.width=O*d,c.height=d}function I(a){O=a,s.width=O*d,s.height=d,c.width=O*d,c.height=d}s.parentElement?.insertBefore(c,s);W(500);var l=class{x;y;dir;scene;hidden;layer;refresh(){b.init().refresh()}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)*2<i.width+e.width&&Math.abs(i.y-e.y)*2<i.height+e.height))return!1;let r=i.x-i.width/2,g=i.y-i.height/2,m=i.x+i.width/2,p=i.y+i.height/2,L=e.x-e.width/2,k=e.y-e.height/2,E=e.x+e.width/2,A=e.y+e.height/2,T=Math.max(r,L),X=Math.max(g,k),F=Math.min(m,E),H=Math.min(p,A),P=F-T,M=H-X;if(P<=0||M<=0)return!1;let Y=document.createElement("canvas");Y.width=P,Y.height=M;let u=Y.getContext("2d");u.save(),u.translate(-T,-X),u.fillStyle="red",u.fill(this.getPath()),u.restore();let z=u.getImageData(0,0,P,M).data;u.clearRect(0,0,P,M),u.save(),u.translate(-T,-X),u.fillStyle="blue",u.fill(t.getPath()),u.restore();let $=u.getImageData(0,0,P,M).data;for(let R=3;R<z.length;R+=4)if(z[R]>0&&$[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 a{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;sounds=[];mouseX=0;mouseY=0;mouseDown=!1;mouseClicked=!1;keysPressed=new Set;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new a),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}resumeLoop(){this.loopRunning=!0}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(r=>r.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)for(this.loopRunning=!0;this.loopRunning;)await i(),await this.wait(1e3/t)}refresh(){h.clearRect(0,0,s.width,s.height),this.sceneMap[this.currentScene]?.sprites.forEach(t=>{t.hidden||t.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()})}isHovered(t){let{mouseX:i,mouseY:e}=this,n=i+s.width/2,r=s.height/2-e,g=n-(t.x+s.width/2),m=r-(s.height/2-t.y),p=-this.toRadians(t.dir),L=g*Math.cos(p)-m*Math.sin(p),k=g*Math.sin(p)+m*Math.cos(p);return h.isPointInPath(t.getPath(),L,k)}isKeyPressed(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),c.addEventListener("mousemove",t=>{this.mouseX=t.clientX-c.offsetLeft-c.width/2,this.mouseY=-(t.clientY-c.offsetTop-c.height/2)}),c.addEventListener("mousedown",t=>{this.mouseDown=!0}),c.addEventListener("mouseup",t=>{this.mouseDown=!1}),c.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 f=class extends l{discriminant="rectangle";width;height;color;outlineColor;outlineWidth;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));let r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setWidth(t){this.width=t,this.refresh()}setHeight(t){this.height=t,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 x=class extends l{discriminant="square";sideLength;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.sideLength,height: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 r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setSideLength(t){this.sideLength=t,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 y=class extends l{discriminant="circle";radX;radY;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.radX*2,height: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 r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setRadX(t){this.radX=t,this.refresh()}setRadY(t){this.radY=t,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 w=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 r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setRadius(t){this.radius=t,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 S=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=Math.PI*2/this.sides,e=this.toRadians(this.dir),n=this.radius;for(let r=0;r<this.sides;r++){let g=r*i-Math.PI/2+e,m=n*Math.cos(g),p=-n*Math.sin(g);r===0?t.moveTo(m,p):t.lineTo(m,p)}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);let r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setSides(t){this.sides=t,this.refresh()}setRadius(t){this.radius=t,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 v=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)}ereaseAll(){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.refresh()}setColor(t){this.color=t,this.refresh()}setFontSize(t){this.fontSize=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.refresh()}setFontFamily(t){this.fontFamily=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.refresh()}setAlign(t){this.align=t,this.refresh()}setBaseline(t){this.baseline=t,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 C=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.getPath()),i.restore()}setSrc(t){this.src=t,this.refresh()}setWidth(t){this.width=t,this.refresh()}setHeight(t){this.height=t,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:f,Square:x,Oval:y,Circle:w,RegularPolygon:S,Pen:v,Text:B,ImageSprite:C,setScale:W,setAspectRatio:I,canvas:s,ctx:h},Q=N;0&&(module.exports={Circle,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 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 // Rendering\r\n\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 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 // 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 public maxFPS: number = 24;\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 // Set a loop\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 // 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 this.loopRunning = true;\r\n\r\n while (this.loopRunning) {\r\n await loop();\r\n await this.wait(1000 / maxFPS);\r\n }\r\n }\r\n\r\n public refresh() {\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n this.sceneMap[this.currentScene]?.sprites.forEach(sprite => {\r\n if (!sprite.hidden)\r\n sprite.draw();\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 isHovered(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 isKeyPressed(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 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 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 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.getPath();\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.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\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 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 sideLength: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\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.getPath();\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.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 SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface OvalOptions extends SpriteOptions {\r\n radA?: number;\r\n radB?: 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 radA: number;\r\n public radB: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\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.radA,\r\n this.radB,\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.getPath();\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 setRadA(radA: number) {\r\n this.radA = radA;\r\n this.refresh();\r\n }\r\n\r\n public setRadB(radB: number) {\r\n this.radB = radB;\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.radA = options?.radA ?? 25;\r\n this.radB = options?.radB ?? 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 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 radius: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\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.getPath();\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.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 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 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 getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n const step = (Math.PI * 2) / this.sides;\r\n const rotation = this.toRadians(this.dir);\r\n const r = this.radius;\r\n\r\n for (let i = 0; i < this.sides; i++) {\r\n const theta = i * step - Math.PI / 2 + rotation;\r\n const px = r * Math.cos(theta);\r\n const py = -r * Math.sin(theta);\r\n\r\n if (i === 0) path.moveTo(px, py);\r\n else path.lineTo(px, py);\r\n }\r\n\r\n path.closePath();\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\r\n c.translate(cX, cY);\r\n\r\n const path = this.getPath();\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.refresh();\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\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 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 drawing: boolean;\r\n public size: number;\r\n public color: string;\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 ereaseAll() {\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 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 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 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.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.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.refresh();\r\n }\r\n\r\n public setAlign(align: CanvasTextAlign) {\r\n this.align = align;\r\n this.refresh();\r\n }\r\n\r\n public setBaseline(baseline: CanvasTextBaseline) {\r\n this.baseline = baseline;\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 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 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 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.getPath());\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.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\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":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,YAAAE,EAAA,WAAAC,EAAA,gBAAAC,EAAA,SAAAC,EAAA,QAAAC,EAAA,cAAAC,EAAA,mBAAAC,EAAA,WAAAC,EAAA,WAAAC,EAAA,SAAAC,EAAA,WAAAC,EAAA,QAAAC,EAAA,YAAAC,EAAA,mBAAAC,EAAA,aAAAC,IAAA,eAAAC,EAAAjB,GCAO,IAAMkB,EAAS,SAAS,eAAe,aAAa,GAA0B,SAAS,cAAc,QAAQ,EACvGC,EAAMD,EAAO,WAAW,IAAI,EAE5BE,EAAY,SAAS,cAAc,QAAQ,EAC3CC,EAASD,EAAU,WAAW,IAAI,EAC/CA,EAAU,GAAK,aAEf,IAAIE,EAAgB,GAAK,EACrBC,EAEG,SAASC,EAASC,EAAkB,CACvCF,EAAQE,EAERP,EAAO,MAAQI,EAAQC,EACvBL,EAAO,OAASK,EAEhBH,EAAU,MAAQE,EAAQC,EAC1BH,EAAU,OAASG,CACvB,CAEO,SAASG,EAAeC,EAAwB,CACnDL,EAAQK,EAERT,EAAO,MAAQI,EAAQC,EACvBL,EAAO,OAASK,EAEhBH,EAAU,MAAQE,EAAQC,EAC1BH,EAAU,OAASG,CACvB,CAEAL,EAAO,eAAe,aAAaE,EAAWF,CAAM,EAEpDM,EAAS,GAAG,ECrBZ,IAA8BI,EAA9B,KAAqC,CAE1B,EACA,EACA,IACA,MACA,OACA,MAOG,SAAU,CAChBC,EAAO,KAAK,EAAE,QAAQ,CAC1B,CAEA,YAAYC,EAAyB,CACjC,KAAK,EAAIA,GAAS,GAAK,EACvB,KAAK,EAAIA,GAAS,GAAK,EACvB,KAAK,IAAMA,GAAS,KAAO,EAC3B,KAAK,MAAQA,GAAS,OAAS,OAC/B,KAAK,OAASA,GAAS,QAAU,GACjC,KAAK,MAAQA,GAAS,OAAS,EAC/BD,EAAO,KAAK,EAAE,UAAU,IAAI,CAChC,CAIU,UAAUE,EAAa,CAC7B,OAAOA,EAAM,KAAK,GAAK,GAC3B,CAEU,UAAUC,EAAa,CAC7B,OAAOA,EAAM,IAAM,KAAK,EAC5B,CAKO,KAAKC,EAAe,CACvB,KAAK,GAAKA,EAAQ,KAAK,IAAI,KAAK,UAAU,KAAK,GAAG,CAAC,EACnD,KAAK,GAAKA,EAAQ,KAAK,IAAI,KAAK,UAAU,KAAK,GAAG,CAAC,EACnD,KAAK,QAAQ,CACjB,CAEO,KAAKF,EAAa,CACrB,KAAK,KAAOA,EACZ,KAAK,QAAQ,CACjB,CAEO,MAAMG,EAAa,CACtB,KAAK,IAAMA,EACX,KAAK,QAAQ,CACjB,CAEO,aAAaC,EAAWC,EAAW,CACtC,KAAK,IAAM,GAAK,KAAK,UAAU,KAAK,MAAMA,EAAGD,CAAC,CAAC,EAC/C,KAAK,QAAQ,CACjB,CAEO,KAAKA,EAAW,CACnB,KAAK,EAAIA,EACT,KAAK,QAAQ,CACjB,CAEO,KAAKC,EAAW,CACnB,KAAK,EAAIA,EACT,KAAK,QAAQ,CACjB,CAEO,KAAKD,EAAWC,EAAW,CAC9B,KAAK,EAAID,EACT,KAAK,EAAIC,EACT,KAAK,QAAQ,CACjB,CAEO,QAAQC,EAAY,CACvB,KAAK,GAAKA,EACV,KAAK,QAAQ,CACjB,CAEO,QAAQC,EAAY,CACvB,KAAK,GAAKA,EACV,KAAK,QAAQ,CACjB,CAIO,MAAO,CACV,KAAK,OAAS,GACd,KAAK,QAAQ,CACjB,CAEO,MAAO,CACV,KAAK,OAAS,GACd,KAAK,QAAQ,CACjB,CAEO,UAAUC,EAAe,CAC5B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEO,YAAYC,EAAY,CAC3B,KAAK,OAASA,EACd,KAAK,QAAQ,CACjB,CACJ,EC5GA,IAAqBC,EAArB,MAAqBC,CAAO,CAExB,OAAe,SAEP,YAAuB,GACxB,SAA4B,KAC5B,OAAiB,GAEjB,OAA6B,CAAC,EAE9B,OAAiB,EACjB,OAAiB,EAEjB,UAAqB,GACrB,aAAwB,GAEvB,YAA2B,IAAI,IAEhC,aAAuB,OACvB,SAAqB,CAAC,EAI7B,OAAc,MAAO,CACjB,OAAK,KAAK,WACN,KAAK,SAAW,IAAIA,GAEjB,KAAK,QAChB,CAIO,YAAYC,EAAe,CACzB,KAAK,SAASA,CAAK,IACpB,KAAK,SAASA,CAAK,EAAI,CAAE,QAAS,CAAC,EAAG,KAAM,IAAK,GAErD,KAAK,YAAc,GACnB,KAAK,aAAeA,EACpB,KAAK,SAAW,KAAK,SAASA,CAAK,EAAE,KACrC,KAAK,sBAAsB,KAAK,MAAM,CAC1C,CAIO,QAAQA,EAAeC,EAAgB,CAC1C,GAAI,CAAC,KAAK,SAASD,CAAK,EAAG,CACvB,KAAK,SAASA,CAAK,EAAI,CAAE,QAAS,CAAC,EAAG,KAAAC,CAAK,EACvCD,IAAU,KAAK,cACf,KAAK,YAAYA,CAAK,EAC1B,MACJ,CAEA,KAAK,SAASA,CAAK,EAAE,KAAOC,EACxBD,IAAU,KAAK,cACf,KAAK,YAAYA,CAAK,CAC9B,CAIO,UAAUE,EAAgB,CAC7B,GAAM,CAAE,MAAAF,EAAO,MAAAG,CAAM,EAAID,EAEzB,GAAI,CAAC,KAAK,SAASF,CAAK,EAAG,CACvB,KAAK,SAASA,CAAK,EAAI,CAAE,QAAS,CAACE,CAAM,EAAG,KAAM,IAAK,EACvD,MACJ,CAEA,IAAIE,EAAc,KAAK,SAASJ,CAAK,EAAE,QAAQ,UAAUK,GAAKA,EAAE,MAAQF,CAAK,EAC7E,GAAIC,IAAgB,GAAI,CACpB,KAAK,SAASJ,CAAK,EAAE,QAAQ,KAAKE,CAAM,EACxC,MACJ,CAEA,KAAK,SAASF,CAAK,EAAE,QAAQ,OAAOI,EAAa,EAAGF,CAAM,EAC1D,KAAK,QAAQ,CACjB,CAEO,aAAaA,EAAgB,CAChC,GAAM,CAAE,MAAAF,CAAM,EAAIE,EAEb,KAAK,SAASF,CAAK,IAExB,KAAK,SAASA,CAAK,EAAE,QAAU,KAAK,SAASA,CAAK,EAAE,QAAQ,OAAO,GAAK,IAAME,CAAM,EACpF,KAAK,QAAQ,EACjB,CAEA,MAAa,sBAAsBI,EAAgB,CAC/C,KAAK,OAASA,EAEd,IAAIL,EAAO,KAAK,SAChB,GAAKA,EAIL,IAFA,KAAK,YAAc,GAEZ,KAAK,aACR,MAAMA,EAAK,EACX,MAAM,KAAK,KAAK,IAAOK,CAAM,CAErC,CAEO,SAAU,CACbC,EAAI,UAAU,EAAG,EAAGC,EAAO,MAAOA,EAAO,MAAM,EAC/C,KAAK,SAAS,KAAK,YAAY,GAAG,QAAQ,QAAQN,GAAU,CACnDA,EAAO,QACRA,EAAO,KAAK,CACpB,CAAC,CACL,CAIA,MAAa,KAAKO,EAA2B,CACzC,OAAO,IAAI,QAAQC,GAAW,WAAWA,EAASD,CAAE,CAAC,CACzD,CAEA,MAAa,UAAUE,EAA+C,CAClE,OAAO,IAAI,QAAQD,GAAW,CAC1B,IAAME,EAAQ,IAAM,CACZD,EAAgB,EAAGD,EAAQ,EAC1B,WAAWE,EAAO,IAAO,KAAK,MAAM,CAC7C,EACAA,EAAM,CACV,CAAC,CACL,CAIO,UAAUV,EAAgB,CAC7B,GAAM,CAAE,OAAAW,EAAQ,OAAAC,CAAO,EAAI,KAErBC,EAAeF,EAASL,EAAO,MAAQ,EACvCQ,EAAeR,EAAO,OAAS,EAAIM,EAGnCG,EAASF,GAAgBb,EAAO,EAAIM,EAAO,MAAQ,GACnDU,EAASF,GAAgBR,EAAO,OAAS,EAAIN,EAAO,GAGpDiB,EAAQ,CAAC,KAAK,UAAUjB,EAAO,GAAG,EAClCkB,EAAWH,EAAS,KAAK,IAAIE,CAAK,EAAID,EAAS,KAAK,IAAIC,CAAK,EAC7DE,EAAWJ,EAAS,KAAK,IAAIE,CAAK,EAAID,EAAS,KAAK,IAAIC,CAAK,EAEnE,OAAOZ,EAAI,cAAcL,EAAO,QAAQ,EAAGkB,EAAUC,CAAQ,CACjE,CAEO,aAAaC,EAAa,CAC7B,OAAO,KAAK,YAAY,IAAIA,CAAG,CACnC,CAIO,UAAUC,EAAa,CAC1B,IAAMC,EAAQ,IAAI,MAAMD,CAAG,EAC3B,YAAK,OAAO,KAAKC,CAAK,EAEtBA,EAAM,KAAK,EAEJA,CACX,CAEO,UAAUC,EAAyB,CACtCA,EAAM,MAAM,EACZA,EAAM,YAAc,EACpB,KAAK,OAAS,KAAK,OAAO,OAAOpB,GAAKA,IAAMoB,CAAK,CACrD,CAEO,eAAgB,CACnB,KAAK,OAAO,QAAQA,GAAS,CACzBA,EAAM,MAAM,EACZA,EAAM,YAAc,CACxB,CAAC,EACD,KAAK,OAAS,CAAC,CACnB,CAIO,WAAWC,EAAaC,EAAa,CACxC,OAAID,EAAMC,IACN,CAACD,EAAKC,CAAG,EAAI,CAACA,EAAKD,CAAG,GACnB,KAAK,MAAM,KAAK,OAAO,GAAKC,EAAMD,EAAM,GAAKA,CAAG,CAC3D,CAGO,IAAIE,EAAa,CACpB,OAAO,KAAK,IAAI,KAAK,UAAUA,CAAG,CAAC,CACvC,CAEO,IAAIA,EAAa,CACpB,OAAO,KAAK,IAAI,KAAK,UAAUA,CAAG,CAAC,CACvC,CAEO,IAAIA,EAAa,CACpB,OAAO,KAAK,IAAI,KAAK,UAAUA,CAAG,CAAC,CACvC,CAEO,IAAIA,EAAa,CACpB,MAAO,GAAI,KAAK,IAAI,KAAK,UAAUA,CAAG,CAAC,CAC3C,CAEO,IAAIA,EAAa,CACpB,MAAO,GAAI,KAAK,IAAI,KAAK,UAAUA,CAAG,CAAC,CAC3C,CAEO,IAAIA,EAAa,CACpB,MAAO,GAAI,KAAK,IAAI,KAAK,UAAUA,CAAG,CAAC,CAC3C,CAGO,KAAKC,EAAa,CACrB,OAAO,KAAK,UAAU,KAAK,KAAKA,CAAG,CAAC,CACxC,CAEO,KAAKA,EAAa,CACrB,OAAO,KAAK,UAAU,KAAK,KAAKA,CAAG,CAAC,CACxC,CAEO,KAAKA,EAAa,CACrB,OAAO,KAAK,UAAU,KAAK,KAAK,EAAIA,CAAG,CAAC,CAC5C,CAEO,KAAKA,EAAa,CACrB,OAAO,KAAK,UAAU,KAAK,KAAK,EAAIA,CAAG,CAAC,CAC5C,CAIO,UAAUD,EAAa,CAC1B,OAAOA,EAAM,KAAK,GAAK,GAC3B,CAEO,UAAUE,EAAa,CAC1B,OAAOA,EAAM,IAAM,KAAK,EAC5B,CAIQ,aAAc,CACb,KAAK,sBAAsB,EAAE,EAKlCC,EAAU,iBAAiB,YAAaC,GAAK,CACzC,KAAK,OAASA,EAAE,QAAUD,EAAU,WAAaA,EAAU,MAAQ,EACnE,KAAK,OAAS,EAAEC,EAAE,QAAUD,EAAU,UAAYA,EAAU,OAAS,EACzE,CAAC,EACDA,EAAU,iBAAiB,YAAaC,GAAK,CACzC,KAAK,UAAY,EACrB,CAAC,EACDD,EAAU,iBAAiB,UAAWC,GAAK,CACvC,KAAK,UAAY,EACrB,CAAC,EACDD,EAAU,iBAAiB,QAASC,GAAK,CACrC,KAAK,aAAe,GACpB,WAAW,IAAM,KAAK,aAAe,GAAO,CAAC,CACjD,CAAC,EAGD,iBAAiB,UAAWA,GAAK,CACzBA,EAAE,QACN,KAAK,YAAY,IAAIA,EAAE,GAAG,CAC9B,CAAC,EAED,iBAAiB,QAASA,GAAK,CAC3B,KAAK,YAAY,OAAOA,EAAE,GAAG,CACjC,CAAC,CACL,CACJ,EC3QA,IAAqBC,EAArB,cAAuCC,CAAO,CAEnC,MACA,OACA,MACA,aACA,aAEA,SAAkB,CACrB,IAAMC,EAAO,IAAI,OAEjB,OAAAA,EAAK,KACD,CAAC,KAAK,MAAQ,EACd,CAAC,KAAK,OAAS,EACf,KAAK,MACL,KAAK,MACT,EAEOA,CACX,CAEO,KAAKC,EAA0B,CAClC,IAAMC,EAAID,EAAWE,EAASC,EAE9BF,EAAE,KAAK,EAEP,IAAMG,EAAK,KAAK,EAAIC,EAAO,MAAQ,EAC7BC,EAAK,CAAC,KAAK,EAAID,EAAO,OAAS,EACrCJ,EAAE,UAAUG,EAAIE,CAAE,EAElBL,EAAE,OAAO,KAAK,UAAU,KAAK,GAAG,CAAC,EAEjC,IAAMF,EAAO,KAAK,QAAQ,EAE1BE,EAAE,UAAY,KAAK,MACnBA,EAAE,YAAc,KAAK,aACrBA,EAAE,UAAY,KAAK,aACnBA,EAAE,KAAKF,CAAI,EACP,KAAK,cACLE,EAAE,OAAOF,CAAI,EAEjBE,EAAE,QAAQ,CACd,CAEO,SAASM,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEO,UAAUC,EAAgB,CAC7B,KAAK,OAASA,EACd,KAAK,QAAQ,CACjB,CAEO,SAASC,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEA,YAAYC,EAA4B,CACpC,MAAMA,CAAO,EACb,KAAK,MAAQA,GAAS,OAAS,GAC/B,KAAK,OAASA,GAAS,QAAU,GACjC,KAAK,MAAQA,GAAS,OAAS,QAC/B,KAAK,aAAeA,GAAS,cAAgB,QAC7C,KAAK,aAAeA,GAAS,cAAgB,EAC7C,KAAK,KAAK,CACd,CAEJ,ECtEA,IAAqBC,EAArB,cAAoCC,CAAO,CAEhC,WACA,MACA,aACA,aAEA,SAAkB,CACrB,IAAMC,EAAO,IAAI,OAEjB,OAAAA,EAAK,KACD,CAAC,KAAK,WAAa,EACnB,CAAC,KAAK,WAAa,EACnB,KAAK,WACL,KAAK,UACT,EAEOA,CACX,CAEO,KAAKC,EAA0B,CAClC,IAAMC,EAAID,EAAWE,EAASC,EAE9BF,EAAE,KAAK,EAEP,IAAMG,EAAK,KAAK,EAAIC,EAAO,MAAQ,EAC7BC,EAAK,CAAC,KAAK,EAAID,EAAO,OAAS,EACrCJ,EAAE,UAAUG,EAAIE,CAAE,EAElBL,EAAE,OAAO,KAAK,UAAU,KAAK,GAAG,CAAC,EAEjC,IAAMF,EAAO,KAAK,QAAQ,EAE1BE,EAAE,UAAY,KAAK,MACnBA,EAAE,YAAc,KAAK,aACrBA,EAAE,UAAY,KAAK,aACnBA,EAAE,KAAKF,CAAI,EACP,KAAK,cACLE,EAAE,OAAOF,CAAI,EAEjBE,EAAE,QAAQ,CACd,CAEO,cAAcM,EAAoB,CACrC,KAAK,WAAaA,EAClB,KAAK,QAAQ,CACjB,CAEO,SAASC,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEA,YAAYC,EAAyB,CACjC,MAAMA,CAAO,EACb,KAAK,WAAaA,GAAS,YAAc,GACzC,KAAK,MAAQA,GAAS,OAAS,QAC/B,KAAK,aAAeA,GAAS,cAAgB,QAC7C,KAAK,aAAeA,GAAS,cAAgB,EAC7C,KAAK,KAAK,CACd,CAEJ,EC7DA,IAAqBC,EAArB,cAAkCC,CAAO,CAE9B,KACA,KACA,MACA,aACA,aAEA,SAAkB,CACrB,IAAMC,EAAO,IAAI,OAEjB,OAAAA,EAAK,QACD,EAAG,EACH,KAAK,KACL,KAAK,KACL,EAAG,EACH,KAAK,GAAK,CACd,EAEOA,CACX,CAEO,KAAKC,EAA0B,CAClC,IAAMC,EAAID,EAAWE,EAASC,EAE9BF,EAAE,KAAK,EAEP,IAAMG,EAAK,KAAK,EAAIC,EAAO,MAAQ,EAC7BC,EAAK,CAAC,KAAK,EAAID,EAAO,OAAS,EACrCJ,EAAE,UAAUG,EAAIE,CAAE,EAElBL,EAAE,OAAO,KAAK,UAAU,KAAK,GAAG,CAAC,EAEjC,IAAMF,EAAO,KAAK,QAAQ,EAE1BE,EAAE,UAAY,KAAK,MACnBA,EAAE,YAAc,KAAK,aACrBA,EAAE,UAAY,KAAK,aACnBA,EAAE,KAAKF,CAAI,EACP,KAAK,cACLE,EAAE,OAAOF,CAAI,EAEjBE,EAAE,QAAQ,CACd,CAEO,QAAQM,EAAc,CACzB,KAAK,KAAOA,EACZ,KAAK,QAAQ,CACjB,CAEO,QAAQC,EAAc,CACzB,KAAK,KAAOA,EACZ,KAAK,QAAQ,CACjB,CAEO,SAASC,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEA,YAAYC,EAAuB,CAC/B,MAAMA,CAAO,EACb,KAAK,KAAOA,GAAS,MAAQ,GAC7B,KAAK,KAAOA,GAAS,MAAQ,GAC7B,KAAK,MAAQA,GAAS,OAAS,QAC/B,KAAK,aAAeA,GAAS,cAAgB,QAC7C,KAAK,aAAeA,GAAS,cAAgB,EAC7C,KAAK,KAAK,CACd,CAEJ,ECvEA,IAAqBC,EAArB,cAAoCC,CAAO,CAEhC,OACA,MACA,aACA,aAEA,SAAkB,CACrB,IAAMC,EAAO,IAAI,OAEjB,OAAAA,EAAK,QACD,EAAG,EACH,KAAK,OACL,KAAK,OACL,EAAG,EACH,KAAK,GAAK,CACd,EAEOA,CACX,CAEO,KAAKC,EAA0B,CAClC,IAAMC,EAAID,EAAWE,EAASC,EAE9BF,EAAE,KAAK,EAEP,IAAMG,EAAK,KAAK,EAAIC,EAAO,MAAQ,EAC7BC,EAAK,CAAC,KAAK,EAAID,EAAO,OAAS,EACrCJ,EAAE,UAAUG,EAAIE,CAAE,EAElBL,EAAE,OAAO,KAAK,UAAU,KAAK,GAAG,CAAC,EAEjC,IAAMF,EAAO,KAAK,QAAQ,EAE1BE,EAAE,UAAY,KAAK,MACnBA,EAAE,YAAc,KAAK,aACrBA,EAAE,UAAY,KAAK,aACnBA,EAAE,KAAKF,CAAI,EACP,KAAK,cACLE,EAAE,OAAOF,CAAI,EAEjBE,EAAE,QAAQ,CACd,CAEO,UAAUM,EAAgB,CAC7B,KAAK,OAASA,EACd,KAAK,QAAQ,CACjB,CAEO,SAASC,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEA,YAAYC,EAAyB,CACjC,MAAMA,CAAO,EACb,KAAK,OAASA,GAAS,QAAU,GACjC,KAAK,MAAQA,GAAS,OAAS,QAC/B,KAAK,aAAeA,GAAS,cAAgB,QAC7C,KAAK,aAAeA,GAAS,cAAgB,EAC7C,KAAK,KAAK,CACd,CAEJ,EC9DA,IAAqBC,EAArB,cAA4CC,CAAO,CAExC,MACA,OACA,MACA,aACA,aAEA,SAAkB,CACrB,IAAMC,EAAO,IAAI,OAEXC,EAAQ,KAAK,GAAK,EAAK,KAAK,MAC5BC,EAAW,KAAK,UAAU,KAAK,GAAG,EAClC,EAAI,KAAK,OAEf,QAASC,EAAI,EAAGA,EAAI,KAAK,MAAOA,IAAK,CACjC,IAAMC,EAAQD,EAAIF,EAAO,KAAK,GAAK,EAAIC,EACjCG,EAAK,EAAI,KAAK,IAAID,CAAK,EACvBE,EAAK,CAAC,EAAI,KAAK,IAAIF,CAAK,EAE1BD,IAAM,EAAGH,EAAK,OAAOK,EAAIC,CAAE,EAC1BN,EAAK,OAAOK,EAAIC,CAAE,CAC3B,CAEA,OAAAN,EAAK,UAAU,EAERA,CACX,CAEO,KAAKO,EAAoB,CAC5B,IAAMC,EAAID,EAAWE,EAASC,EAE9BF,EAAE,KAAK,EAEP,IAAMG,EAAK,KAAK,EAAIC,EAAO,MAAQ,EAC7BC,EAAK,CAAC,KAAK,EAAID,EAAO,OAAS,EAErCJ,EAAE,UAAUG,EAAIE,CAAE,EAElB,IAAMb,EAAO,KAAK,QAAQ,EAE1BQ,EAAE,UAAY,KAAK,MACnBA,EAAE,YAAc,KAAK,aACrBA,EAAE,UAAY,KAAK,aACnBA,EAAE,KAAKR,CAAI,EACP,KAAK,cACLQ,EAAE,OAAOR,CAAI,EAEjBQ,EAAE,QAAQ,CACd,CAEO,SAASM,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEO,UAAUC,EAAgB,CAC7B,KAAK,OAASA,EACd,KAAK,QAAQ,CACjB,CAEO,SAASC,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEA,YAAYC,EAAiC,CACzC,MAAMA,CAAO,EACb,KAAK,MAAQA,GAAS,OAAS,EAC/B,KAAK,OAASA,GAAS,QAAU,GACjC,KAAK,MAAQA,GAAS,OAAS,QAC/B,KAAK,aAAeA,GAAS,cAAgB,QAC7C,KAAK,aAAeA,GAAS,cAAgB,EAC7C,KAAK,KAAK,CACd,CAEJ,EC9EA,IAAqBC,EAArB,cAAiCC,CAAO,CAE7B,QACA,KACA,MAEA,SAAkB,CACrB,OAAO,IAAI,MACf,CACO,MAAO,CAAC,CAER,IAAK,CACR,KAAK,QAAU,EACnB,CAEO,MAAO,CACV,KAAK,QAAU,EACnB,CAEO,MAAMC,EAAgB,CACzBA,EAAO,KAAK,EAAI,CACpB,CAEO,WAAY,CACfC,EAAO,UAAU,EAAG,EAAGC,EAAO,MAAOA,EAAO,MAAM,CACtD,CAEO,KAAM,CACTD,EAAO,UAAY,KAAK,MACxBA,EAAO,SACH,KAAK,EAAI,KAAK,KAAO,EAAIC,EAAO,MAAQ,EACxC,CAAC,KAAK,EAAI,KAAK,KAAO,EAAIA,EAAO,OAAS,EAC1C,KAAK,KACL,KAAK,IACT,CACJ,CAEQ,SAASC,EAAeC,EAAe,CAC3CH,EAAO,UAAU,EAEjBA,EAAO,OAAOE,EAAQD,EAAO,MAAQ,EAAG,CAACE,EAAQF,EAAO,OAAS,CAAC,EAClED,EAAO,OAAO,KAAK,EAAIC,EAAO,MAAQ,EAAG,CAAC,KAAK,EAAIA,EAAO,OAAS,CAAC,EAEpED,EAAO,UAAY,KAAK,KACxBA,EAAO,YAAc,KAAK,MAC1BA,EAAO,OAAO,CAClB,CAIgB,KAAKI,EAAe,CAChC,IAAMF,EAAQ,KAAK,EACbC,EAAQ,KAAK,EAEnB,KAAK,GAAKC,EAAQ,KAAK,IAAI,KAAK,UAAU,KAAK,GAAG,CAAC,EACnD,KAAK,GAAKA,EAAQ,KAAK,IAAI,KAAK,UAAU,KAAK,GAAG,CAAC,EAC/C,KAAK,SACL,KAAK,SAASF,EAAOC,CAAK,EAC9B,KAAK,QAAQ,CACjB,CAEgB,KAAKE,EAAW,CAC5B,IAAMH,EAAQ,KAAK,EACbC,EAAQ,KAAK,EAEnB,KAAK,EAAIE,EACL,KAAK,SACL,KAAK,SAASH,EAAOC,CAAK,EAC9B,KAAK,QAAQ,CACjB,CAEgB,KAAKG,EAAW,CAC5B,IAAMJ,EAAQ,KAAK,EACbC,EAAQ,KAAK,EAEnB,KAAK,EAAIG,EACL,KAAK,SACL,KAAK,SAASJ,EAAOC,CAAK,EAC9B,KAAK,QAAQ,CACjB,CAEgB,KAAKE,EAAWC,EAAW,CACvC,IAAMJ,EAAQ,KAAK,EACbC,EAAQ,KAAK,EAEnB,KAAK,EAAIE,EACT,KAAK,EAAIC,EACL,KAAK,SACL,KAAK,SAASJ,EAAOC,CAAK,EAC9B,KAAK,QAAQ,CACjB,CAEgB,QAAQI,EAAY,CAChC,IAAML,EAAQ,KAAK,EACbC,EAAQ,KAAK,EAEnB,KAAK,GAAKI,EACN,KAAK,SACL,KAAK,SAASL,EAAOC,CAAK,EAC9B,KAAK,QAAQ,CACjB,CAEgB,QAAQK,EAAY,CAChC,IAAMN,EAAQ,KAAK,EACbC,EAAQ,KAAK,EAEnB,KAAK,GAAKK,EACN,KAAK,SACL,KAAK,SAASN,EAAOC,CAAK,EAC9B,KAAK,QAAQ,CACjB,CAIA,YAAYM,EAAsB,CAC9B,MAAMA,CAAO,EACb,KAAK,QAAUA,GAAS,SAAW,GACnC,KAAK,KAAOA,GAAS,MAAQ,EAC7B,KAAK,MAAQA,GAAS,OAAS,OACnC,CAEJ,ECvGA,IAAqBC,EAArB,cAAkCC,CAAO,CAE9B,QACA,MACA,WACA,SACA,MACA,SAEC,KAED,SAAkB,CACrB,IAAMC,EAAO,IAAI,OAEjBC,EAAI,KAAK,EAETA,EAAI,KAAO,KAAK,KAEhB,IAAMC,EAAUD,EAAI,YAAY,KAAK,OAAO,EACtCE,EAAQD,EAAQ,MAChBE,EAASF,EAAQ,wBAA0BA,EAAQ,yBAEzD,OAAAD,EAAI,QAAQ,EAEZD,EAAK,KAAK,CAACG,EAAQ,EAAG,CAACC,EAAS,EAAGD,EAAOC,CAAM,EAEzCJ,CACX,CAEO,KAAKK,EAAoB,CAC5B,IAAMC,EAAID,EAAWE,EAASN,EAE9BK,EAAE,KAAK,EAEP,IAAME,EAAK,KAAK,EAAIC,EAAO,MAAQ,EAC7BC,EAAK,CAAC,KAAK,EAAID,EAAO,OAAS,EACrCH,EAAE,UAAUE,EAAIE,CAAE,EAElBJ,EAAE,OAAO,KAAK,UAAU,KAAK,GAAG,CAAC,EAEjCA,EAAE,KAAO,KAAK,KACdA,EAAE,UAAY,KAAK,MACnBA,EAAE,UAAY,KAAK,MACnBA,EAAE,aAAe,KAAK,SAEtBA,EAAE,SAAS,KAAK,QAAS,EAAG,CAAC,EAE7BA,EAAE,QAAQ,CACd,CAIO,WAAWK,EAAiB,CAC/B,KAAK,QAAUA,EACf,KAAK,QAAQ,CACjB,CAEO,SAASC,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEO,YAAYC,EAAkB,CACjC,KAAK,SAAWA,EAChB,KAAK,KAAO,GAAG,KAAK,QAAQ,MAAM,KAAK,UAAU,GACjD,KAAK,QAAQ,CACjB,CAEO,cAAcC,EAAoB,CACrC,KAAK,WAAaA,EAClB,KAAK,KAAO,GAAG,KAAK,QAAQ,MAAM,KAAK,UAAU,GACjD,KAAK,QAAQ,CACjB,CAEO,SAASC,EAAwB,CACpC,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEO,YAAYC,EAA8B,CAC7C,KAAK,SAAWA,EAChB,KAAK,QAAQ,CACjB,CAIA,YAAYC,EAAuB,CAC/B,MAAMA,CAAO,EAEb,KAAK,QAAUA,GAAS,SAAW,GACnC,KAAK,MAAQA,GAAS,OAAS,QAC/B,KAAK,WAAaA,GAAS,YAAc,QACzC,KAAK,SAAWA,GAAS,UAAY,GACrC,KAAK,MAAQA,GAAS,OAAS,SAC/B,KAAK,SAAWA,GAAS,UAAY,SAErC,KAAK,KAAO,GAAG,KAAK,QAAQ,MAAM,KAAK,UAAU,GAEjD,KAAK,KAAK,CACd,CACJ,ECpHA,IAAqBC,EAArB,cAAyCC,CAAO,CAErC,IACA,MACA,OACA,aACA,aAEG,IAEH,SAAkB,CACrB,IAAMC,EAAO,IAAI,OAEjB,OAAAA,EAAK,KACD,CAAC,KAAK,MAAQ,EACd,CAAC,KAAK,OAAS,EACf,KAAK,MACL,KAAK,MACT,EAEOA,CACX,CAEO,KAAKC,EAAoB,CAC5B,IAAMC,EAAID,EAAWE,EAASC,EAE9BF,EAAE,KAAK,EAEP,IAAMG,EAAK,KAAK,EAAIC,EAAO,MAAQ,EAC7BC,EAAK,CAAC,KAAK,EAAID,EAAO,OAAS,EACrCJ,EAAE,UAAUG,EAAIE,CAAE,EAElBL,EAAE,OAAO,KAAK,UAAU,KAAK,GAAG,CAAC,EAEjCA,EAAE,YAAc,KAAK,aACrBA,EAAE,UAAY,KAAK,aACnBA,EAAE,UACE,KAAK,IACL,EAAG,EACH,KAAK,IAAI,MACT,KAAK,IAAI,OACT,CAAC,KAAK,MAAQ,EACd,CAAC,KAAK,OAAS,EACf,KAAK,MAAO,KAAK,MACrB,EACI,KAAK,cACLA,EAAE,OAAO,KAAK,QAAQ,CAAC,EAE3BA,EAAE,QAAQ,CACd,CAIO,OAAOM,EAAa,CACvB,KAAK,IAAMA,EACX,KAAK,QAAQ,CACjB,CAEO,SAASC,EAAe,CAC3B,KAAK,MAAQA,EACb,KAAK,QAAQ,CACjB,CAEO,UAAUC,EAAgB,CAC7B,KAAK,OAASA,EACd,KAAK,QAAQ,CACjB,CAIA,YAAYC,EAA8B,CACtC,MAAMA,CAAO,EAEb,KAAK,IAAMA,GAAS,KAAO,GAC3B,KAAK,IAAM,IAAI,MACf,KAAK,IAAI,IAAM,KAAK,IAEpB,KAAK,MAAQA,GAAS,OAAS,KAAK,IAAI,MACxC,KAAK,OAASA,GAAS,QAAU,KAAK,IAAI,OAE1C,KAAK,aAAeA,GAAS,cAAgB,QAC7C,KAAK,aAAeA,GAAS,cAAgB,EAE7C,KAAK,KAAK,CACd,CACJ,EXnFA,IAAMC,EAAW,CAEb,OAAAC,EACA,OAAAC,EAGA,UAAAC,EACA,OAAAC,EACA,KAAAC,EACA,OAAAC,EACA,eAAAC,EACA,IAAAC,EACA,KAAAC,EACA,YAAAC,EAGA,SAAAC,EACA,eAAAC,EACA,OAAAC,EACA,IAAAC,CACJ,EAEOC,EAAQf","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","Engine","options","deg","rad","steps","dir","x","y","dX","dY","layer","dL","Engine","_Engine","scene","loop","sprite","layer","targetIndex","s","maxFPS","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","radA","radB","color","options","Circle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radius","color","options","RegularPolygon","Sprite","path","step","rotation","i","theta","px","py","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","path","ctx","metrics","width","height","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/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 // 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 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) * 2 < (bBox1.width + bBox2.width) &&\r\n Math.abs(bBox1.y - bBox2.y) * 2 < (bBox1.height + bBox2.height);\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.max(b1Top, b2Top);\r\n const xMax = Math.min(b1Right, b2Right);\r\n const yMax = Math.min(b1Bottom, b2Bottom);\r\n\r\n const width = xMax - xMin;\r\n const height = yMax - yMin;\r\n\r\n if (width <= 0 || height <= 0) return false;\r\n\r\n // Create offscreen canvas just for intersection region\r\n const canvas = document.createElement('canvas');\r\n canvas.width = width;\r\n canvas.height = height;\r\n const ctx = canvas.getContext('2d')!;\r\n\r\n // Draw first sprite\r\n ctx.save();\r\n ctx.translate(-xMin, -yMin);\r\n ctx.fillStyle = 'red';\r\n ctx.fill(this.getPath());\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(-xMin, -yMin);\r\n ctx.fillStyle = 'blue';\r\n ctx.fill(sprite.getPath());\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\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 public maxFPS: number = 24;\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 }\r\n\r\n public resumeLoop() {\r\n this.loopRunning = true;\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 this.loopRunning = true;\r\n\r\n while (this.loopRunning) {\r\n await loop();\r\n await this.wait(1000 / maxFPS);\r\n }\r\n }\r\n\r\n public refresh() {\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n this.sceneMap[this.currentScene]?.sprites.forEach(sprite => {\r\n if (!sprite.hidden)\r\n sprite.draw();\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 isHovered(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 isKeyPressed(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: 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): 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.getPath();\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.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\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: this.sideLength,\r\n height: 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.getPath();\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.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: this.radX * 2,\r\n height: 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.getPath();\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.refresh();\r\n }\r\n\r\n public setRadY(radY: number) {\r\n this.radY = radY;\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.getPath();\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.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\r\n const step = (Math.PI * 2) / this.sides;\r\n const rotation = this.toRadians(this.dir);\r\n const r = this.radius;\r\n\r\n for (let i = 0; i < this.sides; i++) {\r\n const theta = i * step - Math.PI / 2 + rotation;\r\n const px = r * Math.cos(theta);\r\n const py = -r * Math.sin(theta);\r\n\r\n if (i === 0) path.moveTo(px, py);\r\n else path.lineTo(px, py);\r\n }\r\n\r\n path.closePath();\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\r\n c.translate(cX, cY);\r\n\r\n const path = this.getPath();\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.refresh();\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\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 ereaseAll() {\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.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.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.refresh();\r\n }\r\n\r\n public setAlign(align: CanvasTextAlign) {\r\n this.align = align;\r\n this.refresh();\r\n }\r\n\r\n public setBaseline(baseline: CanvasTextBaseline) {\r\n this.baseline = baseline;\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.getPath());\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.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\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","Engine","options","sprite","bBox1","bBox2","b1Left","b1Top","b1Right","b1Bottom","b2Left","b2Top","b2Right","b2Bottom","xMin","yMin","xMax","yMax","width","height","canvas","ctx","img1","img2","i","deg","rad","steps","dir","x","y","dX","dY","layer","dL","Engine","_Engine","scene","loop","sprite","layer","targetIndex","s","maxFPS","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","rotation","r","i","theta","px","py","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"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
interface BoundingBox {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
}
|
|
1
7
|
interface SpriteOptions {
|
|
2
8
|
x?: number;
|
|
3
9
|
y?: number;
|
|
@@ -13,10 +19,12 @@ declare abstract class Sprite {
|
|
|
13
19
|
scene: string;
|
|
14
20
|
hidden: boolean;
|
|
15
21
|
layer: number;
|
|
22
|
+
abstract getBoundingBox(): BoundingBox;
|
|
16
23
|
abstract getPath(): Path2D;
|
|
17
24
|
abstract draw(stamping?: boolean): void;
|
|
18
25
|
protected refresh(): void;
|
|
19
26
|
constructor(options?: SpriteOptions);
|
|
27
|
+
touching(sprite: Sprite): boolean;
|
|
20
28
|
protected toRadians(deg: number): number;
|
|
21
29
|
protected toDegrees(rad: number): number;
|
|
22
30
|
move(steps: number): void;
|
|
@@ -57,6 +65,8 @@ declare class Engine {
|
|
|
57
65
|
static init(): Engine;
|
|
58
66
|
changeScene(scene: string): void;
|
|
59
67
|
setLoop(scene: string, loop: GameLoop): void;
|
|
68
|
+
pauseLoop(): void;
|
|
69
|
+
resumeLoop(): void;
|
|
60
70
|
addSprite(sprite: Sprite): void;
|
|
61
71
|
removeSprite(sprite: Sprite): void;
|
|
62
72
|
setMaxFramesPerSecond(maxFPS: number): Promise<void>;
|
|
@@ -97,11 +107,13 @@ interface RectangleOptions extends SpriteOptions {
|
|
|
97
107
|
outlineWidth?: number;
|
|
98
108
|
}
|
|
99
109
|
declare class Rectangle extends Sprite {
|
|
110
|
+
discriminant: string;
|
|
100
111
|
width: number;
|
|
101
112
|
height: number;
|
|
102
113
|
color: string;
|
|
103
114
|
outlineColor: string;
|
|
104
115
|
outlineWidth: number;
|
|
116
|
+
getBoundingBox(): BoundingBox;
|
|
105
117
|
getPath(): Path2D;
|
|
106
118
|
draw(stamping?: boolean): void;
|
|
107
119
|
setWidth(width: number): void;
|
|
@@ -117,10 +129,12 @@ interface SquareOptions extends SpriteOptions {
|
|
|
117
129
|
outlineWidth?: number;
|
|
118
130
|
}
|
|
119
131
|
declare class Square extends Sprite {
|
|
132
|
+
discriminant: string;
|
|
120
133
|
sideLength: number;
|
|
121
134
|
color: string;
|
|
122
135
|
outlineColor: string;
|
|
123
136
|
outlineWidth: number;
|
|
137
|
+
getBoundingBox(): BoundingBox;
|
|
124
138
|
getPath(): Path2D;
|
|
125
139
|
draw(stamping?: boolean): void;
|
|
126
140
|
setSideLength(sideLength: number): void;
|
|
@@ -129,22 +143,24 @@ declare class Square extends Sprite {
|
|
|
129
143
|
}
|
|
130
144
|
|
|
131
145
|
interface OvalOptions extends SpriteOptions {
|
|
132
|
-
|
|
133
|
-
|
|
146
|
+
radX?: number;
|
|
147
|
+
radY?: number;
|
|
134
148
|
color?: string;
|
|
135
149
|
outlineColor?: string;
|
|
136
150
|
outlineWidth?: number;
|
|
137
151
|
}
|
|
138
152
|
declare class Oval extends Sprite {
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
discriminant: string;
|
|
154
|
+
radX: number;
|
|
155
|
+
radY: number;
|
|
141
156
|
color: string;
|
|
142
157
|
outlineColor: string;
|
|
143
158
|
outlineWidth: number;
|
|
159
|
+
getBoundingBox(): BoundingBox;
|
|
144
160
|
getPath(): Path2D;
|
|
145
161
|
draw(stamping?: boolean): void;
|
|
146
|
-
|
|
147
|
-
|
|
162
|
+
setRadX(radX: number): void;
|
|
163
|
+
setRadY(radY: number): void;
|
|
148
164
|
setColor(color: string): void;
|
|
149
165
|
constructor(options?: OvalOptions);
|
|
150
166
|
}
|
|
@@ -156,10 +172,12 @@ interface CircleOptions extends SpriteOptions {
|
|
|
156
172
|
outlineWidth?: number;
|
|
157
173
|
}
|
|
158
174
|
declare class Circle extends Sprite {
|
|
175
|
+
discriminant: string;
|
|
159
176
|
radius: number;
|
|
160
177
|
color: string;
|
|
161
178
|
outlineColor: string;
|
|
162
179
|
outlineWidth: number;
|
|
180
|
+
getBoundingBox(): BoundingBox;
|
|
163
181
|
getPath(): Path2D;
|
|
164
182
|
draw(stamping?: boolean): void;
|
|
165
183
|
setRadius(radius: number): void;
|
|
@@ -175,11 +193,13 @@ interface RegularPolygonOptions extends SpriteOptions {
|
|
|
175
193
|
outlineWidth?: number;
|
|
176
194
|
}
|
|
177
195
|
declare class RegularPolygon extends Sprite {
|
|
196
|
+
discriminant: string;
|
|
178
197
|
sides: number;
|
|
179
198
|
radius: number;
|
|
180
199
|
color: string;
|
|
181
200
|
outlineColor: string;
|
|
182
201
|
outlineWidth: number;
|
|
202
|
+
getBoundingBox(): BoundingBox;
|
|
183
203
|
getPath(): Path2D;
|
|
184
204
|
draw(stamping?: boolean): void;
|
|
185
205
|
setSides(sides: number): void;
|
|
@@ -194,9 +214,11 @@ interface PenOptions extends SpriteOptions {
|
|
|
194
214
|
color?: string;
|
|
195
215
|
}
|
|
196
216
|
declare class Pen extends Sprite {
|
|
217
|
+
discriminant: string;
|
|
197
218
|
drawing: boolean;
|
|
198
219
|
size: number;
|
|
199
220
|
color: string;
|
|
221
|
+
getBoundingBox(): BoundingBox;
|
|
200
222
|
getPath(): Path2D;
|
|
201
223
|
draw(): void;
|
|
202
224
|
up(): void;
|
|
@@ -225,6 +247,7 @@ interface TextOptions extends SpriteOptions {
|
|
|
225
247
|
baseline?: CanvasTextBaseline;
|
|
226
248
|
}
|
|
227
249
|
declare class Text extends Sprite {
|
|
250
|
+
discriminant: string;
|
|
228
251
|
content: string;
|
|
229
252
|
color: string;
|
|
230
253
|
fontFamily: string;
|
|
@@ -232,6 +255,7 @@ declare class Text extends Sprite {
|
|
|
232
255
|
align: CanvasTextAlign;
|
|
233
256
|
baseline: CanvasTextBaseline;
|
|
234
257
|
private font;
|
|
258
|
+
getBoundingBox(): BoundingBox;
|
|
235
259
|
getPath(): Path2D;
|
|
236
260
|
draw(stamping?: boolean): void;
|
|
237
261
|
setContent(content: string): void;
|
|
@@ -251,12 +275,14 @@ interface ImageSpriteOptions extends SpriteOptions {
|
|
|
251
275
|
outlineWidth?: number;
|
|
252
276
|
}
|
|
253
277
|
declare class ImageSprite extends Sprite {
|
|
278
|
+
discriminant: string;
|
|
254
279
|
src: string;
|
|
255
280
|
width: number;
|
|
256
281
|
height: number;
|
|
257
282
|
outlineColor: string;
|
|
258
283
|
outlineWidth: number;
|
|
259
284
|
protected img: HTMLImageElement;
|
|
285
|
+
getBoundingBox(): BoundingBox;
|
|
260
286
|
getPath(): Path2D;
|
|
261
287
|
draw(stamping?: boolean): void;
|
|
262
288
|
setSrc(src: string): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
interface BoundingBox {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
}
|
|
1
7
|
interface SpriteOptions {
|
|
2
8
|
x?: number;
|
|
3
9
|
y?: number;
|
|
@@ -13,10 +19,12 @@ declare abstract class Sprite {
|
|
|
13
19
|
scene: string;
|
|
14
20
|
hidden: boolean;
|
|
15
21
|
layer: number;
|
|
22
|
+
abstract getBoundingBox(): BoundingBox;
|
|
16
23
|
abstract getPath(): Path2D;
|
|
17
24
|
abstract draw(stamping?: boolean): void;
|
|
18
25
|
protected refresh(): void;
|
|
19
26
|
constructor(options?: SpriteOptions);
|
|
27
|
+
touching(sprite: Sprite): boolean;
|
|
20
28
|
protected toRadians(deg: number): number;
|
|
21
29
|
protected toDegrees(rad: number): number;
|
|
22
30
|
move(steps: number): void;
|
|
@@ -57,6 +65,8 @@ declare class Engine {
|
|
|
57
65
|
static init(): Engine;
|
|
58
66
|
changeScene(scene: string): void;
|
|
59
67
|
setLoop(scene: string, loop: GameLoop): void;
|
|
68
|
+
pauseLoop(): void;
|
|
69
|
+
resumeLoop(): void;
|
|
60
70
|
addSprite(sprite: Sprite): void;
|
|
61
71
|
removeSprite(sprite: Sprite): void;
|
|
62
72
|
setMaxFramesPerSecond(maxFPS: number): Promise<void>;
|
|
@@ -97,11 +107,13 @@ interface RectangleOptions extends SpriteOptions {
|
|
|
97
107
|
outlineWidth?: number;
|
|
98
108
|
}
|
|
99
109
|
declare class Rectangle extends Sprite {
|
|
110
|
+
discriminant: string;
|
|
100
111
|
width: number;
|
|
101
112
|
height: number;
|
|
102
113
|
color: string;
|
|
103
114
|
outlineColor: string;
|
|
104
115
|
outlineWidth: number;
|
|
116
|
+
getBoundingBox(): BoundingBox;
|
|
105
117
|
getPath(): Path2D;
|
|
106
118
|
draw(stamping?: boolean): void;
|
|
107
119
|
setWidth(width: number): void;
|
|
@@ -117,10 +129,12 @@ interface SquareOptions extends SpriteOptions {
|
|
|
117
129
|
outlineWidth?: number;
|
|
118
130
|
}
|
|
119
131
|
declare class Square extends Sprite {
|
|
132
|
+
discriminant: string;
|
|
120
133
|
sideLength: number;
|
|
121
134
|
color: string;
|
|
122
135
|
outlineColor: string;
|
|
123
136
|
outlineWidth: number;
|
|
137
|
+
getBoundingBox(): BoundingBox;
|
|
124
138
|
getPath(): Path2D;
|
|
125
139
|
draw(stamping?: boolean): void;
|
|
126
140
|
setSideLength(sideLength: number): void;
|
|
@@ -129,22 +143,24 @@ declare class Square extends Sprite {
|
|
|
129
143
|
}
|
|
130
144
|
|
|
131
145
|
interface OvalOptions extends SpriteOptions {
|
|
132
|
-
|
|
133
|
-
|
|
146
|
+
radX?: number;
|
|
147
|
+
radY?: number;
|
|
134
148
|
color?: string;
|
|
135
149
|
outlineColor?: string;
|
|
136
150
|
outlineWidth?: number;
|
|
137
151
|
}
|
|
138
152
|
declare class Oval extends Sprite {
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
discriminant: string;
|
|
154
|
+
radX: number;
|
|
155
|
+
radY: number;
|
|
141
156
|
color: string;
|
|
142
157
|
outlineColor: string;
|
|
143
158
|
outlineWidth: number;
|
|
159
|
+
getBoundingBox(): BoundingBox;
|
|
144
160
|
getPath(): Path2D;
|
|
145
161
|
draw(stamping?: boolean): void;
|
|
146
|
-
|
|
147
|
-
|
|
162
|
+
setRadX(radX: number): void;
|
|
163
|
+
setRadY(radY: number): void;
|
|
148
164
|
setColor(color: string): void;
|
|
149
165
|
constructor(options?: OvalOptions);
|
|
150
166
|
}
|
|
@@ -156,10 +172,12 @@ interface CircleOptions extends SpriteOptions {
|
|
|
156
172
|
outlineWidth?: number;
|
|
157
173
|
}
|
|
158
174
|
declare class Circle extends Sprite {
|
|
175
|
+
discriminant: string;
|
|
159
176
|
radius: number;
|
|
160
177
|
color: string;
|
|
161
178
|
outlineColor: string;
|
|
162
179
|
outlineWidth: number;
|
|
180
|
+
getBoundingBox(): BoundingBox;
|
|
163
181
|
getPath(): Path2D;
|
|
164
182
|
draw(stamping?: boolean): void;
|
|
165
183
|
setRadius(radius: number): void;
|
|
@@ -175,11 +193,13 @@ interface RegularPolygonOptions extends SpriteOptions {
|
|
|
175
193
|
outlineWidth?: number;
|
|
176
194
|
}
|
|
177
195
|
declare class RegularPolygon extends Sprite {
|
|
196
|
+
discriminant: string;
|
|
178
197
|
sides: number;
|
|
179
198
|
radius: number;
|
|
180
199
|
color: string;
|
|
181
200
|
outlineColor: string;
|
|
182
201
|
outlineWidth: number;
|
|
202
|
+
getBoundingBox(): BoundingBox;
|
|
183
203
|
getPath(): Path2D;
|
|
184
204
|
draw(stamping?: boolean): void;
|
|
185
205
|
setSides(sides: number): void;
|
|
@@ -194,9 +214,11 @@ interface PenOptions extends SpriteOptions {
|
|
|
194
214
|
color?: string;
|
|
195
215
|
}
|
|
196
216
|
declare class Pen extends Sprite {
|
|
217
|
+
discriminant: string;
|
|
197
218
|
drawing: boolean;
|
|
198
219
|
size: number;
|
|
199
220
|
color: string;
|
|
221
|
+
getBoundingBox(): BoundingBox;
|
|
200
222
|
getPath(): Path2D;
|
|
201
223
|
draw(): void;
|
|
202
224
|
up(): void;
|
|
@@ -225,6 +247,7 @@ interface TextOptions extends SpriteOptions {
|
|
|
225
247
|
baseline?: CanvasTextBaseline;
|
|
226
248
|
}
|
|
227
249
|
declare class Text extends Sprite {
|
|
250
|
+
discriminant: string;
|
|
228
251
|
content: string;
|
|
229
252
|
color: string;
|
|
230
253
|
fontFamily: string;
|
|
@@ -232,6 +255,7 @@ declare class Text extends Sprite {
|
|
|
232
255
|
align: CanvasTextAlign;
|
|
233
256
|
baseline: CanvasTextBaseline;
|
|
234
257
|
private font;
|
|
258
|
+
getBoundingBox(): BoundingBox;
|
|
235
259
|
getPath(): Path2D;
|
|
236
260
|
draw(stamping?: boolean): void;
|
|
237
261
|
setContent(content: string): void;
|
|
@@ -251,12 +275,14 @@ interface ImageSpriteOptions extends SpriteOptions {
|
|
|
251
275
|
outlineWidth?: number;
|
|
252
276
|
}
|
|
253
277
|
declare class ImageSprite extends Sprite {
|
|
278
|
+
discriminant: string;
|
|
254
279
|
src: string;
|
|
255
280
|
width: number;
|
|
256
281
|
height: number;
|
|
257
282
|
outlineColor: string;
|
|
258
283
|
outlineWidth: number;
|
|
259
284
|
protected img: HTMLImageElement;
|
|
285
|
+
getBoundingBox(): BoundingBox;
|
|
260
286
|
getPath(): Path2D;
|
|
261
287
|
draw(stamping?: boolean): void;
|
|
262
288
|
setSrc(src: string): void;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var i=document.getElementById("game-window")||document.createElement("canvas"),o=i.getContext("2d"),l=document.createElement("canvas"),n=l.getContext("2d");l.id="pen-canvas";var g=16/9,u;function M(c){u=c,i.width=g*u,i.height=u,l.width=g*u,l.height=u}function O(c){g=c,i.width=g*u,i.height=u,l.width=g*u,l.height=u}i.parentElement?.insertBefore(l,i);M(500);var a=class{x;y;dir;scene;hidden;layer;refresh(){p.init().refresh()}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,p.init().addSprite(this)}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,e){this.dir=90-this.toDegrees(Math.atan2(e,t)),this.refresh()}setX(t){this.x=t,this.refresh()}setY(t){this.y=t,this.refresh()}goTo(t,e){this.x=t,this.y=e,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 p=class c{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;sounds=[];mouseX=0;mouseY=0;mouseDown=!1;mouseClicked=!1;keysPressed=new Set;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new c),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,e){if(!this.sceneMap[t]){this.sceneMap[t]={sprites:[],loop:e},t===this.currentScene&&this.changeScene(t);return}this.sceneMap[t].loop=e,t===this.currentScene&&this.changeScene(t)}addSprite(t){let{scene:e,layer:s}=t;if(!this.sceneMap[e]){this.sceneMap[e]={sprites:[t],loop:null};return}let r=this.sceneMap[e].sprites.findIndex(h=>h.layer>s);if(r===-1){this.sceneMap[e].sprites.push(t);return}this.sceneMap[e].sprites.splice(r,0,t),this.refresh()}removeSprite(t){let{scene:e}=t;this.sceneMap[e]&&(this.sceneMap[e].sprites=this.sceneMap[e].sprites.filter(s=>s!==t),this.refresh())}async setMaxFramesPerSecond(t){this.maxFPS=t;let e=this.gameLoop;if(e)for(this.loopRunning=!0;this.loopRunning;)await e(),await this.wait(1e3/t)}refresh(){o.clearRect(0,0,i.width,i.height),this.sceneMap[this.currentScene]?.sprites.forEach(t=>{t.hidden||t.draw()})}async wait(t){return new Promise(e=>setTimeout(e,t))}async waitUntil(t){return new Promise(e=>{let s=()=>{t()?e():setTimeout(s,1e3/this.maxFPS)};s()})}isHovered(t){let{mouseX:e,mouseY:s}=this,r=e+i.width/2,h=i.height/2-s,b=r-(t.x+i.width/2),m=h-(i.height/2-t.y),d=-this.toRadians(t.dir),W=b*Math.cos(d)-m*Math.sin(d),R=b*Math.sin(d)+m*Math.cos(d);return o.isPointInPath(t.getPath(),W,R)}isKeyPressed(t){return this.keysPressed.has(t)}playSound(t){let e=new Audio(t);return this.sounds.push(e),e.play(),e}stopSound(t){t.pause(),t.currentTime=0,this.sounds=this.sounds.filter(e=>e!==t)}stopAllSounds(){this.sounds.forEach(t=>{t.pause(),t.currentTime=0}),this.sounds=[]}pickRandom(t,e){return t>e&&([t,e]=[e,t]),Math.floor(Math.random()*(e-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),l.addEventListener("mousemove",t=>{this.mouseX=t.clientX-l.offsetLeft-l.width/2,this.mouseY=-(t.clientY-l.offsetTop-l.height/2)}),l.addEventListener("mousedown",t=>{this.mouseDown=!0}),l.addEventListener("mouseup",t=>{this.mouseDown=!1}),l.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 f=class extends a{width;height;color;outlineColor;outlineWidth;getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let e=t?n:o;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir));let h=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(h),this.outlineWidth&&e.stroke(h),e.restore()}setWidth(t){this.width=t,this.refresh()}setHeight(t){this.height=t,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 x=class extends a{sideLength;color;outlineColor;outlineWidth;getPath(){let t=new Path2D;return t.rect(-this.sideLength/2,-this.sideLength/2,this.sideLength,this.sideLength),t}draw(t){let e=t?n:o;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir));let h=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(h),this.outlineWidth&&e.stroke(h),e.restore()}setSideLength(t){this.sideLength=t,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 y=class extends a{radA;radB;color;outlineColor;outlineWidth;getPath(){let t=new Path2D;return t.ellipse(0,0,this.radA,this.radB,0,0,Math.PI*2),t}draw(t){let e=t?n:o;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir));let h=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(h),this.outlineWidth&&e.stroke(h),e.restore()}setRadA(t){this.radA=t,this.refresh()}setRadB(t){this.radB=t,this.refresh()}setColor(t){this.color=t,this.refresh()}constructor(t){super(t),this.radA=t?.radA??25,this.radB=t?.radB??25,this.color=t?.color??"black",this.outlineColor=t?.outlineColor??"black",this.outlineWidth=t?.outlineWidth??0,this.draw()}};var w=class extends a{radius;color;outlineColor;outlineWidth;getPath(){let t=new Path2D;return t.ellipse(0,0,this.radius,this.radius,0,0,Math.PI*2),t}draw(t){let e=t?n:o;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir));let h=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(h),this.outlineWidth&&e.stroke(h),e.restore()}setRadius(t){this.radius=t,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 S=class extends a{sides;radius;color;outlineColor;outlineWidth;getPath(){let t=new Path2D,e=Math.PI*2/this.sides,s=this.toRadians(this.dir),r=this.radius;for(let h=0;h<this.sides;h++){let b=h*e-Math.PI/2+s,m=r*Math.cos(b),d=-r*Math.sin(b);h===0?t.moveTo(m,d):t.lineTo(m,d)}return t.closePath(),t}draw(t){let e=t?n:o;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r);let h=this.getPath();e.fillStyle=this.color,e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.fill(h),this.outlineWidth&&e.stroke(h),e.restore()}setSides(t){this.sides=t,this.refresh()}setRadius(t){this.radius=t,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 v=class extends a{drawing;size;color;getPath(){return new Path2D}draw(){}up(){this.drawing=!1}down(){this.drawing=!0}stamp(t){t.draw(!0)}ereaseAll(){n.clearRect(0,0,i.width,i.height)}dot(){n.fillStyle=this.color,n.fillRect(this.x-this.size/2+i.width/2,-this.y-this.size/2+i.height/2,this.size,this.size)}drawLine(t,e){n.beginPath(),n.moveTo(t+i.width/2,-e+i.height/2),n.lineTo(this.x+i.width/2,-this.y+i.height/2),n.lineWidth=this.size,n.strokeStyle=this.color,n.stroke()}move(t){let e=this.x,s=this.y;this.x+=t*Math.sin(this.toRadians(this.dir)),this.y+=t*Math.cos(this.toRadians(this.dir)),this.drawing&&this.drawLine(e,s),this.refresh()}setX(t){let e=this.x,s=this.y;this.x=t,this.drawing&&this.drawLine(e,s),this.refresh()}setY(t){let e=this.x,s=this.y;this.y=t,this.drawing&&this.drawLine(e,s),this.refresh()}goTo(t,e){let s=this.x,r=this.y;this.x=t,this.y=e,this.drawing&&this.drawLine(s,r),this.refresh()}changeX(t){let e=this.x,s=this.y;this.x+=t,this.drawing&&this.drawLine(e,s),this.refresh()}changeY(t){let e=this.x,s=this.y;this.y+=t,this.drawing&&this.drawLine(e,s),this.refresh()}constructor(t){super(t),this.drawing=t?.drawing??!1,this.size=t?.size??5,this.color=t?.color??"black"}};var C=class extends a{content;color;fontFamily;fontSize;align;baseline;font;getPath(){let t=new Path2D;o.save(),o.font=this.font;let e=o.measureText(this.content),s=e.width,r=e.actualBoundingBoxAscent+e.actualBoundingBoxDescent;return o.restore(),t.rect(-s/2,-r/2,s,r),t}draw(t){let e=t?n:o;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir)),e.font=this.font,e.fillStyle=this.color,e.textAlign=this.align,e.textBaseline=this.baseline,e.fillText(this.content,0,0),e.restore()}setContent(t){this.content=t,this.refresh()}setColor(t){this.color=t,this.refresh()}setFontSize(t){this.fontSize=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.refresh()}setFontFamily(t){this.fontFamily=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.refresh()}setAlign(t){this.align=t,this.refresh()}setBaseline(t){this.baseline=t,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 P=class extends a{src;width;height;outlineColor;outlineWidth;img;getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let e=t?n:o;e.save();let s=this.x+i.width/2,r=-this.y+i.height/2;e.translate(s,r),e.rotate(this.toRadians(this.dir)),e.strokeStyle=this.outlineColor,e.lineWidth=this.outlineWidth,e.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height),this.outlineWidth&&e.stroke(this.getPath()),e.restore()}setSrc(t){this.src=t,this.refresh()}setWidth(t){this.width=t,this.refresh()}setHeight(t){this.height=t,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:p,Sprite:a,Rectangle:f,Square:x,Oval:y,Circle:w,RegularPolygon:S,Pen:v,Text:C,ImageSprite:P,setScale:M,setAspectRatio:O,canvas:i,ctx:o},xt=k;export{w as Circle,p as Engine,P as ImageSprite,y as Oval,v as Pen,f as Rectangle,S as RegularPolygon,a as Sprite,x as Square,C as Text,i as canvas,o as ctx,xt as default,O as setAspectRatio,M as setScale};
|
|
1
|
+
var s=document.getElementById("game-window")||document.createElement("canvas"),h=s.getContext("2d"),l=document.createElement("canvas"),o=l.getContext("2d");l.id="pen-canvas";var y=16/9,d;function Y(c){d=c,s.width=y*d,s.height=d,l.width=y*d,l.height=d}function I(c){y=c,s.width=y*d,s.height=d,l.width=y*d,l.height=d}s.parentElement?.insertBefore(l,s);Y(500);var a=class{x;y;dir;scene;hidden;layer;refresh(){b.init().refresh()}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)*2<i.width+e.width&&Math.abs(i.y-e.y)*2<i.height+e.height))return!1;let r=i.x-i.width/2,g=i.y-i.height/2,m=i.x+i.width/2,p=i.y+i.height/2,W=e.x-e.width/2,L=e.y-e.height/2,z=e.x+e.width/2,E=e.y+e.height/2,k=Math.max(r,W),T=Math.max(g,L),A=Math.min(m,z),F=Math.min(p,E),f=A-k,x=F-T;if(f<=0||x<=0)return!1;let X=document.createElement("canvas");X.width=f,X.height=x;let u=X.getContext("2d");u.save(),u.translate(-k,-T),u.fillStyle="red",u.fill(this.getPath()),u.restore();let D=u.getImageData(0,0,f,x).data;u.clearRect(0,0,f,x),u.save(),u.translate(-k,-T),u.fillStyle="blue",u.fill(t.getPath()),u.restore();let H=u.getImageData(0,0,f,x).data;for(let R=3;R<D.length;R+=4)if(D[R]>0&&H[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 c{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;sounds=[];mouseX=0;mouseY=0;mouseDown=!1;mouseClicked=!1;keysPressed=new Set;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new c),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}resumeLoop(){this.loopRunning=!0}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(r=>r.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)for(this.loopRunning=!0;this.loopRunning;)await i(),await this.wait(1e3/t)}refresh(){h.clearRect(0,0,s.width,s.height),this.sceneMap[this.currentScene]?.sprites.forEach(t=>{t.hidden||t.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()})}isHovered(t){let{mouseX:i,mouseY:e}=this,n=i+s.width/2,r=s.height/2-e,g=n-(t.x+s.width/2),m=r-(s.height/2-t.y),p=-this.toRadians(t.dir),W=g*Math.cos(p)-m*Math.sin(p),L=g*Math.sin(p)+m*Math.cos(p);return h.isPointInPath(t.getPath(),W,L)}isKeyPressed(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),l.addEventListener("mousemove",t=>{this.mouseX=t.clientX-l.offsetLeft-l.width/2,this.mouseY=-(t.clientY-l.offsetTop-l.height/2)}),l.addEventListener("mousedown",t=>{this.mouseDown=!0}),l.addEventListener("mouseup",t=>{this.mouseDown=!1}),l.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 w=class extends a{discriminant="rectangle";width;height;color;outlineColor;outlineWidth;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));let r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setWidth(t){this.width=t,this.refresh()}setHeight(t){this.height=t,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 S=class extends a{discriminant="square";sideLength;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.sideLength,height: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 r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setSideLength(t){this.sideLength=t,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 a{discriminant="circle";radX;radY;color;outlineColor;outlineWidth;getBoundingBox(){return{x:this.x,y:this.y,width:this.radX*2,height: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 r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setRadX(t){this.radX=t,this.refresh()}setRadY(t){this.radY=t,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 B=class extends a{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 r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setRadius(t){this.radius=t,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 extends a{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=Math.PI*2/this.sides,e=this.toRadians(this.dir),n=this.radius;for(let r=0;r<this.sides;r++){let g=r*i-Math.PI/2+e,m=n*Math.cos(g),p=-n*Math.sin(g);r===0?t.moveTo(m,p):t.lineTo(m,p)}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);let r=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(r),this.outlineWidth&&i.stroke(r),i.restore()}setSides(t){this.sides=t,this.refresh()}setRadius(t){this.radius=t,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 P=class extends a{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)}ereaseAll(){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 M=class extends a{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.refresh()}setColor(t){this.color=t,this.refresh()}setFontSize(t){this.fontSize=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.refresh()}setFontFamily(t){this.fontFamily=t,this.font=`${this.fontSize}px ${this.fontFamily}`,this.refresh()}setAlign(t){this.align=t,this.refresh()}setBaseline(t){this.baseline=t,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 O=class extends a{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.getPath()),i.restore()}setSrc(t){this.src=t,this.refresh()}setWidth(t){this.width=t,this.refresh()}setHeight(t){this.height=t,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 $={Engine:b,Sprite:a,Rectangle:w,Square:S,Oval:v,Circle:B,RegularPolygon:C,Pen:P,Text:M,ImageSprite:O,setScale:Y,setAspectRatio:I,canvas:s,ctx:h},kt=$;export{B as Circle,b as Engine,O as ImageSprite,v as Oval,P as Pen,w as Rectangle,C as RegularPolygon,a as Sprite,S as Square,M as Text,s as canvas,h as ctx,kt as default,I as setAspectRatio,Y as setScale};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../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","../src/index.ts"],"sourcesContent":["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 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 // Rendering\r\n\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 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 // 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 public maxFPS: number = 24;\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 // Set a loop\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 // 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 this.loopRunning = true;\r\n\r\n while (this.loopRunning) {\r\n await loop();\r\n await this.wait(1000 / maxFPS);\r\n }\r\n }\r\n\r\n public refresh() {\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n this.sceneMap[this.currentScene]?.sprites.forEach(sprite => {\r\n if (!sprite.hidden)\r\n sprite.draw();\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 isHovered(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 isKeyPressed(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 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 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 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.getPath();\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.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\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 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 sideLength: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\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.getPath();\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.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 SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface OvalOptions extends SpriteOptions {\r\n radA?: number;\r\n radB?: 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 radA: number;\r\n public radB: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\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.radA,\r\n this.radB,\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.getPath();\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 setRadA(radA: number) {\r\n this.radA = radA;\r\n this.refresh();\r\n }\r\n\r\n public setRadB(radB: number) {\r\n this.radB = radB;\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.radA = options?.radA ?? 25;\r\n this.radB = options?.radB ?? 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 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 radius: number;\r\n public color: string;\r\n public outlineColor: string;\r\n public outlineWidth: number;\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.getPath();\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.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 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 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 getPath(): Path2D {\r\n const path = new Path2D();\r\n\r\n const step = (Math.PI * 2) / this.sides;\r\n const rotation = this.toRadians(this.dir);\r\n const r = this.radius;\r\n\r\n for (let i = 0; i < this.sides; i++) {\r\n const theta = i * step - Math.PI / 2 + rotation;\r\n const px = r * Math.cos(theta);\r\n const py = -r * Math.sin(theta);\r\n\r\n if (i === 0) path.moveTo(px, py);\r\n else path.lineTo(px, py);\r\n }\r\n\r\n path.closePath();\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\r\n c.translate(cX, cY);\r\n\r\n const path = this.getPath();\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.refresh();\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\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 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 drawing: boolean;\r\n public size: number;\r\n public color: string;\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 ereaseAll() {\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 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 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 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.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.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.refresh();\r\n }\r\n\r\n public setAlign(align: CanvasTextAlign) {\r\n this.align = align;\r\n this.refresh();\r\n }\r\n\r\n public setBaseline(baseline: CanvasTextBaseline) {\r\n this.baseline = baseline;\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 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 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 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.getPath());\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.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\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}","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};"],"mappings":"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","names":["canvas","ctx","penCanvas","penCtx","ratio","scale","setScale","newScale","setAspectRatio","newAspectRatio","Sprite","Engine","options","deg","rad","steps","dir","x","y","dX","dY","layer","dL","Engine","_Engine","scene","loop","sprite","layer","targetIndex","s","maxFPS","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","radA","radB","color","options","Circle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radius","color","options","RegularPolygon","Sprite","path","step","rotation","i","theta","px","py","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","path","ctx","metrics","width","height","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/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","../src/index.ts"],"sourcesContent":["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 // 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 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) * 2 < (bBox1.width + bBox2.width) &&\r\n Math.abs(bBox1.y - bBox2.y) * 2 < (bBox1.height + bBox2.height);\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.max(b1Top, b2Top);\r\n const xMax = Math.min(b1Right, b2Right);\r\n const yMax = Math.min(b1Bottom, b2Bottom);\r\n\r\n const width = xMax - xMin;\r\n const height = yMax - yMin;\r\n\r\n if (width <= 0 || height <= 0) return false;\r\n\r\n // Create offscreen canvas just for intersection region\r\n const canvas = document.createElement('canvas');\r\n canvas.width = width;\r\n canvas.height = height;\r\n const ctx = canvas.getContext('2d')!;\r\n\r\n // Draw first sprite\r\n ctx.save();\r\n ctx.translate(-xMin, -yMin);\r\n ctx.fillStyle = 'red';\r\n ctx.fill(this.getPath());\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(-xMin, -yMin);\r\n ctx.fillStyle = 'blue';\r\n ctx.fill(sprite.getPath());\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\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 public maxFPS: number = 24;\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 }\r\n\r\n public resumeLoop() {\r\n this.loopRunning = true;\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 this.loopRunning = true;\r\n\r\n while (this.loopRunning) {\r\n await loop();\r\n await this.wait(1000 / maxFPS);\r\n }\r\n }\r\n\r\n public refresh() {\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n this.sceneMap[this.currentScene]?.sprites.forEach(sprite => {\r\n if (!sprite.hidden)\r\n sprite.draw();\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 isHovered(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 isKeyPressed(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: 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): 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.getPath();\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.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\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: this.sideLength,\r\n height: 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.getPath();\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.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: this.radX * 2,\r\n height: 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.getPath();\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.refresh();\r\n }\r\n\r\n public setRadY(radY: number) {\r\n this.radY = radY;\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.getPath();\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.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\r\n const step = (Math.PI * 2) / this.sides;\r\n const rotation = this.toRadians(this.dir);\r\n const r = this.radius;\r\n\r\n for (let i = 0; i < this.sides; i++) {\r\n const theta = i * step - Math.PI / 2 + rotation;\r\n const px = r * Math.cos(theta);\r\n const py = -r * Math.sin(theta);\r\n\r\n if (i === 0) path.moveTo(px, py);\r\n else path.lineTo(px, py);\r\n }\r\n\r\n path.closePath();\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\r\n c.translate(cX, cY);\r\n\r\n const path = this.getPath();\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.refresh();\r\n }\r\n\r\n public setRadius(radius: number) {\r\n this.radius = radius;\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 ereaseAll() {\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.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.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.refresh();\r\n }\r\n\r\n public setAlign(align: CanvasTextAlign) {\r\n this.align = align;\r\n this.refresh();\r\n }\r\n\r\n public setBaseline(baseline: CanvasTextBaseline) {\r\n this.baseline = baseline;\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.getPath());\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.refresh();\r\n }\r\n\r\n public setHeight(height: number) {\r\n this.height = height;\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}","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};"],"mappings":"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","names":["canvas","ctx","penCanvas","penCtx","ratio","scale","setScale","newScale","setAspectRatio","newAspectRatio","Sprite","Engine","options","sprite","bBox1","bBox2","b1Left","b1Top","b1Right","b1Bottom","b2Left","b2Top","b2Right","b2Bottom","xMin","yMin","xMax","yMax","width","height","canvas","ctx","img1","img2","i","deg","rad","steps","dir","x","y","dX","dY","layer","dL","Engine","_Engine","scene","loop","sprite","layer","targetIndex","s","maxFPS","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","rotation","r","i","theta","px","py","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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tscratch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "A Scratch-style game engine for TypeScript.",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"files": [
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"url": "https://github.com/Sebastian-GOAT/tscratch"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://tscratch.vercel.app",
|
|
27
31
|
"author": "sebastian-goat",
|
|
28
32
|
"license": "MIT",
|
|
29
33
|
"type": "module",
|