tscratch 0.3.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -149,6 +149,42 @@ export default class Player extends Rectangle {
149
149
  }
150
150
  ```
151
151
 
152
+ For sprites that directly inherit from `Sprite`, you'll need to implement the
153
+ following methods:
154
+
155
+ ```ts
156
+ import { Sprite, ctx, penCtx } from 'tscratch';
157
+
158
+ export default class MySprite extends Sprite {
159
+
160
+ public getPath(): Path2D {
161
+ const path = new Path2D();
162
+
163
+ // Example path
164
+ path.rect(
165
+ -this.width / 2, -this.height / 2,
166
+ this.width, this.height
167
+ );
168
+ path.closePath();
169
+
170
+ return path;
171
+ }
172
+
173
+ public draw(stamping?: boolean): void {
174
+ // For pen stamping (optional, you can just use ctx)
175
+ const c = stamping ? penCtx : ctx;
176
+ c.save();
177
+ c.translate(
178
+ this.x + canvas.width / 2,
179
+ -this.y + canvas.height / 2
180
+ );
181
+ c.rotate(this.toRadians(this.dir));
182
+ c.fill(this.getPath());
183
+ c.restore();
184
+ }
185
+ }
186
+ ```
187
+
152
188
  ## Scenes
153
189
 
154
190
  TScratch supports scenes with the `scene` property. In every sprite you create,
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var P=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var X=(n,t)=>{for(var e in t)P(n,e,{get:t[e],enumerable:!0})},Y=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of D(t))!L.call(n,r)&&r!==e&&P(n,r,{get:()=>t[r],enumerable:!(s=C(t,r))||s.enumerable});return n};var B=n=>Y(P({},"__esModule",{value:!0}),n);var I={};X(I,{Engine:()=>l,ImageSprite:()=>w,Oval:()=>m,Pen:()=>f,Rectangle:()=>b,RegularPolygon:()=>g,Sprite:()=>o,Text:()=>x,canvas:()=>i,ctx:()=>h,default:()=>z,setAspectRatio:()=>O,setScale:()=>M});module.exports=B(I);var i=document.getElementById("game-window"),h=i.getContext("2d"),d=document.createElement("canvas"),a=d.getContext("2d");d.id="pen-canvas";var v=16/9,c;function M(n){c=n,i.width=v*c,i.height=c,d.width=v*c,d.height=c}function O(n){v=n,i.width=v*c,i.height=c,d.width=v*c,d.height=c}i.parentElement?.insertBefore(d,i);M(500);var o=class{x;y;dir;scene;hidden;layer;refresh(){l.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,l.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()}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 l=class n{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;mouseX=0;mouseY=0;mouseDown=!1;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new n),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(p=>p.layer>s);if(r===-1){this.sceneMap[e].sprites.push(t);return}this.sceneMap[e].sprites.splice(r,0,t)}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(){h.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))}isHovered(t){let{mouseX:e,mouseY:s}=this,r=e+i.width/2,p=i.height/2-s,y=r-(t.x+i.width/2),S=p-(i.height/2-t.y),u=-this.toRadians(t.dir),R=y*Math.cos(u)-S*Math.sin(u),T=y*Math.sin(u)+S*Math.cos(u);return h.isPointInPath(t.getPath(),R,T)}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),i.addEventListener("mousemove",t=>{this.mouseX=t.clientX-i.offsetLeft-i.width/2,this.mouseY=-(t.clientY-i.offsetTop-i.height/2)}),i.addEventListener("mousedown",t=>{this.mouseDown=!0}),i.addEventListener("mouseup",t=>{this.mouseDown=!1})}};var b=class extends o{width;height;color;getPath(){let t=new Path2D;return t.rect(-this.width/2,-this.height/2,this.width,this.height),t}draw(t){let e=t?a:h;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.fillStyle=this.color,e.fill(this.getPath()),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.draw()}};var m=class extends o{radA;radB;color;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?a:h;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.fillStyle=this.color,e.fill(this.getPath()),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.draw()}};var g=class extends o{sides;radius;color;getPath(){let t=new Path2D,e=Math.PI*2/this.sides,s=this.toRadians(this.dir),r=this.radius;for(let p=0;p<this.sides;p++){let y=p*e-Math.PI/2+s,S=r*Math.cos(y),u=-r*Math.sin(y);p===0?t.moveTo(S,u):t.lineTo(S,u)}return t.closePath(),t}draw(t){let e=t?a:h;e.save();let s=this.x+i.width/2,r=this.y+i.height/2;e.translate(s,r),e.fillStyle=this.color,e.fill(this.getPath()),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.draw()}};var f=class extends o{drawing;size;color;getPath(){return new Path2D}draw(){}up(){this.drawing=!1}down(){this.drawing=!0}stamp(t){t.draw(!0)}ereaseAll(){a.clearRect(0,0,i.width,i.height)}dot(){a.fillStyle=this.color,a.fillRect(this.x-this.size/2+i.width/2,-this.y-this.size/2+i.height/2,this.size,this.size)}drawLine(t,e){a.beginPath(),a.moveTo(t+i.width/2,-e+i.height/2),a.lineTo(this.x+i.width/2,-this.y+i.height/2),a.lineWidth=this.size,a.strokeStyle=this.color,a.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 x=class extends o{content;color;fontFamily;fontSize;align;baseline;font;getPath(){let t=new Path2D;h.save(),h.font=this.font;let e=h.measureText(this.content),s=e.width,r=e.actualBoundingBoxAscent+e.actualBoundingBoxDescent;return h.restore(),t.rect(-s/2,-r/2,s,r),t}draw(t){let e=t?a:h;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}`}};var w=class extends o{src;width;height;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?a:h;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.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height),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}};var A={Engine:l,Sprite:o,Rectangle:b,Oval:m,RegularPolygon:g,Pen:f,Text:x,ImageSprite:w,setScale:M,setAspectRatio:O,canvas:i,ctx:h},z=A;0&&(module.exports={Engine,ImageSprite,Oval,Pen,Rectangle,RegularPolygon,Sprite,Text,canvas,ctx,setAspectRatio,setScale});
1
+ "use strict";var P=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var D=(n,t)=>{for(var i in t)P(n,i,{get:t[i],enumerable:!0})},W=(n,t,i,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of L(t))!A.call(n,r)&&r!==i&&P(n,r,{get:()=>t[r],enumerable:!(s=T(t,r))||s.enumerable});return n};var X=n=>W(P({},"__esModule",{value:!0}),n);var k={};D(k,{Engine:()=>u,ImageSprite:()=>y,Oval:()=>m,Pen:()=>f,Rectangle:()=>b,RegularPolygon:()=>g,Sprite:()=>a,Text:()=>x,canvas:()=>e,ctx:()=>h,default:()=>B,setAspectRatio:()=>C,setScale:()=>M});module.exports=X(k);var e=document.getElementById("game-window"),h=e.getContext("2d"),d=document.createElement("canvas"),o=d.getContext("2d");d.id="pen-canvas";var v=16/9,c;function M(n){c=n,e.width=v*c,e.height=c,d.width=v*c,d.height=c}function C(n){v=n,e.width=v*c,e.height=c,d.width=v*c,d.height=c}e.parentElement?.insertBefore(d,e);M(500);var a=class{x;y;dir;scene;hidden;layer;refresh(){u.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,u.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()}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 u=class n{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;sounds=[];mouseX=0;mouseY=0;mouseDown=!1;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new n),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)}addSprite(t){let{scene:i,layer:s}=t;if(!this.sceneMap[i]){this.sceneMap[i]={sprites:[t],loop:null};return}let r=this.sceneMap[i].sprites.findIndex(l=>l.layer>s);if(r===-1){this.sceneMap[i].sprites.push(t);return}this.sceneMap[i].sprites.splice(r,0,t)}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,e.width,e.height),this.sceneMap[this.currentScene]?.sprites.forEach(t=>{t.hidden||t.draw()})}async wait(t){return new Promise(i=>setTimeout(i,t))}isHovered(t){let{mouseX:i,mouseY:s}=this,r=i+e.width/2,l=e.height/2-s,w=r-(t.x+e.width/2),S=l-(e.height/2-t.y),p=-this.toRadians(t.dir),O=w*Math.cos(p)-S*Math.sin(p),R=w*Math.sin(p)+S*Math.cos(p);return h.isPointInPath(t.getPath(),O,R)}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),e.addEventListener("mousemove",t=>{this.mouseX=t.clientX-e.offsetLeft-e.width/2,this.mouseY=-(t.clientY-e.offsetTop-e.height/2)}),e.addEventListener("mousedown",t=>{this.mouseDown=!0}),e.addEventListener("mouseup",t=>{this.mouseDown=!1})}};var b=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 i=t?o:h;i.save();let s=this.x+e.width/2,r=-this.y+e.height/2;i.translate(s,r),i.rotate(this.toRadians(this.dir));let l=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(l),i.stroke(l),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="black",this.outlineWidth=0,this.draw()}};var m=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 i=t?o:h;i.save();let s=this.x+e.width/2,r=-this.y+e.height/2;i.translate(s,r),i.rotate(this.toRadians(this.dir));let l=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(l),i.stroke(l),i.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="black",this.outlineWidth=0,this.draw()}};var g=class extends a{sides;radius;color;outlineColor;outlineWidth;getPath(){let t=new Path2D,i=Math.PI*2/this.sides,s=this.toRadians(this.dir),r=this.radius;for(let l=0;l<this.sides;l++){let w=l*i-Math.PI/2+s,S=r*Math.cos(w),p=-r*Math.sin(w);l===0?t.moveTo(S,p):t.lineTo(S,p)}return t.closePath(),t}draw(t){let i=t?o:h;i.save();let s=this.x+e.width/2,r=this.y+e.height/2;i.translate(s,r);let l=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(l),i.stroke(l),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="black",this.outlineWidth=0,this.draw()}};var f=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(){o.clearRect(0,0,e.width,e.height)}dot(){o.fillStyle=this.color,o.fillRect(this.x-this.size/2+e.width/2,-this.y-this.size/2+e.height/2,this.size,this.size)}drawLine(t,i){o.beginPath(),o.moveTo(t+e.width/2,-i+e.height/2),o.lineTo(this.x+e.width/2,-this.y+e.height/2),o.lineWidth=this.size,o.strokeStyle=this.color,o.stroke()}move(t){let i=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(i,s),this.refresh()}setX(t){let i=this.x,s=this.y;this.x=t,this.drawing&&this.drawLine(i,s),this.refresh()}setY(t){let i=this.x,s=this.y;this.y=t,this.drawing&&this.drawLine(i,s),this.refresh()}goTo(t,i){let s=this.x,r=this.y;this.x=t,this.y=i,this.drawing&&this.drawLine(s,r),this.refresh()}changeX(t){let i=this.x,s=this.y;this.x+=t,this.drawing&&this.drawLine(i,s),this.refresh()}changeY(t){let i=this.x,s=this.y;this.y+=t,this.drawing&&this.drawLine(i,s),this.refresh()}constructor(t){super(t),this.drawing=t?.drawing??!1,this.size=t?.size??5,this.color=t?.color??"black"}};var x=class extends a{content;color;fontFamily;fontSize;align;baseline;font;getPath(){let t=new Path2D;h.save(),h.font=this.font;let i=h.measureText(this.content),s=i.width,r=i.actualBoundingBoxAscent+i.actualBoundingBoxDescent;return h.restore(),t.rect(-s/2,-r/2,s,r),t}draw(t){let i=t?o:h;i.save();let s=this.x+e.width/2,r=-this.y+e.height/2;i.translate(s,r),i.rotate(this.toRadians(this.dir)),i.font=this.font,i.fillStyle=this.color,i.textAlign=this.align,i.textBaseline=this.baseline,i.fillText(this.content,0,0),i.restore()}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}`}};var y=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 i=t?o:h;i.save();let s=this.x+e.width/2,r=-this.y+e.height/2;i.translate(s,r),i.rotate(this.toRadians(this.dir)),i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height),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="black",this.outlineWidth=0}};var Y={Engine:u,Sprite:a,Rectangle:b,Oval:m,RegularPolygon:g,Pen:f,Text:x,ImageSprite:y,setScale:M,setAspectRatio:C,canvas:e,ctx:h},B=Y;0&&(module.exports={Engine,ImageSprite,Oval,Pen,Rectangle,RegularPolygon,Sprite,Text,canvas,ctx,setAspectRatio,setScale});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/canvas.ts","../src/Sprite.ts","../src/Engine.ts","../src/Rectangle.ts","../src/Oval.ts","../src/RegularPolygon.ts","../src/Pen.ts","../src/Text.ts","../src/ImageSprite.ts"],"sourcesContent":["import Engine from './Engine.ts';\r\n\r\nimport Sprite, { type SpriteOptions } from './Sprite.ts';\r\nimport Rectangle, { type RectangleOptions } from './Rectangle.ts';\r\nimport Oval, { type OvalOptions } from './Oval.ts';\r\nimport RegularPolygon, { type RegularPolygonOptions } from './RegularPolygon.ts';\r\nimport Pen, { type PenOptions } from './Pen.ts';\r\nimport Text, { type TextOptions, type CanvasTextAlign, type CanvasTextBaseline } from './Text.ts';\r\nimport ImageSprite, { type ImageSpriteOptions } from './ImageSprite.ts';\r\n\r\nimport { setScale, setAspectRatio, canvas, ctx } from './canvas.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 Oval,\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 Oval,\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 OvalOptions,\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;\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 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 } 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 mouseX: number = 0;\r\n public mouseY: number = 0;\r\n\r\n public mouseDown: boolean = false;\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 }\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 function\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 // Mouse 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 // 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 canvas.addEventListener('mousemove', e => {\r\n this.mouseX = e.clientX - canvas.offsetLeft - canvas.width / 2;\r\n this.mouseY = -(e.clientY - canvas.offsetTop - canvas.height / 2);\r\n });\r\n canvas.addEventListener('mousedown', e => {\r\n this.mouseDown = true;\r\n });\r\n canvas.addEventListener('mouseup', e => {\r\n this.mouseDown = false;\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};\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\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 c.fillStyle = this.color;\r\n c.fill(this.getPath())\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.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};\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\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 c.fillStyle = this.color;\r\n c.fill(this.getPath());\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.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}\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\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 c.fillStyle = this.color;\r\n c.fill(this.getPath());\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.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}","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};\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\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.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\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}"],"mappings":"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","names":["index_exports","__export","Engine","ImageSprite","Oval","Pen","Rectangle","RegularPolygon","Sprite","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","mouseX","mouseY","canvasMouseX","canvasMouseY","localX","localY","angle","rotatedX","rotatedY","min","max","deg","val","rad","e","Rectangle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","width","height","color","options","Oval","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radA","radB","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","Oval","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/Rectangle.ts","../src/Oval.ts","../src/RegularPolygon.ts","../src/Pen.ts","../src/Text.ts","../src/ImageSprite.ts"],"sourcesContent":["import Engine from './Engine.ts';\r\n\r\nimport Sprite, { type SpriteOptions } from './Sprite.ts';\r\nimport Rectangle, { type RectangleOptions } from './Rectangle.ts';\r\nimport Oval, { type OvalOptions } from './Oval.ts';\r\nimport RegularPolygon, { type RegularPolygonOptions } from './RegularPolygon.ts';\r\nimport Pen, { type PenOptions } from './Pen.ts';\r\nimport Text, { type TextOptions, type CanvasTextAlign, type CanvasTextBaseline } from './Text.ts';\r\nimport ImageSprite, { type ImageSpriteOptions } from './ImageSprite.ts';\r\n\r\nimport { setScale, setAspectRatio, canvas, ctx } from './canvas.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 Oval,\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 Oval,\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 OvalOptions,\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;\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 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 } 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\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 }\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 function\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 // Mouse 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 // 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 canvas.addEventListener('mousemove', e => {\r\n this.mouseX = e.clientX - canvas.offsetLeft - canvas.width / 2;\r\n this.mouseY = -(e.clientY - canvas.offsetTop - canvas.height / 2);\r\n });\r\n canvas.addEventListener('mousedown', e => {\r\n this.mouseDown = true;\r\n });\r\n canvas.addEventListener('mouseup', e => {\r\n this.mouseDown = false;\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 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 = 'black';\r\n this.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 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 = 'black';\r\n this.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 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 = 'black';\r\n this.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}","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 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 = 'black';\r\n this.outlineWidth = 0;\r\n }\r\n}"],"mappings":"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","names":["index_exports","__export","Engine","ImageSprite","Oval","Pen","Rectangle","RegularPolygon","Sprite","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","mouseX","mouseY","canvasMouseX","canvasMouseY","localX","localY","angle","rotatedX","rotatedY","src","audio","sound","min","max","deg","val","rad","e","Rectangle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","width","height","color","options","Oval","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radA","radB","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","Oval","RegularPolygon","Pen","Text","ImageSprite","setScale","setAspectRatio","canvas","ctx","index_default"]}
package/dist/index.d.cts CHANGED
@@ -45,6 +45,7 @@ declare class Engine {
45
45
  private loopRunning;
46
46
  gameLoop: GameLoop | null;
47
47
  maxFPS: number;
48
+ sounds: HTMLAudioElement[];
48
49
  mouseX: number;
49
50
  mouseY: number;
50
51
  mouseDown: boolean;
@@ -58,6 +59,9 @@ declare class Engine {
58
59
  refresh(): void;
59
60
  wait(ms: number): Promise<void>;
60
61
  isHovered(sprite: Sprite): boolean;
62
+ playSound(src: string): HTMLAudioElement;
63
+ stopSound(sound: HTMLAudioElement): void;
64
+ stopAllSounds(): void;
61
65
  pickRandom(min: number, max: number): number;
62
66
  sin(deg: number): number;
63
67
  cos(deg: number): number;
@@ -78,11 +82,15 @@ interface RectangleOptions extends SpriteOptions {
78
82
  width?: number;
79
83
  height?: number;
80
84
  color?: string;
85
+ outlineColor?: string;
86
+ outlineWidth?: number;
81
87
  }
82
88
  declare class Rectangle extends Sprite {
83
89
  width: number;
84
90
  height: number;
85
91
  color: string;
92
+ outlineColor: string;
93
+ outlineWidth: number;
86
94
  getPath(): Path2D;
87
95
  draw(stamping?: boolean): void;
88
96
  setWidth(width: number): void;
@@ -95,11 +103,15 @@ interface OvalOptions extends SpriteOptions {
95
103
  radA?: number;
96
104
  radB?: number;
97
105
  color?: string;
106
+ outlineColor?: string;
107
+ outlineWidth?: number;
98
108
  }
99
109
  declare class Oval extends Sprite {
100
110
  radA: number;
101
111
  radB: number;
102
112
  color: string;
113
+ outlineColor: string;
114
+ outlineWidth: number;
103
115
  getPath(): Path2D;
104
116
  draw(stamping?: boolean): void;
105
117
  setRadA(radA: number): void;
@@ -112,11 +124,15 @@ interface RegularPolygonOptions extends SpriteOptions {
112
124
  sides?: number;
113
125
  radius?: number;
114
126
  color?: string;
127
+ outlineColor?: string;
128
+ outlineWidth?: number;
115
129
  }
116
130
  declare class RegularPolygon extends Sprite {
117
131
  sides: number;
118
132
  radius: number;
119
133
  color: string;
134
+ outlineColor: string;
135
+ outlineWidth: number;
120
136
  getPath(): Path2D;
121
137
  draw(stamping?: boolean): void;
122
138
  setSides(sides: number): void;
@@ -184,11 +200,15 @@ interface ImageSpriteOptions extends SpriteOptions {
184
200
  src?: string;
185
201
  width: number;
186
202
  height: number;
203
+ outlineColor?: string;
204
+ outlineWidth?: number;
187
205
  }
188
206
  declare class ImageSprite extends Sprite {
189
207
  src: string;
190
208
  width: number;
191
209
  height: number;
210
+ outlineColor: string;
211
+ outlineWidth: number;
192
212
  protected img: HTMLImageElement;
193
213
  getPath(): Path2D;
194
214
  draw(stamping?: boolean): void;
package/dist/index.d.ts CHANGED
@@ -45,6 +45,7 @@ declare class Engine {
45
45
  private loopRunning;
46
46
  gameLoop: GameLoop | null;
47
47
  maxFPS: number;
48
+ sounds: HTMLAudioElement[];
48
49
  mouseX: number;
49
50
  mouseY: number;
50
51
  mouseDown: boolean;
@@ -58,6 +59,9 @@ declare class Engine {
58
59
  refresh(): void;
59
60
  wait(ms: number): Promise<void>;
60
61
  isHovered(sprite: Sprite): boolean;
62
+ playSound(src: string): HTMLAudioElement;
63
+ stopSound(sound: HTMLAudioElement): void;
64
+ stopAllSounds(): void;
61
65
  pickRandom(min: number, max: number): number;
62
66
  sin(deg: number): number;
63
67
  cos(deg: number): number;
@@ -78,11 +82,15 @@ interface RectangleOptions extends SpriteOptions {
78
82
  width?: number;
79
83
  height?: number;
80
84
  color?: string;
85
+ outlineColor?: string;
86
+ outlineWidth?: number;
81
87
  }
82
88
  declare class Rectangle extends Sprite {
83
89
  width: number;
84
90
  height: number;
85
91
  color: string;
92
+ outlineColor: string;
93
+ outlineWidth: number;
86
94
  getPath(): Path2D;
87
95
  draw(stamping?: boolean): void;
88
96
  setWidth(width: number): void;
@@ -95,11 +103,15 @@ interface OvalOptions extends SpriteOptions {
95
103
  radA?: number;
96
104
  radB?: number;
97
105
  color?: string;
106
+ outlineColor?: string;
107
+ outlineWidth?: number;
98
108
  }
99
109
  declare class Oval extends Sprite {
100
110
  radA: number;
101
111
  radB: number;
102
112
  color: string;
113
+ outlineColor: string;
114
+ outlineWidth: number;
103
115
  getPath(): Path2D;
104
116
  draw(stamping?: boolean): void;
105
117
  setRadA(radA: number): void;
@@ -112,11 +124,15 @@ interface RegularPolygonOptions extends SpriteOptions {
112
124
  sides?: number;
113
125
  radius?: number;
114
126
  color?: string;
127
+ outlineColor?: string;
128
+ outlineWidth?: number;
115
129
  }
116
130
  declare class RegularPolygon extends Sprite {
117
131
  sides: number;
118
132
  radius: number;
119
133
  color: string;
134
+ outlineColor: string;
135
+ outlineWidth: number;
120
136
  getPath(): Path2D;
121
137
  draw(stamping?: boolean): void;
122
138
  setSides(sides: number): void;
@@ -184,11 +200,15 @@ interface ImageSpriteOptions extends SpriteOptions {
184
200
  src?: string;
185
201
  width: number;
186
202
  height: number;
203
+ outlineColor?: string;
204
+ outlineWidth?: number;
187
205
  }
188
206
  declare class ImageSprite extends Sprite {
189
207
  src: string;
190
208
  width: number;
191
209
  height: number;
210
+ outlineColor: string;
211
+ outlineWidth: number;
192
212
  protected img: HTMLImageElement;
193
213
  getPath(): Path2D;
194
214
  draw(stamping?: boolean): void;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var i=document.getElementById("game-window"),h=i.getContext("2d"),d=document.createElement("canvas"),n=d.getContext("2d");d.id="pen-canvas";var g=16/9,c;function M(o){c=o,i.width=g*c,i.height=c,d.width=g*c,d.height=c}function P(o){g=o,i.width=g*c,i.height=c,d.width=g*c,d.height=c}i.parentElement?.insertBefore(d,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()}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 o{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;mouseX=0;mouseY=0;mouseDown=!1;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new o),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(l=>l.layer>s);if(r===-1){this.sceneMap[e].sprites.push(t);return}this.sceneMap[e].sprites.splice(r,0,t)}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(){h.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))}isHovered(t){let{mouseX:e,mouseY:s}=this,r=e+i.width/2,l=i.height/2-s,b=r-(t.x+i.width/2),m=l-(i.height/2-t.y),u=-this.toRadians(t.dir),O=b*Math.cos(u)-m*Math.sin(u),R=b*Math.sin(u)+m*Math.cos(u);return h.isPointInPath(t.getPath(),O,R)}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),i.addEventListener("mousemove",t=>{this.mouseX=t.clientX-i.offsetLeft-i.width/2,this.mouseY=-(t.clientY-i.offsetTop-i.height/2)}),i.addEventListener("mousedown",t=>{this.mouseDown=!0}),i.addEventListener("mouseup",t=>{this.mouseDown=!1})}};var f=class extends a{width;height;color;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:h;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.fillStyle=this.color,e.fill(this.getPath()),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.draw()}};var x=class extends a{radA;radB;color;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:h;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.fillStyle=this.color,e.fill(this.getPath()),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.draw()}};var w=class extends a{sides;radius;color;getPath(){let t=new Path2D,e=Math.PI*2/this.sides,s=this.toRadians(this.dir),r=this.radius;for(let l=0;l<this.sides;l++){let b=l*e-Math.PI/2+s,m=r*Math.cos(b),u=-r*Math.sin(b);l===0?t.moveTo(m,u):t.lineTo(m,u)}return t.closePath(),t}draw(t){let e=t?n:h;e.save();let s=this.x+i.width/2,r=this.y+i.height/2;e.translate(s,r),e.fillStyle=this.color,e.fill(this.getPath()),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.draw()}};var y=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 S=class extends a{content;color;fontFamily;fontSize;align;baseline;font;getPath(){let t=new Path2D;h.save(),h.font=this.font;let e=h.measureText(this.content),s=e.width,r=e.actualBoundingBoxAscent+e.actualBoundingBoxDescent;return h.restore(),t.rect(-s/2,-r/2,s,r),t}draw(t){let e=t?n:h;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}`}};var v=class extends a{src;width;height;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:h;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.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height),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}};var T={Engine:p,Sprite:a,Rectangle:f,Oval:x,RegularPolygon:w,Pen:y,Text:S,ImageSprite:v,setScale:M,setAspectRatio:P,canvas:i,ctx:h},ot=T;export{p as Engine,v as ImageSprite,x as Oval,y as Pen,f as Rectangle,w as RegularPolygon,a as Sprite,S as Text,i as canvas,h as ctx,ot as default,P as setAspectRatio,M as setScale};
1
+ var e=document.getElementById("game-window"),h=e.getContext("2d"),d=document.createElement("canvas"),n=d.getContext("2d");d.id="pen-canvas";var g=16/9,c;function M(l){c=l,e.width=g*c,e.height=c,d.width=g*c,d.height=c}function P(l){g=l,e.width=g*c,e.height=c,d.width=g*c,d.height=c}e.parentElement?.insertBefore(d,e);M(500);var a=class{x;y;dir;scene;hidden;layer;refresh(){u.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,u.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()}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 u=class l{static instance;loopRunning=!1;gameLoop=null;maxFPS=24;sounds=[];mouseX=0;mouseY=0;mouseDown=!1;currentScene="main";sceneMap={};static init(){return this.instance||(this.instance=new l),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)}addSprite(t){let{scene:i,layer:s}=t;if(!this.sceneMap[i]){this.sceneMap[i]={sprites:[t],loop:null};return}let r=this.sceneMap[i].sprites.findIndex(o=>o.layer>s);if(r===-1){this.sceneMap[i].sprites.push(t);return}this.sceneMap[i].sprites.splice(r,0,t)}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,e.width,e.height),this.sceneMap[this.currentScene]?.sprites.forEach(t=>{t.hidden||t.draw()})}async wait(t){return new Promise(i=>setTimeout(i,t))}isHovered(t){let{mouseX:i,mouseY:s}=this,r=i+e.width/2,o=e.height/2-s,b=r-(t.x+e.width/2),m=o-(e.height/2-t.y),p=-this.toRadians(t.dir),C=b*Math.cos(p)-m*Math.sin(p),O=b*Math.sin(p)+m*Math.cos(p);return h.isPointInPath(t.getPath(),C,O)}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),e.addEventListener("mousemove",t=>{this.mouseX=t.clientX-e.offsetLeft-e.width/2,this.mouseY=-(t.clientY-e.offsetTop-e.height/2)}),e.addEventListener("mousedown",t=>{this.mouseDown=!0}),e.addEventListener("mouseup",t=>{this.mouseDown=!1})}};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 i=t?n:h;i.save();let s=this.x+e.width/2,r=-this.y+e.height/2;i.translate(s,r),i.rotate(this.toRadians(this.dir));let o=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(o),i.stroke(o),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="black",this.outlineWidth=0,this.draw()}};var x=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 i=t?n:h;i.save();let s=this.x+e.width/2,r=-this.y+e.height/2;i.translate(s,r),i.rotate(this.toRadians(this.dir));let o=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(o),i.stroke(o),i.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="black",this.outlineWidth=0,this.draw()}};var y=class extends a{sides;radius;color;outlineColor;outlineWidth;getPath(){let t=new Path2D,i=Math.PI*2/this.sides,s=this.toRadians(this.dir),r=this.radius;for(let o=0;o<this.sides;o++){let b=o*i-Math.PI/2+s,m=r*Math.cos(b),p=-r*Math.sin(b);o===0?t.moveTo(m,p):t.lineTo(m,p)}return t.closePath(),t}draw(t){let i=t?n:h;i.save();let s=this.x+e.width/2,r=this.y+e.height/2;i.translate(s,r);let o=this.getPath();i.fillStyle=this.color,i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.fill(o),i.stroke(o),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="black",this.outlineWidth=0,this.draw()}};var w=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,e.width,e.height)}dot(){n.fillStyle=this.color,n.fillRect(this.x-this.size/2+e.width/2,-this.y-this.size/2+e.height/2,this.size,this.size)}drawLine(t,i){n.beginPath(),n.moveTo(t+e.width/2,-i+e.height/2),n.lineTo(this.x+e.width/2,-this.y+e.height/2),n.lineWidth=this.size,n.strokeStyle=this.color,n.stroke()}move(t){let i=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(i,s),this.refresh()}setX(t){let i=this.x,s=this.y;this.x=t,this.drawing&&this.drawLine(i,s),this.refresh()}setY(t){let i=this.x,s=this.y;this.y=t,this.drawing&&this.drawLine(i,s),this.refresh()}goTo(t,i){let s=this.x,r=this.y;this.x=t,this.y=i,this.drawing&&this.drawLine(s,r),this.refresh()}changeX(t){let i=this.x,s=this.y;this.x+=t,this.drawing&&this.drawLine(i,s),this.refresh()}changeY(t){let i=this.x,s=this.y;this.y+=t,this.drawing&&this.drawLine(i,s),this.refresh()}constructor(t){super(t),this.drawing=t?.drawing??!1,this.size=t?.size??5,this.color=t?.color??"black"}};var S=class extends a{content;color;fontFamily;fontSize;align;baseline;font;getPath(){let t=new Path2D;h.save(),h.font=this.font;let i=h.measureText(this.content),s=i.width,r=i.actualBoundingBoxAscent+i.actualBoundingBoxDescent;return h.restore(),t.rect(-s/2,-r/2,s,r),t}draw(t){let i=t?n:h;i.save();let s=this.x+e.width/2,r=-this.y+e.height/2;i.translate(s,r),i.rotate(this.toRadians(this.dir)),i.font=this.font,i.fillStyle=this.color,i.textAlign=this.align,i.textBaseline=this.baseline,i.fillText(this.content,0,0),i.restore()}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}`}};var v=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 i=t?n:h;i.save();let s=this.x+e.width/2,r=-this.y+e.height/2;i.translate(s,r),i.rotate(this.toRadians(this.dir)),i.strokeStyle=this.outlineColor,i.lineWidth=this.outlineWidth,i.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height),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="black",this.outlineWidth=0}};var R={Engine:u,Sprite:a,Rectangle:f,Oval:x,RegularPolygon:y,Pen:w,Text:S,ImageSprite:v,setScale:M,setAspectRatio:P,canvas:e,ctx:h},at=R;export{u as Engine,v as ImageSprite,x as Oval,w as Pen,f as Rectangle,y as RegularPolygon,a as Sprite,S as Text,e as canvas,h as ctx,at as default,P as setAspectRatio,M 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/Rectangle.ts","../src/Oval.ts","../src/RegularPolygon.ts","../src/Pen.ts","../src/Text.ts","../src/ImageSprite.ts","../src/index.ts"],"sourcesContent":["export const canvas = document.getElementById('game-window') as HTMLCanvasElement;\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 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 } 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 mouseX: number = 0;\r\n public mouseY: number = 0;\r\n\r\n public mouseDown: boolean = false;\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 }\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 function\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 // Mouse 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 // 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 canvas.addEventListener('mousemove', e => {\r\n this.mouseX = e.clientX - canvas.offsetLeft - canvas.width / 2;\r\n this.mouseY = -(e.clientY - canvas.offsetTop - canvas.height / 2);\r\n });\r\n canvas.addEventListener('mousedown', e => {\r\n this.mouseDown = true;\r\n });\r\n canvas.addEventListener('mouseup', e => {\r\n this.mouseDown = false;\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};\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\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 c.fillStyle = this.color;\r\n c.fill(this.getPath())\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.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};\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\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 c.fillStyle = this.color;\r\n c.fill(this.getPath());\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.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}\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\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 c.fillStyle = this.color;\r\n c.fill(this.getPath());\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.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}","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};\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\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.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\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}","import Engine from './Engine.ts';\r\n\r\nimport Sprite, { type SpriteOptions } from './Sprite.ts';\r\nimport Rectangle, { type RectangleOptions } from './Rectangle.ts';\r\nimport Oval, { type OvalOptions } from './Oval.ts';\r\nimport RegularPolygon, { type RegularPolygonOptions } from './RegularPolygon.ts';\r\nimport Pen, { type PenOptions } from './Pen.ts';\r\nimport Text, { type TextOptions, type CanvasTextAlign, type CanvasTextBaseline } from './Text.ts';\r\nimport ImageSprite, { type ImageSpriteOptions } from './ImageSprite.ts';\r\n\r\nimport { setScale, setAspectRatio, canvas, ctx } from './canvas.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 Oval,\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 Oval,\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 OvalOptions,\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","mouseX","mouseY","canvasMouseX","canvasMouseY","localX","localY","angle","rotatedX","rotatedY","min","max","deg","val","rad","e","Rectangle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","width","height","color","options","Oval","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radA","radB","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","Oval","RegularPolygon","Pen","Text","ImageSprite","setScale","setAspectRatio","canvas","ctx","index_default"]}
1
+ {"version":3,"sources":["../src/canvas.ts","../src/Sprite.ts","../src/Engine.ts","../src/Rectangle.ts","../src/Oval.ts","../src/RegularPolygon.ts","../src/Pen.ts","../src/Text.ts","../src/ImageSprite.ts","../src/index.ts"],"sourcesContent":["export const canvas = document.getElementById('game-window') as HTMLCanvasElement;\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 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 } 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\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 }\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 function\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 // Mouse 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 // 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 canvas.addEventListener('mousemove', e => {\r\n this.mouseX = e.clientX - canvas.offsetLeft - canvas.width / 2;\r\n this.mouseY = -(e.clientY - canvas.offsetTop - canvas.height / 2);\r\n });\r\n canvas.addEventListener('mousedown', e => {\r\n this.mouseDown = true;\r\n });\r\n canvas.addEventListener('mouseup', e => {\r\n this.mouseDown = false;\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 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 = 'black';\r\n this.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 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 = 'black';\r\n this.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 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 = 'black';\r\n this.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}","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 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 = 'black';\r\n this.outlineWidth = 0;\r\n }\r\n}","import Engine from './Engine.ts';\r\n\r\nimport Sprite, { type SpriteOptions } from './Sprite.ts';\r\nimport Rectangle, { type RectangleOptions } from './Rectangle.ts';\r\nimport Oval, { type OvalOptions } from './Oval.ts';\r\nimport RegularPolygon, { type RegularPolygonOptions } from './RegularPolygon.ts';\r\nimport Pen, { type PenOptions } from './Pen.ts';\r\nimport Text, { type TextOptions, type CanvasTextAlign, type CanvasTextBaseline } from './Text.ts';\r\nimport ImageSprite, { type ImageSpriteOptions } from './ImageSprite.ts';\r\n\r\nimport { setScale, setAspectRatio, canvas, ctx } from './canvas.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 Oval,\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 Oval,\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 OvalOptions,\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","mouseX","mouseY","canvasMouseX","canvasMouseY","localX","localY","angle","rotatedX","rotatedY","src","audio","sound","min","max","deg","val","rad","e","Rectangle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","width","height","color","options","Oval","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radA","radB","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","Oval","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.8",
3
+ "version": "0.4.0",
4
4
  "description": "A Scratch-style game engine for TypeScript.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",