{"version":3,"sources":["../src/index.ts","../src/canvas.ts","../src/Sprite.ts","../src/Engine.ts","../src/sprites/Rectangle.ts","../src/sprites/Square.ts","../src/sprites/Oval.ts","../src/sprites/Circle.ts","../src/sprites/Arc.ts","../src/sprites/RegularPolygon.ts","../src/sprites/CustomPolygon.ts","../src/sprites/Pen.ts","../src/sprites/Text.ts","../src/sprites/ImageSprite.ts"],"sourcesContent":["import Engine from './Engine.ts';\r\nimport Sprite, { type SpriteOptions } from './Sprite.ts';\r\nimport { setScale, setAspectRatio, canvas, ctx } from './canvas.ts';\r\n\r\nimport Rectangle, { type RectangleOptions } from './sprites/Rectangle.ts';\r\nimport Square, { type SquareOptions } from './sprites/Square.ts';\r\nimport Oval, { type OvalOptions } from './sprites/Oval.ts';\r\nimport Circle, { type CircleOptions } from './sprites/Circle.ts';\r\nimport Arc, { type ArcOptions } from './sprites/Arc.ts';\r\nimport RegularPolygon, { type RegularPolygonOptions } from './sprites/RegularPolygon.ts';\r\nimport CustomPolygon, { type CustomPolygonOptions } from './sprites/CustomPolygon.ts';\r\nimport Pen, { type PenOptions } from './sprites/Pen.ts';\r\nimport Text, { type TextOptions, type CanvasTextAlign, type CanvasTextBaseline } from './sprites/Text.ts';\r\nimport ImageSprite, { type ImageSpriteOptions } from './sprites/ImageSprite.ts';\r\n\r\nimport type { Vec2, Vec3, Vec4 } from './types/Vectors.ts';\r\n\r\nconst TScratch = {\r\n    // Main\r\n    Engine,\r\n    Sprite,\r\n\r\n    // Sprites\r\n    Rectangle,\r\n    Square,\r\n    Oval,\r\n    Circle,\r\n    Arc,\r\n    RegularPolygon,\r\n    CustomPolygon,\r\n    Pen,\r\n    Text,\r\n    ImageSprite,\r\n\r\n    // Canvas\r\n    setScale,\r\n    setAspectRatio,\r\n    canvas,\r\n    ctx\r\n};\r\n\r\nexport default TScratch;\r\nexport {\r\n    // Main\r\n    Engine,\r\n    Sprite,\r\n\r\n    // Sprites\r\n    Rectangle,\r\n    Square,\r\n    Oval,\r\n    Circle,\r\n    Arc,\r\n    RegularPolygon,\r\n    CustomPolygon,\r\n    Pen,\r\n    Text,\r\n    ImageSprite,\r\n\r\n    // Options\r\n    type SpriteOptions,\r\n    type RectangleOptions,\r\n    type SquareOptions,\r\n    type OvalOptions,\r\n    type CircleOptions,\r\n    type ArcOptions,\r\n    type RegularPolygonOptions,\r\n    type CustomPolygonOptions,\r\n    type PenOptions,\r\n    type TextOptions,\r\n    type ImageSpriteOptions,\r\n\r\n    // Other types\r\n    type CanvasTextAlign,\r\n    type CanvasTextBaseline,\r\n    type Vec2,\r\n    type Vec3,\r\n    type Vec4,\r\n    \r\n    // Canvas\r\n    setScale,\r\n    setAspectRatio,\r\n    canvas,\r\n    ctx\r\n};","export const canvas = document.getElementById('game-window') as HTMLCanvasElement || document.createElement('canvas'); // For testing\r\nexport const ctx = canvas.getContext('2d')!;\r\n\r\nexport const penCanvas = document.createElement('canvas');\r\nexport const penCtx = penCanvas.getContext('2d')!;\r\npenCanvas.id = 'pen-canvas';\r\n\r\nlet ratio: number = 16 / 9;\r\nlet scale: number;\r\n\r\nexport function setScale(newScale: number) {\r\n    scale = newScale;\r\n\r\n    canvas.width = ratio * scale;\r\n    canvas.height = scale;\r\n\r\n    penCanvas.width = ratio * scale;\r\n    penCanvas.height = scale;\r\n}\r\n\r\nexport function setAspectRatio(newAspectRatio: number) {\r\n    ratio = newAspectRatio;\r\n\r\n    canvas.width = ratio * scale;\r\n    canvas.height = scale;\r\n\r\n    penCanvas.width = ratio * scale;\r\n    penCanvas.height = scale;\r\n}\r\n\r\ncanvas.parentElement?.insertBefore(penCanvas, canvas);\r\n\r\nsetScale(500);","import Engine from './Engine.ts';\r\n\r\nexport interface BoundingBox {\r\n    x: number;\r\n    y: number;\r\n    width: number;\r\n    height: number;\r\n}\r\n\r\nexport interface SpriteOptions {\r\n    x?: number;\r\n    y?: number;\r\n    dir?: number;\r\n    scene?: string;\r\n    hidden?: boolean;\r\n    layer?: number;\r\n}\r\n\r\nexport default abstract class Sprite {\r\n\r\n    public x: number;\r\n    public y: number;\r\n    public dir: number;\r\n    public scene: string;\r\n    public hidden: boolean;\r\n    public layer: number;\r\n\r\n    private cachedPath: Path2D | null = null;\r\n    private pathDirty: boolean = true;\r\n\r\n    // Reusable collision detection canvas\r\n    private static collisionCanvas: HTMLCanvasElement | null = null;\r\n    private static collisionCtx: CanvasRenderingContext2D | null = null;\r\n\r\n    // Rendering\r\n\r\n    public abstract getBoundingBox(): BoundingBox;\r\n    public abstract getPath(): Path2D;\r\n    public abstract draw(stamping?: boolean): void;\r\n\r\n    protected refresh() {\r\n        Engine.init().refresh();\r\n    }\r\n\r\n    protected invalidatePath() {\r\n        this.pathDirty = true;\r\n        this.cachedPath = null;\r\n    }\r\n\r\n    protected getCachedPath(): Path2D {\r\n        if (this.pathDirty || !this.cachedPath) {\r\n            this.cachedPath = this.getPath();\r\n            this.pathDirty = false;\r\n        }\r\n        return this.cachedPath;\r\n    }\r\n\r\n    constructor(options?: SpriteOptions) {\r\n        this.x = options?.x ?? 0;\r\n        this.y = options?.y ?? 0;\r\n        this.dir = options?.dir ?? 0;\r\n        this.scene = options?.scene ?? 'main';\r\n        this.hidden = options?.hidden ?? false;\r\n        this.layer = options?.layer ?? 0;\r\n        Engine.init().addSprite(this);\r\n    }\r\n\r\n    // Sensing\r\n\r\n    public touching(sprite: Sprite): boolean {\r\n\r\n        // AABB (bounding boxes)\r\n        const bBox1 = this.getBoundingBox();\r\n        const bBox2 = sprite.getBoundingBox();\r\n\r\n        const aabbOverlap =\r\n            Math.abs(bBox1.x - bBox2.x) < (bBox1.width + bBox2.width) / 2 &&\r\n            Math.abs(bBox1.y - bBox2.y) < (bBox1.height + bBox2.height) / 2;\r\n\r\n        if (!aabbOverlap) return false;\r\n\r\n        // Image data (pixel perfect)\r\n\r\n        // Compute intersection bounding box\r\n        const b1Left = bBox1.x - bBox1.width / 2;\r\n        const b1Top = bBox1.y + bBox1.height / 2;\r\n        const b1Right = bBox1.x + bBox1.width / 2;\r\n        const b1Bottom = bBox1.y - bBox1.height / 2;\r\n\r\n        const b2Left = bBox2.x - bBox2.width / 2;\r\n        const b2Top = bBox2.y + bBox2.height / 2;\r\n        const b2Right = bBox2.x + bBox2.width / 2;\r\n        const b2Bottom = bBox2.y - bBox2.height / 2;\r\n\r\n        const xMin = Math.max(b1Left, b2Left);\r\n        const yMin = Math.min(b1Bottom, b2Bottom);\r\n        const xMax = Math.min(b1Right, b2Right);\r\n        const yMax = Math.max(b1Top, b2Top);\r\n\r\n        const width = xMax - xMin;\r\n        const height = yMax - yMin;\r\n\r\n        if (width <= 1 || height <= 1) return false;\r\n\r\n        // Reuse or create offscreen canvas for collision detection\r\n        if (!Sprite.collisionCanvas) {\r\n            Sprite.collisionCanvas = document.createElement('canvas');\r\n            Sprite.collisionCtx = Sprite.collisionCanvas.getContext('2d', { willReadFrequently: true })!;\r\n        }\r\n\r\n        // Resize if needed\r\n        if (Sprite.collisionCanvas.width < width || Sprite.collisionCanvas.height < height) {\r\n            Sprite.collisionCanvas.width = Math.max(width, Sprite.collisionCanvas.width);\r\n            Sprite.collisionCanvas.height = Math.max(height, Sprite.collisionCanvas.height);\r\n        }\r\n\r\n        const ctx = Sprite.collisionCtx!;\r\n        ctx.clearRect(0, 0, width, height);\r\n\r\n        // Draw first sprite\r\n        ctx.save();\r\n        ctx.translate(this.x - xMin, height - this.y + yMin);\r\n        ctx.rotate(this.toRadians(this.dir));\r\n        ctx.fillStyle = 'red';\r\n        ctx.fill(this.getCachedPath());\r\n        ctx.restore();\r\n        const img1 = ctx.getImageData(0, 0, width, height).data;\r\n\r\n        // Draw second sprite\r\n        ctx.clearRect(0, 0, width, height);\r\n        ctx.save();\r\n        ctx.translate(sprite.x - xMin, height - sprite.y + yMin);\r\n        ctx.rotate(this.toRadians(sprite.dir));\r\n        ctx.fillStyle = 'blue';\r\n        ctx.fill(sprite.getCachedPath());\r\n        ctx.restore();\r\n        const img2 = ctx.getImageData(0, 0, width, height).data;\r\n\r\n        // Check for overlapping non-transparent pixels\r\n        for (let i = 3; i < img1.length; i += 4) // alpha channel\r\n            if (img1[i]! > 0 && img2[i]! > 0) return true;\r\n\r\n        return false;\r\n    }\r\n\r\n    // Helpers\r\n\r\n    protected toRadians(deg: number) {\r\n        return deg * Math.PI / 180;\r\n    }\r\n\r\n    protected toDegrees(rad: number) {\r\n        return rad * 180 / Math.PI;\r\n    }\r\n\r\n    // Methods\r\n\r\n    // Motion\r\n    public move(steps: number) {\r\n        this.x += steps * Math.sin(this.toRadians(this.dir));\r\n        this.y += steps * Math.cos(this.toRadians(this.dir));\r\n        this.refresh();\r\n    }\r\n\r\n    public turn(deg: number) {\r\n        this.dir += deg;\r\n        this.refresh();\r\n    }\r\n\r\n    public point(dir: number) {\r\n        this.dir = dir;\r\n        this.refresh();\r\n    }\r\n\r\n    public pointTowards(x: number, y: number) {\r\n        this.dir = 90 - this.toDegrees(Math.atan2(y, x));\r\n        this.refresh();\r\n    }\r\n\r\n    public setX(x: number) {\r\n        this.x = x;\r\n        this.refresh();\r\n    }\r\n\r\n    public setY(y: number) {\r\n        this.y = y;\r\n        this.refresh();\r\n    }\r\n\r\n    public goTo(x: number, y: number) {\r\n        this.x = x;\r\n        this.y = y;\r\n        this.refresh();\r\n    }\r\n\r\n    public changeX(dX: number) {\r\n        this.x += dX;\r\n        this.refresh();\r\n    }\r\n\r\n    public changeY(dY: number) {\r\n        this.y += dY;\r\n        this.refresh();\r\n    }\r\n\r\n    // Looks\r\n\r\n    public show() {\r\n        this.hidden = false;\r\n        this.refresh();\r\n    }\r\n\r\n    public hide() {\r\n        this.hidden = true;\r\n        this.refresh();\r\n    }\r\n\r\n    public goToLayer(layer: number) {\r\n        this.layer = layer;\r\n        this.refresh();\r\n    }\r\n\r\n    public changeLayer(dL: number) {\r\n        this.layer += dL;\r\n        this.refresh();\r\n    }\r\n}","import { canvas, ctx, penCanvas } from './canvas.ts';\r\nimport Sprite from './Sprite.ts';\r\nimport type { Vec2, Vec3, Vec4 } from './types/Vectors.ts';\r\n\r\ntype GameLoop = (() => any) | (() => Promise<any>);\r\n\r\ntype SceneMap = {\r\n    [scene: string]: {\r\n        sprites: Sprite[];\r\n        loop: GameLoop | null;\r\n    };\r\n};\r\n\r\nexport default class Engine {\r\n\r\n    private static instance: Engine;\r\n\r\n    private loopRunning: boolean = false;\r\n    public gameLoop: GameLoop | null = null;\r\n\r\n    public maxFPS: number = 24;\r\n    public deltaTime: number = 1 / this.maxFPS;\r\n    private lastFrame: number = performance.now();\r\n    private refreshScheduled: boolean = false;\r\n    private animationFrameId: number | null = null;\r\n\r\n    public sounds: HTMLAudioElement[] = [];\r\n\r\n    public mouseX: number = 0;\r\n    public mouseY: number = 0;\r\n\r\n    public mouseDown: boolean = false;\r\n    public mouseClicked: boolean = false;\r\n\r\n    private keysPressed: Set<string> = new Set<string>();\r\n\r\n    public currentScene: string = 'main';\r\n    public sceneMap: SceneMap = {};\r\n\r\n    // Singleton initialization\r\n\r\n    public static init() {\r\n        if (!this.instance)\r\n            this.instance = new Engine();\r\n\r\n        return this.instance;\r\n    }\r\n\r\n    // Change the scene\r\n\r\n    public changeScene(scene: string) {\r\n        if (!this.sceneMap[scene])\r\n            this.sceneMap[scene] = { sprites: [], loop: null };\r\n\r\n        this.loopRunning = false;\r\n        this.currentScene = scene;\r\n        this.gameLoop = this.sceneMap[scene].loop;\r\n        this.setMaxFramesPerSecond(this.maxFPS); // Update the interval function\r\n    }\r\n\r\n    // Loops\r\n\r\n    public setLoop(scene: string, loop: GameLoop) {\r\n        if (!this.sceneMap[scene]) {\r\n            this.sceneMap[scene] = { sprites: [], loop };\r\n            if (scene === this.currentScene)\r\n                this.changeScene(scene);\r\n            return;\r\n        }\r\n\r\n        this.sceneMap[scene].loop = loop;\r\n        if (scene === this.currentScene)\r\n            this.changeScene(scene);\r\n    }\r\n\r\n    public pauseLoop() {\r\n        this.loopRunning = false;\r\n        if (this.animationFrameId !== null) {\r\n            cancelAnimationFrame(this.animationFrameId);\r\n            this.animationFrameId = null;\r\n        }\r\n    }\r\n\r\n    public resumeLoop() {\r\n        this.loopRunning = true;\r\n        void this.setMaxFramesPerSecond(this.maxFPS);\r\n    }\r\n\r\n    // Internal\r\n\r\n    public addSprite(sprite: Sprite) {\r\n        const { scene, layer } = sprite;\r\n\r\n        if (!this.sceneMap[scene]) {\r\n            this.sceneMap[scene] = { sprites: [sprite], loop: null };\r\n            return;\r\n        }\r\n\r\n        let targetIndex = this.sceneMap[scene].sprites.findIndex(s => s.layer > layer);\r\n        if (targetIndex === -1) {\r\n            this.sceneMap[scene].sprites.push(sprite);\r\n            return;\r\n        }\r\n\r\n        this.sceneMap[scene].sprites.splice(targetIndex, 0, sprite);\r\n        this.refresh();\r\n    }\r\n\r\n    public removeSprite(sprite: Sprite) {\r\n        const { scene } = sprite;\r\n\r\n        if (!this.sceneMap[scene]) return;\r\n\r\n        this.sceneMap[scene].sprites = this.sceneMap[scene].sprites.filter(s => s !== sprite);\r\n        this.refresh();\r\n    }\r\n\r\n    public async setMaxFramesPerSecond(maxFPS: number) {\r\n        this.maxFPS = maxFPS;\r\n\r\n        let loop = this.gameLoop;\r\n        if (!loop) return;\r\n\r\n        // Cancel existing animation frame if any\r\n        if (this.animationFrameId !== null) {\r\n            cancelAnimationFrame(this.animationFrameId);\r\n            this.animationFrameId = null;\r\n        }\r\n\r\n        this.loopRunning = true;\r\n        const frameInterval = 1000 / maxFPS;\r\n        let accumulator = 0;\r\n\r\n        const tick = async (currentTime: number) => {\r\n            if (!this.loopRunning) return;\r\n\r\n            const deltaTime = currentTime - this.lastFrame;\r\n            this.lastFrame = currentTime;\r\n            accumulator += deltaTime;\r\n\r\n            // Fixed timestep: only run loop when enough time has passed\r\n            if (accumulator >= frameInterval) {\r\n                this.deltaTime = accumulator / 1000;\r\n                accumulator = accumulator % frameInterval;\r\n\r\n                if (loop) await loop();\r\n            }\r\n\r\n            this.animationFrameId = requestAnimationFrame(tick);\r\n        };\r\n\r\n        this.lastFrame = performance.now();\r\n        this.animationFrameId = requestAnimationFrame(tick);\r\n    }\r\n\r\n    public refresh() {\r\n        if (this.refreshScheduled) return;\r\n        this.refreshScheduled = true;\r\n\r\n        requestAnimationFrame(() => {\r\n            this.refreshScheduled = false;\r\n            ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n            const sprites = [\r\n                ...(this.sceneMap[this.currentScene]?.sprites ?? []),\r\n                ...(this.sceneMap['*']?.sprites ?? [])\r\n            ];\r\n            sprites.forEach(sprite => {\r\n                if (!sprite.hidden)\r\n                    sprite.draw();\r\n            });\r\n        });\r\n    }\r\n\r\n    // Wait functions\r\n\r\n    public async wait(ms: number): Promise<void> {\r\n        return new Promise(resolve => setTimeout(resolve, ms));\r\n    }\r\n\r\n    public async waitUntil(conditionGetter: () => boolean): Promise<void> {\r\n        return new Promise(resolve => {\r\n            const check = () => {\r\n                if (conditionGetter()) resolve();\r\n                else setTimeout(check, 1000 / this.maxFPS);\r\n            }\r\n            check();\r\n        });\r\n    }\r\n\r\n    // Events\r\n\r\n    public hovering(sprite: Sprite) {\r\n        const { mouseX, mouseY } = this;\r\n\r\n        const canvasMouseX = mouseX + canvas.width / 2;\r\n        const canvasMouseY = canvas.height / 2 - mouseY;\r\n\r\n        // Mouse relative to sprite center\r\n        const localX = canvasMouseX - (sprite.x + canvas.width / 2);\r\n        const localY = canvasMouseY - (canvas.height / 2 - sprite.y);\r\n\r\n        // Rotate mouse point by -dir to align with the path's local coordinates\r\n        const angle = -this.toRadians(sprite.dir);\r\n        const rotatedX = localX * Math.cos(angle) - localY * Math.sin(angle);\r\n        const rotatedY = localX * Math.sin(angle) + localY * Math.cos(angle);\r\n\r\n        return ctx.isPointInPath(sprite.getPath(), rotatedX, rotatedY);\r\n    }\r\n\r\n    public keyPressed(key: string) {\r\n        return this.keysPressed.has(key);\r\n    }\r\n\r\n    // Sound\r\n\r\n    public playSound(src: string) {\r\n        const audio = new Audio(src);\r\n        this.sounds.push(audio);\r\n\r\n        audio.play();\r\n\r\n        return audio;\r\n    }\r\n\r\n    public stopSound(sound: HTMLAudioElement) {\r\n        sound.pause();\r\n        sound.currentTime = 0;\r\n        this.sounds = this.sounds.filter(s => s !== sound);\r\n    }\r\n\r\n    public stopAllSounds() {\r\n        this.sounds.forEach(sound => {\r\n            sound.pause();\r\n            sound.currentTime = 0;\r\n        });\r\n        this.sounds = [];\r\n    }\r\n\r\n    // Math\r\n\r\n    public pickRandom(min: number, max: number) {\r\n        if (min > max)\r\n            [min, max] = [max, min];\r\n        return Math.floor(Math.random() * (max - min + 1) + min);\r\n    }\r\n\r\n    public dotProduct(vectors: [Vec2, Vec2] | [Vec3, Vec3] | [Vec4, Vec4]) {\r\n        const [a, b] = vectors;\r\n\r\n        switch (a.length) {\r\n            case 2: return a[0] * b[0] + a[1] * b[1];\r\n            case 3: return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]!;\r\n            case 4: return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]! + a[3] * b[3]!; // TypeScript doesn't narrow down the types on b\r\n        }\r\n    }\r\n\r\n    // Trigonometric functions\r\n    public sin(deg: number) {\r\n        return Math.sin(this.toRadians(deg));\r\n    }\r\n\r\n    public cos(deg: number) {\r\n        return Math.cos(this.toRadians(deg));\r\n    }\r\n\r\n    public tan(deg: number) {\r\n        return Math.tan(this.toRadians(deg));\r\n    }\r\n\r\n    public csc(deg: number) {\r\n        return 1 / Math.sin(this.toRadians(deg));\r\n    }\r\n\r\n    public sec(deg: number) {\r\n        return 1 / Math.cos(this.toRadians(deg));\r\n    }\r\n\r\n    public cot(deg: number) {\r\n        return 1 / Math.tan(this.toRadians(deg));\r\n    }\r\n\r\n    // Inverse Trigonometric functions\r\n    public asin(val: number) {\r\n        return this.toDegrees(Math.asin(val));\r\n    }\r\n\r\n    public acos(val: number) {\r\n        return this.toDegrees(Math.acos(val));\r\n    }\r\n\r\n    public acsc(val: number) {\r\n        return this.toDegrees(Math.asin(1 / val));\r\n    }\r\n\r\n    public asec(val: number) {\r\n        return this.toDegrees(Math.acos(1 / val));\r\n    }\r\n\r\n    // Helpers\r\n\r\n    public toRadians(deg: number) {\r\n        return deg * Math.PI / 180;\r\n    }\r\n\r\n    public toDegrees(rad: number) {\r\n        return rad * 180 / Math.PI;\r\n    }\r\n\r\n    // Private constructor\r\n\r\n    private constructor() {\r\n        void this.setMaxFramesPerSecond(24);\r\n\r\n        // Events\r\n\r\n        // Mouse\r\n        penCanvas.addEventListener('mousemove', e => {\r\n            this.mouseX = e.clientX - penCanvas.offsetLeft - penCanvas.width / 2;\r\n            this.mouseY = -(e.clientY - penCanvas.offsetTop - penCanvas.height / 2);\r\n        });\r\n        penCanvas.addEventListener('mousedown', e => {\r\n            this.mouseDown = true;\r\n        });\r\n        penCanvas.addEventListener('mouseup', e => {\r\n            this.mouseDown = false;\r\n        });\r\n        penCanvas.addEventListener('click', e => {\r\n            this.mouseClicked = true;\r\n            setTimeout(() => this.mouseClicked = false, 0);\r\n        });\r\n\r\n        // Keys\r\n        addEventListener('keydown', e => {\r\n            if (e.repeat) return;\r\n            this.keysPressed.add(e.key);\r\n        });\r\n\r\n        addEventListener('keyup', e => {\r\n            this.keysPressed.delete(e.key);\r\n        });\r\n    }\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { ctx, canvas, penCtx } from '../canvas.ts';\r\n\r\nexport interface RectangleOptions extends SpriteOptions {\r\n    width?: number;\r\n    height?: number;\r\n    color?: string;\r\n    outlineColor?: string;\r\n    outlineWidth?: number;\r\n};\r\n\r\nexport default class Rectangle extends Sprite {\r\n\r\n    public discriminant = 'rectangle';\r\n\r\n    public width: number;\r\n    public height: number;\r\n    public color: string;\r\n    public outlineColor: string;\r\n    public outlineWidth: number;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: Math.hypot(this.width, this.height),\r\n            height: Math.hypot(this.width, this.height)\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n\r\n        path.rect(\r\n            -this.width / 2,\r\n            -this.height / 2,\r\n            this.width,\r\n            this.height\r\n        );\r\n\r\n        return path;\r\n    }\r\n\r\n    public draw(stamping?: boolean): void {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n        c.translate(cX, cY);\r\n\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        const path = this.getCachedPath();\r\n\r\n        c.fillStyle = this.color;\r\n        c.strokeStyle = this.outlineColor;\r\n        c.lineWidth = this.outlineWidth;\r\n        c.fill(path)\r\n        if (this.outlineWidth)\r\n            c.stroke(path);\r\n\r\n        c.restore();\r\n    }\r\n\r\n    public setWidth(width: number) {\r\n        this.width = width;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setHeight(height: number) {\r\n        this.height = height;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setColor(color: string) {\r\n        this.color = color;\r\n        this.refresh();\r\n    }\r\n\r\n    constructor(options?: RectangleOptions) {\r\n        super(options);\r\n        this.width = options?.width ?? 50;\r\n        this.height = options?.height ?? 50;\r\n        this.color = options?.color ?? 'black';\r\n        this.outlineColor = options?.outlineColor ?? 'black';\r\n        this.outlineWidth = options?.outlineWidth ?? 0;\r\n        this.draw();\r\n    }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { ctx, canvas, penCtx } from '../canvas.ts';\r\n\r\nexport interface SquareOptions extends SpriteOptions {\r\n    sideLength?: number;\r\n    color?: string;\r\n    outlineColor?: string;\r\n    outlineWidth?: number;\r\n};\r\n\r\nexport default class Square extends Sprite {\r\n\r\n    public discriminant = 'square';\r\n\r\n    public sideLength: number;\r\n    public color: string;\r\n    public outlineColor: string;\r\n    public outlineWidth: number;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: Math.hypot(this.sideLength, this.sideLength),\r\n            height: Math.hypot(this.sideLength, this.sideLength)\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n\r\n        path.rect(\r\n            -this.sideLength / 2,\r\n            -this.sideLength / 2,\r\n            this.sideLength,\r\n            this.sideLength\r\n        );\r\n\r\n        return path;\r\n    }\r\n\r\n    public draw(stamping?: boolean): void {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n        c.translate(cX, cY);\r\n\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        const path = this.getCachedPath();\r\n\r\n        c.fillStyle = this.color;\r\n        c.strokeStyle = this.outlineColor;\r\n        c.lineWidth = this.outlineWidth;\r\n        c.fill(path)\r\n        if (this.outlineWidth)\r\n            c.stroke(path);\r\n\r\n        c.restore();\r\n    }\r\n\r\n    public setSideLength(sideLength: number) {\r\n        this.sideLength = sideLength;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setColor(color: string) {\r\n        this.color = color;\r\n        this.refresh();\r\n    }\r\n\r\n    constructor(options?: SquareOptions) {\r\n        super(options);\r\n        this.sideLength = options?.sideLength ?? 50;\r\n        this.color = options?.color ?? 'black';\r\n        this.outlineColor = options?.outlineColor ?? 'black';\r\n        this.outlineWidth = options?.outlineWidth ?? 0;\r\n        this.draw();\r\n    }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface OvalOptions extends SpriteOptions {\r\n    radX?: number;\r\n    radY?: number;\r\n    color?: string;\r\n    outlineColor?: string;\r\n    outlineWidth?: number;\r\n};\r\n\r\nexport default class Oval extends Sprite {\r\n\r\n    public discriminant = 'oval';\r\n\r\n    public radX: number;\r\n    public radY: number;\r\n    public color: string;\r\n    public outlineColor: string;\r\n    public outlineWidth: number;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: Math.hypot(this.radX * 2, this.radY * 2),\r\n            height: Math.hypot(this.radX * 2, this.radY * 2)\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n\r\n        path.ellipse(\r\n            0, 0,\r\n            this.radX,\r\n            this.radY,\r\n            0, 0,\r\n            Math.PI * 2\r\n        );\r\n\r\n        return path;\r\n    }\r\n\r\n    public draw(stamping?: boolean): void {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n        c.translate(cX, cY);\r\n\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        const path = this.getCachedPath();\r\n\r\n        c.fillStyle = this.color;\r\n        c.strokeStyle = this.outlineColor;\r\n        c.lineWidth = this.outlineWidth;\r\n        c.fill(path)\r\n        if (this.outlineWidth)\r\n            c.stroke(path);\r\n\r\n        c.restore();\r\n    }\r\n\r\n    public setRadX(radX: number) {\r\n        this.radX = radX;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setRadY(radY: number) {\r\n        this.radY = radY;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setColor(color: string) {\r\n        this.color = color;\r\n        this.refresh();\r\n    }\r\n\r\n    constructor(options?: OvalOptions) {\r\n        super(options);\r\n        this.radX = options?.radX ?? 25;\r\n        this.radY = options?.radY ?? 25;\r\n        this.color = options?.color ?? 'black';\r\n        this.outlineColor = options?.outlineColor ?? 'black';\r\n        this.outlineWidth = options?.outlineWidth ?? 0;\r\n        this.draw();\r\n    }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface CircleOptions extends SpriteOptions {\r\n    radius?: number;\r\n    color?: string;\r\n    outlineColor?: string;\r\n    outlineWidth?: number;\r\n};\r\n\r\nexport default class Circle extends Sprite {\r\n\r\n    public discriminant = 'circle';\r\n\r\n    public radius: number;\r\n    public color: string;\r\n    public outlineColor: string;\r\n    public outlineWidth: number;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: this.radius * 2,\r\n            height: this.radius * 2\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n\r\n        path.ellipse(\r\n            0, 0,\r\n            this.radius,\r\n            this.radius,\r\n            0, 0,\r\n            Math.PI * 2\r\n        );\r\n\r\n        return path;\r\n    }\r\n\r\n    public draw(stamping?: boolean): void {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n        c.translate(cX, cY);\r\n\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        const path = this.getCachedPath();\r\n\r\n        c.fillStyle = this.color;\r\n        c.strokeStyle = this.outlineColor;\r\n        c.lineWidth = this.outlineWidth;\r\n        c.fill(path)\r\n        if (this.outlineWidth)\r\n            c.stroke(path);\r\n\r\n        c.restore();\r\n    }\r\n\r\n    public setRadius(radius: number) {\r\n        this.radius = radius;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setColor(color: string) {\r\n        this.color = color;\r\n        this.refresh();\r\n    }\r\n\r\n    constructor(options?: CircleOptions) {\r\n        super(options);\r\n        this.radius = options?.radius ?? 25;\r\n        this.color = options?.color ?? 'black';\r\n        this.outlineColor = options?.outlineColor ?? 'black';\r\n        this.outlineWidth = options?.outlineWidth ?? 0;\r\n        this.draw();\r\n    }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\n\r\nexport interface ArcOptions extends SpriteOptions {\r\n    radius?: number;\r\n    angle?: number;\r\n    color?: string;\r\n    outlineColor?: string;\r\n    outlineWidth?: number;\r\n};\r\n\r\nexport default class Arc extends Sprite {\r\n\r\n    public discriminant = 'arc';\r\n\r\n    public radius: number;\r\n    public angle: number;\r\n    public color: string;\r\n    public outlineColor: string;\r\n    public outlineWidth: number;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: this.radius * 2,\r\n            height: this.radius * 2\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n\r\n        path.arc(\r\n            0, 0,\r\n            this.radius,\r\n            this.toRadians(this.angle / 2 - 90),\r\n            this.toRadians(-this.angle / 2 - 90)\r\n        );\r\n\r\n        return path;\r\n    }\r\n\r\n    public draw(stamping?: boolean): void {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n        c.translate(cX, cY);\r\n\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        const path = this.getCachedPath();\r\n\r\n        c.fillStyle = this.color;\r\n        c.strokeStyle = this.outlineColor;\r\n        c.lineWidth = this.outlineWidth;\r\n        c.fill(path)\r\n        if (this.outlineWidth)\r\n            c.stroke(path);\r\n\r\n        c.restore();\r\n    }\r\n\r\n    public setRadius(radius: number) {\r\n        this.radius = radius;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setAngle(angle: number) {\r\n        this.angle = angle;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setColor(color: string) {\r\n        this.color = color;\r\n        this.refresh();\r\n    }\r\n\r\n    constructor(options?: ArcOptions) {\r\n        super(options);\r\n\r\n        this.radius = options?.radius ?? 25;\r\n        this.angle = options?.angle ?? 270;\r\n        this.color = options?.color ?? 'black';\r\n        this.outlineColor = options?.outlineColor ?? 'black';\r\n        this.outlineWidth = options?.outlineWidth ?? 0;\r\n\r\n        this.draw();\r\n    }\r\n\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface RegularPolygonOptions extends SpriteOptions {\r\n    sides?: number;\r\n    radius?: number;\r\n    color?: string;\r\n    outlineColor?: string;\r\n    outlineWidth?: number;\r\n}\r\n\r\nexport default class RegularPolygon extends Sprite {\r\n\r\n    public discriminant = 'regularpolygon';\r\n\r\n    public sides: number;\r\n    public radius: number;\r\n    public color: string;\r\n    public outlineColor: string;\r\n    public outlineWidth: number;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: this.radius * 2,\r\n            height: this.radius * 2\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n        const step = (2 * Math.PI) / this.sides;\r\n        path.moveTo(this.radius, 0);\r\n        for (let i = 1; i < this.sides; i++) {\r\n            path.lineTo(this.radius * Math.cos(step * i), this.radius * Math.sin(step * i));\r\n        }\r\n        path.closePath();\r\n        return path;\r\n    }\r\n\r\n    public draw(stamping?: boolean) {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n\r\n        c.translate(cX, cY);\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        const path = this.getCachedPath();\r\n\r\n        c.fillStyle = this.color;\r\n        c.strokeStyle = this.outlineColor;\r\n        c.lineWidth = this.outlineWidth;\r\n        c.fill(path)\r\n        if (this.outlineWidth)\r\n            c.stroke(path);\r\n\r\n        c.restore();\r\n    }\r\n\r\n    public setSides(sides: number) {\r\n        this.sides = sides;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setRadius(radius: number) {\r\n        this.radius = radius;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setColor(color: string) {\r\n        this.color = color;\r\n        this.refresh();\r\n    }\r\n\r\n    constructor(options?: RegularPolygonOptions) {\r\n        super(options);\r\n        this.sides = options?.sides ?? 5;\r\n        this.radius = options?.radius ?? 50;\r\n        this.color = options?.color ?? 'black';\r\n        this.outlineColor = options?.outlineColor ?? 'black';\r\n        this.outlineWidth = options?.outlineWidth ?? 0;\r\n        this.draw();\r\n    }\r\n\r\n}","import Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\nimport { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport type { Vec2 } from '../types/Vectors.ts';\r\n\r\nexport interface CustomPolygonOptions extends SpriteOptions {\r\n    vertices?: Vec2[];\r\n    color?: string;\r\n    outlineColor?: string;\r\n    outlineWidth?: number;\r\n};\r\n\r\nexport default class CustomPolygon extends Sprite {\r\n\r\n    public discriminant = 'custompolygon';\r\n\r\n    public vertices: Vec2[];\r\n    public color: string;\r\n    public outlineColor: string;\r\n    public outlineWidth: number;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n\r\n        let furthestVertexSize = 0;\r\n\r\n        for (const v of this.vertices) {\r\n\r\n            const size = Math.hypot(v[0], v[1]);\r\n\r\n            if (size > furthestVertexSize)\r\n                furthestVertexSize = size;\r\n        }\r\n\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: furthestVertexSize,\r\n            height: furthestVertexSize\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n        const vertices = this.vertices;\r\n\r\n        if (vertices.length < 2) return path;\r\n\r\n        path.moveTo(vertices[0]![0], vertices[0]![1]);\r\n\r\n        for (let i = 1; i < vertices.length; i++)\r\n            path.lineTo(vertices[i]![0], vertices[i]![1]);\r\n\r\n        path.closePath();\r\n\r\n        return path;\r\n    }\r\n\r\n    public draw(stamping?: boolean): void {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n        c.translate(cX, cY);\r\n\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        const path = this.getCachedPath();\r\n\r\n        c.fillStyle = this.color;\r\n        c.strokeStyle = this.outlineColor;\r\n        c.lineWidth = this.outlineWidth;\r\n        c.fill(path)\r\n        if (this.outlineWidth)\r\n            c.stroke(path);\r\n\r\n        c.restore();\r\n    }\r\n\r\n    public setVertices(vertices: Vec2[]) {\r\n        this.vertices = vertices;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setColor(color: string) {\r\n        this.color = color;\r\n        this.refresh();\r\n    }\r\n\r\n    constructor(options?: CustomPolygonOptions) {\r\n        super(options);\r\n\r\n        this.vertices = options?.vertices ?? [];\r\n        this.color = options?.color ?? 'black';\r\n        this.outlineColor = options?.outlineColor ?? 'black';\r\n        this.outlineWidth = options?.outlineWidth ?? 0;\r\n\r\n        this.draw();\r\n    }\r\n\r\n}","import { canvas, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface PenOptions extends SpriteOptions {\r\n    drawing?: boolean;\r\n    size?: number;\r\n    color?: string;\r\n}\r\n\r\nexport default class Pen extends Sprite {\r\n\r\n    public discriminant = 'pen';\r\n\r\n    public drawing: boolean;\r\n    public size: number;\r\n    public color: string;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: this.size,\r\n            height: this.size\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        return new Path2D();\r\n    }\r\n    public draw() {}\r\n\r\n    public up() {\r\n        this.drawing = false;\r\n    }\r\n\r\n    public down() {\r\n        this.drawing = true;\r\n    }\r\n\r\n    public stamp(sprite: Sprite) {\r\n        sprite.draw(true);\r\n    }\r\n\r\n    public eraseAll() {\r\n        penCtx.clearRect(0, 0, canvas.width, canvas.height);\r\n    }\r\n\r\n    public dot() {\r\n        penCtx.fillStyle = this.color;\r\n        penCtx.fillRect(\r\n            this.x - this.size / 2 + canvas.width / 2,\r\n            -this.y - this.size / 2 + canvas.height / 2,\r\n            this.size,\r\n            this.size\r\n        );\r\n    }\r\n\r\n    private drawLine(lastX: number, lastY: number) {\r\n        penCtx.beginPath();\r\n\r\n        penCtx.moveTo(lastX + canvas.width / 2, -lastY + canvas.height / 2);\r\n        penCtx.lineTo(this.x + canvas.width / 2, -this.y + canvas.height / 2);\r\n\r\n        penCtx.lineWidth = this.size;\r\n        penCtx.strokeStyle = this.color;\r\n        penCtx.stroke();\r\n    }\r\n\r\n    // Overriding methods to include drawing\r\n\r\n    public override move(steps: number) {\r\n        const lastX = this.x;\r\n        const lastY = this.y;\r\n\r\n        this.x += steps * Math.sin(this.toRadians(this.dir));\r\n        this.y += steps * Math.cos(this.toRadians(this.dir));\r\n        if (this.drawing)\r\n            this.drawLine(lastX, lastY);\r\n        this.refresh();\r\n    }\r\n\r\n    public override setX(x: number) {\r\n        const lastX = this.x;\r\n        const lastY = this.y;\r\n\r\n        this.x = x;\r\n        if (this.drawing)\r\n            this.drawLine(lastX, lastY);\r\n        this.refresh();\r\n    }\r\n\r\n    public override setY(y: number) {\r\n        const lastX = this.x;\r\n        const lastY = this.y;\r\n\r\n        this.y = y;\r\n        if (this.drawing)\r\n            this.drawLine(lastX, lastY);\r\n        this.refresh();\r\n    }\r\n\r\n    public override goTo(x: number, y: number) {\r\n        const lastX = this.x;\r\n        const lastY = this.y;\r\n\r\n        this.x = x;\r\n        this.y = y;\r\n        if (this.drawing)\r\n            this.drawLine(lastX, lastY);\r\n        this.refresh();\r\n    }\r\n\r\n    public override changeX(dX: number) {\r\n        const lastX = this.x;\r\n        const lastY = this.y;\r\n\r\n        this.x += dX;\r\n        if (this.drawing)\r\n            this.drawLine(lastX, lastY);\r\n        this.refresh();\r\n    }\r\n\r\n    public override changeY(dY: number) {\r\n        const lastX = this.x;\r\n        const lastY = this.y;\r\n\r\n        this.y += dY;\r\n        if (this.drawing)\r\n            this.drawLine(lastX, lastY);\r\n        this.refresh();\r\n    }\r\n\r\n    // Constructor\r\n\r\n    constructor(options?: PenOptions) {\r\n        super(options);\r\n        this.drawing = options?.drawing ?? false;\r\n        this.size = options?.size ?? 5;\r\n        this.color = options?.color ?? 'black';\r\n    }\r\n\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport type CanvasTextAlign =\r\n    | 'left'\r\n    | 'right'\r\n    | 'center'\r\n    | 'start'\r\n    | 'end';\r\n\r\nexport type CanvasTextBaseline =\r\n    | 'top'\r\n    | 'hanging'\r\n    | 'middle'\r\n    | 'alphabetic'\r\n    | 'ideographic'\r\n    | 'bottom';\r\n\r\nexport interface TextOptions extends SpriteOptions {\r\n    content?: string;\r\n    color?: string;\r\n    fontFamily?: string;\r\n    fontSize?: number;\r\n    align?: CanvasTextAlign;\r\n    baseline?: CanvasTextBaseline;\r\n}\r\n\r\nexport default class Text extends Sprite {\r\n\r\n    public discriminant = 'text';\r\n\r\n    public content: string;\r\n    public color: string;\r\n    public fontFamily: string;\r\n    public fontSize: number;\r\n    public align: CanvasTextAlign;\r\n    public baseline: CanvasTextBaseline;\r\n\r\n    private font: string;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        const metrics = ctx.measureText(this.content);\r\n        const width = metrics.width;\r\n        const height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width, height\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n\r\n        ctx.save();\r\n        \r\n        ctx.font = this.font;\r\n\r\n        const metrics = ctx.measureText(this.content);\r\n        const width = metrics.width;\r\n        const height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n\r\n        ctx.restore();\r\n\r\n        path.rect(-width / 2, -height / 2, width, height);\r\n\r\n        return path\r\n    }\r\n\r\n    public override draw(stamping?: boolean) {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n        c.translate(cX, cY);\r\n\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        c.font = this.font;\r\n        c.fillStyle = this.color;\r\n        c.textAlign = this.align;\r\n        c.textBaseline = this.baseline;\r\n\r\n        c.fillText(this.content, 0, 0);\r\n\r\n        c.restore();\r\n    }\r\n\r\n    // Methods\r\n\r\n    public setContent(content: string) {\r\n        this.content = content;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setColor(color: string) {\r\n        this.color = color;\r\n        this.refresh();\r\n    }\r\n\r\n    public setFontSize(fontSize: number) {\r\n        this.fontSize = fontSize;\r\n        this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setFontFamily(fontFamily: string) {\r\n        this.fontFamily = fontFamily;\r\n        this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setAlign(align: CanvasTextAlign) {\r\n        this.align = align;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setBaseline(baseline: CanvasTextBaseline) {\r\n        this.baseline = baseline;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    // Constructor\r\n\r\n    constructor(options?: TextOptions) {\r\n        super(options);\r\n\r\n        this.content = options?.content ?? '';\r\n        this.color = options?.color ?? 'black';\r\n        this.fontFamily = options?.fontFamily ?? 'Arial';\r\n        this.fontSize = options?.fontSize ?? 16;\r\n        this.align = options?.align ?? 'center';\r\n        this.baseline = options?.baseline ?? 'middle';\r\n\r\n        this.font = `${this.fontSize}px ${this.fontFamily}`;\r\n\r\n        this.draw();\r\n    }\r\n}","import { canvas, ctx, penCtx } from '../canvas.ts';\r\nimport Sprite, { type BoundingBox, type SpriteOptions } from '../Sprite.ts';\r\n\r\nexport interface ImageSpriteOptions extends SpriteOptions {\r\n    src?: string;\r\n    width: number;\r\n    height: number;\r\n    outlineColor?: string;\r\n    outlineWidth?: number;\r\n};\r\n\r\nexport default class ImageSprite extends Sprite {\r\n\r\n    public discriminant = 'imagesprite';\r\n\r\n    public src: string;\r\n    public width: number;\r\n    public height: number;\r\n    public outlineColor: string;\r\n    public outlineWidth: number;\r\n\r\n    protected img: HTMLImageElement;\r\n\r\n    public getBoundingBox(): BoundingBox {\r\n        return {\r\n            x: this.x,\r\n            y: this.y,\r\n            width: this.width,\r\n            height: this.height\r\n        };\r\n    }\r\n\r\n    public getPath(): Path2D {\r\n        const path = new Path2D();\r\n\r\n        path.rect(\r\n            -this.width / 2,\r\n            -this.height / 2,\r\n            this.width,\r\n            this.height\r\n        );\r\n\r\n        return path;\r\n    }\r\n\r\n    public override draw(stamping?: boolean) {\r\n        const c = stamping ? penCtx : ctx;\r\n\r\n        c.save();\r\n\r\n        const cX = this.x + canvas.width / 2;\r\n        const cY = -this.y + canvas.height / 2;\r\n        c.translate(cX, cY);\r\n\r\n        c.rotate(this.toRadians(this.dir));\r\n\r\n        c.strokeStyle = this.outlineColor;\r\n        c.lineWidth = this.outlineWidth;\r\n        c.drawImage(\r\n            this.img,\r\n            0, 0,\r\n            this.img.width,\r\n            this.img.height,\r\n            -this.width / 2,\r\n            -this.height / 2,\r\n            this.width, this.height\r\n        );\r\n        if (this.outlineWidth)\r\n            c.stroke(this.getCachedPath());\r\n\r\n        c.restore();\r\n    }\r\n\r\n    // Methods\r\n\r\n    public setSrc(src: string) {\r\n        this.src = src;\r\n        this.refresh();\r\n    }\r\n\r\n    public setWidth(width: number) {\r\n        this.width = width;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    public setHeight(height: number) {\r\n        this.height = height;\r\n        this.invalidatePath();\r\n        this.refresh();\r\n    }\r\n\r\n    // Constructor\r\n\r\n    constructor(options?: ImageSpriteOptions) {\r\n        super(options);\r\n\r\n        this.src = options?.src ?? '';\r\n        this.img = new Image();\r\n        this.img.src = this.src;\r\n\r\n        this.width = options?.width ?? this.img.width;\r\n        this.height = options?.height ?? this.img.height;\r\n\r\n        this.outlineColor = options?.outlineColor ?? 'black';\r\n        this.outlineWidth = options?.outlineWidth ?? 0;\r\n        \r\n        this.draw();\r\n    }\r\n}"],"mappings":"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","names":["index_exports","__export","Arc","Circle","CustomPolygon","Engine","ImageSprite","Oval","Pen","Rectangle","RegularPolygon","Sprite","Square","Text","canvas","ctx","index_default","setAspectRatio","setScale","__toCommonJS","canvas","ctx","penCanvas","penCtx","ratio","scale","setScale","newScale","setAspectRatio","newAspectRatio","Sprite","_Sprite","Engine","options","sprite","bBox1","bBox2","b1Left","b1Top","b1Right","b1Bottom","b2Left","b2Top","b2Right","b2Bottom","xMin","yMin","xMax","yMax","width","height","ctx","img1","img2","i","deg","rad","steps","dir","x","y","dX","dY","layer","dL","Engine","_Engine","scene","loop","sprite","layer","targetIndex","s","maxFPS","frameInterval","accumulator","tick","currentTime","deltaTime","ctx","canvas","ms","resolve","conditionGetter","check","mouseX","mouseY","canvasMouseX","canvasMouseY","localX","localY","angle","rotatedX","rotatedY","key","src","audio","sound","min","max","vectors","a","b","deg","val","rad","penCanvas","e","Rectangle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","width","height","color","options","Square","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","sideLength","color","options","Oval","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radX","radY","color","options","Circle","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radius","color","options","Arc","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","radius","angle","color","options","RegularPolygon","Sprite","path","step","i","stamping","c","penCtx","ctx","cX","canvas","cY","sides","radius","color","options","CustomPolygon","Sprite","furthestVertexSize","v","size","path","vertices","i","stamping","c","penCtx","ctx","cX","canvas","cY","color","options","Pen","Sprite","sprite","penCtx","canvas","lastX","lastY","steps","x","y","dX","dY","options","Text","Sprite","metrics","ctx","width","height","path","stamping","c","penCtx","cX","canvas","cY","content","color","fontSize","fontFamily","align","baseline","options","ImageSprite","Sprite","path","stamping","c","penCtx","ctx","cX","canvas","cY","src","width","height","options","TScratch","Engine","Sprite","Rectangle","Square","Oval","Circle","Arc","RegularPolygon","CustomPolygon","Pen","Text","ImageSprite","setScale","setAspectRatio","canvas","ctx","index_default"]}