rapid-render 0.1.1 → 0.1.2-1.3

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.
@@ -1 +1 @@
1
- "use strict";const t=(t,e,r)=>{const s=t.createShader(r);if(!s)throw new Error("Unable to create webgl shader");t.shaderSource(s,e),t.compileShader(s);if(!t.getShaderParameter(s,t.COMPILE_STATUS)){const r=t.getShaderInfoLog(s);throw console.error("Shader compilation failed:",r),new Error("Unable to compile shader: "+r+e)}return s};const e=5126;class r{constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=t.BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.typedArray=new t(this.arraybuffer),t==Float32Array&&(this.uint32=new Uint32Array(this.arraybuffer))}clear(){this.usedElemNum=0}resize(t=0){if((t+=this.usedElemNum)>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.typedArray=new this.arrayType(this.arraybuffer),this.uint32&&(this.uint32=new Uint32Array(this.arraybuffer)),this.typedArray.set(e)}push(t){this.typedArray[this.usedElemNum++]=t}pushUint(t){this.uint32[this.usedElemNum++]=t}pop(t){this.usedElemNum-=t}getArray(t=0,e){return null==e?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.typedArray.length}}class s extends r{constructor(t,e,r=t.ARRAY_BUFFER){super(e),this.dirty=!0,this.webglBufferSize=0,this.gl=t,this.buffer=t.createBuffer(),this.type=r}push(t){super.push(t),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize?(t.bufferData(this.type,this.getArray(),t.STATIC_DRAW),this.webglBufferSize=this.maxElemNum):t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class i extends r{constructor(){super(Float32Array)}pushMat(){const t=this.usedElemNum-6,e=this.typedArray;this.resize(6),this.push(e[t+0]),this.push(e[t+1]),this.push(e[t+2]),this.push(e[t+3]),this.push(e[t+4]),this.push(e[t+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.push(1),this.push(0),this.push(0),this.push(1),this.push(0),this.push(0)}translate(t,e){if(t instanceof a)return this.translate(t.x,t.y);const r=this.usedElemNum-6,s=this.typedArray;s[r+4]=s[r+0]*t+s[r+2]*e+s[r+4],s[r+5]=s[r+1]*t+s[r+3]*e+s[r+5]}rotate(t){const e=this.usedElemNum-6,r=this.typedArray,s=Math.cos(t),i=Math.sin(t),n=r[e+0],h=r[e+1],a=r[e+2],o=r[e+3];r[e+0]=n*s-h*i,r[e+1]=n*i+h*s,r[e+2]=a*s-o*i,r[e+3]=a*i+o*s}scale(t,e){if(t instanceof a)return this.scale(t.x,t.y);e||(e=t);const r=this.usedElemNum-6,s=this.typedArray;s[r+0]=s[r+0]*t,s[r+1]=s[r+1]*t,s[r+2]=s[r+2]*e,s[r+3]=s[r+3]*e}apply(t,e){if(t instanceof a)return new a(...this.apply(t.x,t.y));const r=this.usedElemNum-6,s=this.typedArray;return[s[r+0]*t+s[r+2]*e+s[r+4],s[r+1]*t+s[r+3]*e+s[r+5]]}getInverse(){const t=this.usedElemNum-6,e=this.typedArray,r=e[t+0],s=e[t+1],i=e[t+2],n=e[t+3],h=e[t+4],a=e[t+5],o=r*n-s*i;return new Float32Array([n/o,-s/o,-i/o,r/o,(i*a-n*h)/o,(s*h-r*a)/o])}getTransform(){const t=this.usedElemNum-6,e=this.typedArray;return new Float32Array([e[t+0],e[t+1],e[t+2],e[t+3],e[t+4],e[t+5]])}setTransform(t){const e=this.usedElemNum-6,r=this.typedArray;r[e+0]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}}class n extends s{constructor(t,e,r,s){super(t,Uint16Array,t.ELEMENT_ARRAY_BUFFER),this.setMaxSize(e*s);for(let t=0;t<s;t++)this.addObject(t*r);this.bindBuffer(),this.bufferData()}addObject(t){}}class h{constructor(t,e,r,s){this._r=t,this._g=e,this._b=r,this._a=s,this.updateUint()}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(t,e,r,s){this.r=t,this.g=e,this.b=r,this.a=s,this.updateUint()}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),s=parseInt(t.slice(4,6),16);let i=255;return t.length>=8&&(i=parseInt(t.slice(6,8),16)),new h(e,r,s,i)}add(t){return new h(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new h(Math.max(this.r-t.r,0),Math.max(this.g-t.g,0),Math.max(this.b-t.b,0),Math.max(this.a-t.a,0))}}class a{constructor(t,e){this.x=void 0!==t?t:0,this.y=void 0!==e?e:0}scalarMult(t){return this.x*=t,this.y*=t,this}perpendicular(){const t=this.x;return this.x=-this.y,this.y=t,this}invert(){return this.x=-this.x,this.y=-this.y,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}normalize(){const t=this.length();return this.x/=t,this.y/=t,this}angle(){return this.y/this.x}static Angle(t,e){return Math.atan2(e.y-t.y,e.x-t.x)}static Add(t,e){return new a(t.x+e.x,t.y+e.y)}static Sub(t,e){return new a(t.x-e.x,t.y-e.y)}static Middle(t,e){return a.Add(t,e).scalarMult(.5)}static FormArray(t){return t.map((t=>new a(t[0],t[1])))}}class o{constructor(t){this.cache=new Map,this.render=t}async textureFromUrl(t,e=!1){let r=this.cache.get(t);if(!r){const s=await this.loadImage(t);r=u.fromImageSource(this.render,s,e),this.cache.set(t,r)}return new l(r)}async loadImage(t){return new Promise((e=>{const r=new Image;r.onload=()=>{e(r)},r.src=t}))}createText(t){return new d(this.render,t)}}class u{constructor(t,e,r){this.texture=t,this.width=e,this.height=r}static fromImageSource(t,e,r=!1){return new u(function(t,e,r){const s=t.createTexture();if(t.bindTexture(t.TEXTURE_2D,s),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),!s)throw new Error("unable to create texture");return s}(t.gl,e,r),e.width,e.height)}}class l{constructor(t){this.scale=1,this.setBaseTextur(t)}setBaseTextur(t){t&&(this.base=t,this.setClipRegion(0,0,t.width,t.height))}setClipRegion(t,e,r,s){this.base&&(this.clipX=t/this.base.width,this.clipY=e/this.base.width,this.clipW=this.clipX+r/this.base.width,this.clipH=this.clipY+s/this.base.height,this.width=r*this.scale,this.height=s*this.scale)}static fromImageSource(t,e,r=!1){return new l(u.fromImageSource(t,e,r))}static fromUrl(t,e){return t.textures.textureFromUrl(e)}}class d extends l{constructor(t,e){super(),this.scale=.5,this.rapid=t,this.options=e,this.text=e.text||"",this.updateTextImage()}updateTextImage(){const t=this.createTextCanvas();this.setBaseTextur(u.fromImageSource(this.rapid,t,!0))}createTextCanvas(){const t=document.createElement("canvas"),e=t.getContext("2d");if(!e)throw new Error("Failed to get canvas context");e.font=`${this.options.fontSize||16}px ${this.options.fontFamily||"Arial"}`,e.fillStyle=this.options.color||"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";const r=this.text.split("\n");let s=0,i=0;for(const t of r){const r=e.measureText(t);s=Math.max(s,r.width),i+=this.options.fontSize||16}t.width=2*s,t.height=2*i,e.scale(2,2),e.font=`${this.options.fontSize||16}px ${this.options.fontFamily||"Arial"}`,e.fillStyle=this.options.color||"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";let n=0;for(const t of r)e.fillText(t,0,n),n+=this.options.fontSize||16;return t}setText(t){this.text!=t&&(this.text=t,this.updateTextImage())}}class c{constructor(e,r,s){this.attributeLoc={},this.uniformLoc={};const i=function(t,e){if(t.includes("%TEXTURE_NUM%")&&(t=t.replace("%TEXTURE_NUM%",e.toString())),t.includes("%GET_COLOR%")){let r="";for(let t=0;t<e;t++)r+=0==t?`if(vTextureId == ${t}.0)`:t==e-1?"else":`else if(vTextureId == ${t}.0)`,r+=`{color = texture2D(uTextures[${t}], vRegion);}`;t=t.replace("%GET_COLOR%",r)}return t}(s,e.maxTextureUnits);this.program=((e,r,s)=>{var i=e.createProgram(),n=t(e,r,35633),h=t(e,s,35632);if(!i)throw new Error("Unable to create program shader");return e.attachShader(i,n),e.attachShader(i,h),e.linkProgram(i),i})(e.gl,r,i),this.gl=e.gl,this.parseShader(r),this.parseShader(i)}setUniforms(t,e){var r;const s=this.gl;for(const i in t){const n=t[i],h=this.getUniform(i);if(n instanceof l&&(null===(r=n.base)||void 0===r?void 0:r.texture))s.activeTexture(s.TEXTURE0+e),s.bindTexture(s.TEXTURE_2D,n.base.texture),s.uniform1i(h,e),e+=1;else if("number"==typeof n)s.uniform1f(h,n);else if(Array.isArray(n))switch(n.length){case 1:Number.isInteger(n[0])?s.uniform1i(h,n[0]):s.uniform1f(h,n[0]);break;case 2:Number.isInteger(n[0])?s.uniform2iv(h,n):s.uniform2fv(h,n);break;case 3:Number.isInteger(n[0])?s.uniform3iv(h,n):s.uniform3fv(h,n);break;case 4:Number.isInteger(n[0])?s.uniform4iv(h,n):s.uniform4fv(h,n);break;case 9:s.uniformMatrix3fv(h,!1,n);break;case 16:s.uniformMatrix4fv(h,!1,n);break;default:console.error(`Unsupported uniform array length for ${i}:`,n.length)}else"boolean"==typeof n?s.uniform1i(h,n?1:0):console.error(`Unsupported uniform type for ${i}:`,typeof n)}}getUniform(t){return this.uniformLoc[t]}use(){this.gl.useProgram(this.program)}parseShader(t){const e=this.gl,r=t.match(/attribute\s+\w+\s+(\w+)/g);if(r)for(const t of r){const r=t.split(" ")[2],s=e.getAttribLocation(this.program,r);-1!=s&&(this.attributeLoc[r]=s)}const s=t.match(/uniform\s+\w+\s+(\w+)/g);if(s)for(const t of s){const r=t.split(" ")[2];this.uniformLoc[r]=e.getUniformLocation(this.program,r)}}setAttribute(t){const e=this.attributeLoc[t.name];if(void 0!==e){const r=this.gl;r.vertexAttribPointer(e,t.size,t.type,t.normalized||!1,t.stride,t.offset||0),r.enableVertexAttribArray(e)}}}class p{constructor(t,e){this.usedTextures=[],this.needBind=new Set,this.attribute=e,this.rapid=t,this.gl=t.gl,this.webglArrayBuffer=new s(t.gl,Float32Array,t.gl.ARRAY_BUFFER),this.TEXTURE_UNITS_ARRAY=Array.from({length:t.maxTextureUnits},((t,e)=>e))}addVertex(t,e,...r){const[s,i]=this.rapid.transformPoint(t,e);this.webglArrayBuffer.push(s),this.webglArrayBuffer.push(i)}useTexture(t){let e=this.usedTextures.indexOf(t);return-1===e&&(this.usedTextures.length>=this.rapid.maxTextureUnits&&this.render(),this.usedTextures.push(t),e=this.usedTextures.length-1,this.needBind.add(e)),e}enterRegion(t){this.currentShader=null!=t?t:this.defaultShader,this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer();for(const t of this.attribute)this.currentShader.setAttribute(t);this.gl.uniformMatrix4fv(this.currentShader.uniformLoc.uProjectionMatrix,!1,this.rapid.projection)}exitRegion(){}initDefaultShader(t,e){this.webglArrayBuffer.bindBuffer(),this.defaultShader=new c(this.rapid,t,e)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){this.webglArrayBuffer.bufferData();const t=this.gl;for(const e of this.needBind)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this.usedTextures[e]);this.needBind.clear()}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures=[]}}class f extends p{constructor(t){super(t,x),this.vertex=0,this.drawType=t.gl.TRIANGLE_FAN,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec4 aColor;\r\nvarying vec4 vColor;\r\nuniform mat4 uProjectionMatrix;\r\nuniform vec4 uColor;\r\n\r\nvoid main(void) {\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n vColor = aColor;\r\n}\r\n","precision mediump float;\r\n\r\nvarying vec4 vColor;\r\nvoid main(void) {\r\n gl_FragColor = vColor;//vColor;\r\n}\r\n")}startRender(){this.vertex=0,this.webglArrayBuffer.clear()}addVertex(t,e,r){this.webglArrayBuffer.resize(3),super.addVertex(t,e),this.webglArrayBuffer.pushUint(r),this.vertex+=1}drawCircle(t,e,r,s){const i=2*Math.PI/30;this.startRender(),this.addVertex(t,e,s);for(let n=0;n<=30;n++){const h=n*i,a=t+r*Math.cos(h),o=e+r*Math.sin(h);this.addVertex(a,o,s)}this.executeRender()}executeRender(){super.executeRender();this.gl.drawArrays(this.drawType,0,this.vertex),this.drawType=this.rapid.gl.TRIANGLE_FAN,this.vertex=0}}const x=[{name:"aPosition",size:2,type:e,stride:12},{name:"aColor",size:4,type:5121,stride:12,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class g extends n{constructor(t,e){super(t,6,4,e)}addObject(t){super.addObject(),this.push(t),this.push(t+3),this.push(t+2),this.push(t),this.push(t+1),this.push(t+2)}}class m extends p{constructor(t){const e=t.gl;super(t,y),this.batchSprite=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec2 aRegion;\r\nattribute float aTextureId;\r\nattribute vec4 aColor;\r\n\r\nuniform mat4 uProjectionMatrix;\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vRegion = aRegion;\r\n vTextureId = aTextureId;\r\n vColor = aColor;\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n}","precision mediump float;\r\nuniform sampler2D uTextures[%TEXTURE_NUM%];\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vec4 color;\r\n %GET_COLOR%\r\n\r\n gl_FragColor = color*vColor;\r\n}"),this.MAX_BATCH=Math.floor(16384),this.indexBuffer=new g(e,this.MAX_BATCH)}addVertex(t,e,r,s,i,n){super.addVertex(t,e),this.webglArrayBuffer.push(r),this.webglArrayBuffer.push(s),this.webglArrayBuffer.push(i),this.webglArrayBuffer.pushUint(n)}renderSprite(t,e,r,s,i,n,h,a,o,u,l){var d;l&&(null===(d=this.currentShader)||void 0===d||d.setUniforms(l,1)),this.batchSprite>=this.MAX_BATCH&&this.render(),this.batchSprite++,this.webglArrayBuffer.resize(24);const c=this.useTexture(t),p=a+e,f=o+r,x=s+n,g=i+h;this.addVertex(a,o,s,i,c,u),this.addVertex(p,o,x,i,c,u),this.addVertex(p,f,x,g,c,u),this.addVertex(a,f,s,g,c,u)}executeRender(){super.executeRender();const t=this.gl;t.drawElements(t.TRIANGLES,6*this.batchSprite,t.UNSIGNED_SHORT,0)}enterRegion(t){super.enterRegion(t),this.indexBuffer.bindBuffer(),this.gl.uniform1iv(this.currentShader.uniformLoc.uTextures,this.TEXTURE_UNITS_ARRAY)}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0}}const y=[{name:"aPosition",size:2,type:e,stride:24},{name:"aRegion",size:2,type:e,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:e,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:5121,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];var T,E;exports.JoinTyps=void 0,(T=exports.JoinTyps||(exports.JoinTyps={}))[T.BEVEL=0]="BEVEL",T[T.ROUND=1]="ROUND",T[T.MITER=2]="MITER",exports.CapTyps=void 0,(E=exports.CapTyps||(exports.CapTyps={}))[E.BUTT=0]="BUTT",E[E.ROUND=1]="ROUND",E[E.SQUARE=2]="SQUARE";const b=1e-4,A=(t,e,r,s)=>{s.push(t),s.push(a.Add(t,r)),s.push(a.Add(e,r)),s.push(e),s.push(a.Add(e,r)),s.push(t)},R=(t,e,r,s,i)=>{const n=a.Sub(t,e).length();let h=Math.atan2(r.y-t.y,r.x-t.x),o=Math.atan2(e.y-t.y,e.x-t.x);const u=h;o>h?o-h>=Math.PI-b&&(o-=2*Math.PI):h-o>=Math.PI-b&&(h-=2*Math.PI);let l=o-h;if(Math.abs(l)>=Math.PI-b&&Math.abs(l)<=Math.PI+b){const e=a.Sub(t,s);0===e.x?e.y>0&&(l=-l):e.x>=-1e-4&&(l=-l)}const d=(Math.abs(l*n)/7|0)+1,c=l/d;for(let e=0;e<d;e++)i.push(new a(t.x,t.y)),i.push(new a(t.x+n*Math.cos(u+c*e),t.y+n*Math.sin(u+c*e))),i.push(new a(t.x+n*Math.cos(u+c*(1+e)),t.y+n*Math.sin(u+c*(1+e))))},S=(t,e,r,s,i,n,h)=>{const o=a.Sub(e,t).perpendicular(),u=a.Sub(r,e).perpendicular();((t,e,r)=>(e.x-t.x)*(r.y-t.y)-(r.x-t.x)*(e.y-t.y))(t,e,r)>0&&(o.invert(),u.invert()),o.normalize().scalarMult(i),u.normalize().scalarMult(i);const l=((t,e,r,s)=>{const i=e.y-t.y,n=t.x-e.x,h=s.y-r.y,o=r.x-s.x,u=i*o-h*n;if(u>-1e-4&&u<b)return null;{const e=i*t.x+n*t.y,s=h*r.x+o*r.y;return new a((o*e-n*s)/u,(i*s-h*e)/u)}})(a.Add(o,t),a.Add(o,e),a.Add(u,r),a.Add(u,e));let d=null,c=Number.MAX_VALUE;l&&(d=a.Sub(l,e),c=d.length());const p=c/i|0,f=a.Sub(t,e).length(),x=a.Sub(e,r).length();if(c>f||c>x)s.push(a.Add(t,o)),s.push(a.Sub(t,o)),s.push(a.Add(e,o)),s.push(a.Sub(t,o)),s.push(a.Add(e,o)),s.push(a.Sub(e,o)),n===exports.JoinTyps.ROUND?R(e,a.Add(e,o),a.Add(e,u),r,s):n===exports.JoinTyps.BEVEL||n===exports.JoinTyps.MITER&&p>=h?(s.push(e),s.push(a.Add(e,o)),s.push(a.Add(e,u))):n===exports.JoinTyps.MITER&&p<h&&l&&(s.push(a.Add(e,o)),s.push(e),s.push(l),s.push(a.Add(e,u)),s.push(e),s.push(l)),s.push(a.Add(r,u)),s.push(a.Sub(e,u)),s.push(a.Add(e,u)),s.push(a.Add(r,u)),s.push(a.Sub(e,u)),s.push(a.Sub(r,u));else{if(s.push(a.Add(t,o)),s.push(a.Sub(t,o)),s.push(a.Sub(e,d)),s.push(a.Add(t,o)),s.push(a.Sub(e,d)),s.push(a.Add(e,o)),n===exports.JoinTyps.ROUND){const t=a.Add(e,o),r=a.Add(e,u),i=a.Sub(e,d),n=e;s.push(t),s.push(n),s.push(i),R(n,t,r,i,s),s.push(n),s.push(r),s.push(i)}else(n===exports.JoinTyps.BEVEL||n===exports.JoinTyps.MITER&&p>=h)&&(s.push(a.Add(e,o)),s.push(a.Add(e,u)),s.push(a.Sub(e,d))),n===exports.JoinTyps.MITER&&p<h&&(s.push(l),s.push(a.Add(e,o)),s.push(a.Add(e,u)));s.push(a.Add(r,u)),s.push(a.Sub(e,d)),s.push(a.Add(e,u)),s.push(a.Add(r,u)),s.push(a.Sub(e,d)),s.push(a.Sub(r,u))}};exports.BaseTexture=u,exports.Color=h,exports.DynamicArrayBuffer=r,exports.GLShader=c,exports.MatrixStack=i,exports.Rapid=class{constructor(t){this.projectionDirty=!0,this.matrixStack=new i,this.textures=new o(this),this.devicePixelRatio=window.devicePixelRatio||1,this.defaultColor=new h(255,255,255,255),this.defaultColorBlack=new h(0,0,0,255),this.regions=new Map;const e=(t=>{const e=t.getContext("webgl2")||t.getContext("webgl");if(!e)throw new Error("TODO");return e})(t.canvas);this.gl=e,this.canvas=t.canvas,this.maxTextureUnits=e.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.width=t.width||this.canvas.width,this.height=t.width||this.canvas.height,this.backgroundColor=t.backgroundColor||new h(255,255,255,255),this.registerBuildInRegion(),this.initWebgl(e)}initWebgl(t){this.resize(this.width,this.height),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}registerBuildInRegion(){this.registerRegion("sprite",m),this.registerRegion("graphic",f)}registerRegion(t,e){this.regions.set(t,new e(this))}setRegion(t,e){if(t!=this.currentRegionName||e&&e!==this.currentRegion.currentShader){const r=this.regions.get(t);this.currentRegion&&(this.currentRegion.render(),this.currentRegion.exitRegion()),this.currentRegion=r,this.currentRegionName=t,r.enterRegion(e)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}startRender(t=!0){t&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0}endRender(){var t;null===(t=this.currentRegion)||void 0===t||t.render(),this.projectionDirty=!1}renderSprite(t,e=0,r=0,s){if(t.base){if(s instanceof h)return this.renderSprite(t,e,r,{color:s});this.setRegion("sprite",null==s?void 0:s.shader),this.currentRegion.renderSprite(t.base.texture,t.width,t.height,t.clipX,t.clipY,t.clipW,t.clipH,e,r,((null==s?void 0:s.color)||this.defaultColor).uint32,null==s?void 0:s.uniforms)}}renderLine(t=0,e=0,r){const s=((t,e)=>{if(t.length<2)return[];let r=e.cap||exports.CapTyps.BUTT,s=e.join||exports.JoinTyps.BEVEL,i=(e.width||1)/2,n=e.miterLimit||10,h=[],o=[];if(2===t.length)s=exports.JoinTyps.BEVEL,S(t[0],a.Middle(t[0],t[1]),t[1],h,i,s,n);else{for(let e=0;e<t.length-1;e++)0===e?o.push(t[0]):e===t.length-2?o.push(t[t.length-1]):o.push(a.Middle(t[e],t[e+1]));for(let e=1;e<o.length;e++)S(o[e-1],t[e],o[e],h,i,s,n)}if(r===exports.CapTyps.ROUND){let e=h[0],r=h[1],s=t[1],i=h[h.length-1],n=h[h.length-3],a=t[t.length-2];R(t[0],e,r,s,h),R(t[t.length-1],i,n,a,h)}else if(r===exports.CapTyps.SQUARE){let e=h[h.length-1],r=h[h.length-3];A(h[0],h[1],a.Sub(t[0],t[1]).normalize().scalarMult(a.Sub(t[0],h[0]).length()),h),A(e,r,a.Sub(t[t.length-1],t[t.length-2]).normalize().scalarMult(a.Sub(r,t[t.length-1]).length()),h)}return h})(r.points,r);this.renderGraphic(t,e,{color:r.color,drawType:this.gl.TRIANGLES,points:s})}renderGraphic(t=0,e=0,r){if(r instanceof Array)return this.renderGraphic(t,e,{points:r});this.startGraphicDraw(),r.drawType&&(this.currentRegion.drawType=r.drawType),r.points.forEach((s=>{this.addGraphicVertex(s.x+t,s.y+e,r.color||this.defaultColorBlack)})),this.endGraphicDraw()}startGraphicDraw(t){this.setRegion("graphic",t),this.currentRegion.startRender()}addGraphicVertex(t,e,r){if(t instanceof a)return this.addGraphicVertex(t.x,t.y,e);this.currentRegion.addVertex(t,e,r.uint32)}endGraphicDraw(){this.currentRegion.render()}resize(t,e){this.width=t,this.height=e;const r=t*this.devicePixelRatio,s=e*this.devicePixelRatio;this.canvas.width=r,this.canvas.height=s,this.gl.viewport(0,0,r,s),this.projection=this.createOrthMatrix(0,t,e,0),this.projectionDirty=!0}clear(){const t=this.gl,e=this.backgroundColor;t.clearColor(e.r,e.g,e.b,e.a),t.clear(t.COLOR_BUFFER_BIT)}createOrthMatrix(t,e,r,s){return new Float32Array([2/(e-t),0,0,0,0,2/(s-r),0,0,0,0,-1,0,-(e+t)/(e-t),-(s+r)/(s-r),0,1])}transformPoint(t,e){return this.matrixStack.apply(t,e)}},exports.SCALEFACTOR=2,exports.Text=d,exports.Texture=l,exports.TextureCache=o,exports.Vec2=a,exports.WebglBufferArray=s,exports.WebglElementBufferArray=n,exports.graphicAttributes=x,exports.spriteAttributes=y;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var t=(t=>(t.KEEP="keep",t.KEEP_H="keep_h",t.KEEP_W="keep_w",t.IGNORE="ignore",t.EXPAND="expand",t))(t||{}),e=(t=>(t.STRETCH="stretch",t.REPEAT="repeat",t))(e||{}),i=(t=>(t.REPEAT="repeat",t.CLAMP="clamp",t.MIRROR="mirror",t))(i||{}),s=(t=>(t.Include="normal",t.Exclude="inverse",t))(s||{}),r=(t=>(t.SQUARE="square",t.ISOMETRIC="isometric",t))(r||{}),n=(t=>(t.SPRITE="sprite",t.GRAPHIC="graphic",t))(n||{}),a=(t=>(t.Additive="additive",t.Subtractive="subtractive",t.Mix="mix",t))(a||{}),o=(t=>(t.POINT="point",t.CIRCLE="circle",t.RECT="rect",t))(o||{});var h=(t=>(t[t.Float32=0]="Float32",t[t.Uint32=1]="Uint32",t[t.Uint16=2]="Uint16",t))(h||{});class u{constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=this.getArrayType(t).BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.updateTypedArray()}getArrayType(t){switch(t){case 0:return Float32Array;case 1:return Uint32Array;case 2:return Uint16Array}}updateTypedArray(){switch(this.uint32=new Uint32Array(this.arraybuffer),this.float32=new Float32Array(this.arraybuffer),this.uint16=new Uint16Array(this.arraybuffer),this.arrayType){case 0:this.typedArray=this.float32;break;case 1:this.typedArray=this.uint32;break;case 2:this.typedArray=this.uint16}}clear(){this.usedElemNum=0}resize(t=0){if((t+=this.usedElemNum)>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.updateTypedArray(),this.typedArray.set(e)}pushUint32(t){this.uint32[this.usedElemNum++]=t}pushFloat32(t){this.float32[this.usedElemNum++]=t}pushUint16(t){this.uint16[this.usedElemNum++]=t}pop(t){this.usedElemNum-=t}getArray(t=0,e){return null==e?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.usedElemNum}}class l extends u{constructor(t,e,i=t.ARRAY_BUFFER,s=t.STATIC_DRAW){super(e),this.dirty=!0,this.webglBufferSize=0,this.gl=t,this.buffer=t.createBuffer(),this.type=i,this.usage=s}pushFloat32(t){super.pushFloat32(t),this.dirty=!0}pushUint32(t){super.pushUint32(t),this.dirty=!0}pushUint16(t){super.pushUint16(t),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize?(t.bufferData(this.type,this.getArray(),this.usage),this.webglBufferSize=this.maxElemNum):t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class c extends u{constructor(){super(0)}pushMat(){const t=this.usedElemNum-6,e=this.typedArray;this.resize(6),this.pushFloat32(e[t+0]),this.pushFloat32(e[t+1]),this.pushFloat32(e[t+2]),this.pushFloat32(e[t+3]),this.pushFloat32(e[t+4]),this.pushFloat32(e[t+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.pushFloat32(1),this.pushFloat32(0),this.pushFloat32(0),this.pushFloat32(1),this.pushFloat32(0),this.pushFloat32(0)}translate(t,e){if("number"!=typeof t)return this.translate(t.x,t.y);const i=this.usedElemNum-6,s=this.typedArray;s[i+4]=s[i+0]*t+s[i+2]*e+s[i+4],s[i+5]=s[i+1]*t+s[i+3]*e+s[i+5]}rotate(t){const e=this.usedElemNum-6,i=this.typedArray,s=Math.cos(t),r=Math.sin(t),n=i[e+0],a=i[e+1],o=i[e+2],h=i[e+3];i[e+0]=n*s-a*r,i[e+1]=n*r+a*s,i[e+2]=o*s-h*r,i[e+3]=o*r+h*s}scale(t,e){if("number"!=typeof t)return this.scale(t.x,t.y);e||(e=t);const i=this.usedElemNum-6,s=this.typedArray;s[i+0]=s[i+0]*t,s[i+1]=s[i+1]*t,s[i+2]=s[i+2]*e,s[i+3]=s[i+3]*e}apply(t,e){if("number"!=typeof t)return new g(...this.apply(t.x,t.y));const i=this.usedElemNum-6,s=this.typedArray;return[s[i+0]*t+s[i+2]*e+s[i+4],s[i+1]*t+s[i+3]*e+s[i+5]]}getInverse(){const t=this.usedElemNum-6,e=this.typedArray,i=e[t+0],s=e[t+1],r=e[t+2],n=e[t+3],a=e[t+4],o=e[t+5],h=i*n-s*r;return new Float32Array([n/h,-s/h,-r/h,i/h,(r*o-n*a)/h,(s*a-i*o)/h])}getTransform(){const t=this.usedElemNum-6,e=this.typedArray;return new Float32Array([e[t+0],e[t+1],e[t+2],e[t+3],e[t+4],e[t+5]])}setTransform(t){const e=this.usedElemNum-6,i=this.typedArray;i[e+0]=t[0],i[e+1]=t[1],i[e+2]=t[2],i[e+3]=t[3],i[e+4]=t[4],i[e+5]=t[5]}getGlobalPosition(){const t=this.usedElemNum-6,e=this.typedArray;return new g(e[t+4],e[t+5])}setGlobalPosition(t,e){if("number"!=typeof t)return void this.setGlobalPosition(t.x,t.y);const i=this.usedElemNum-6,s=this.typedArray;s[i+4]=t,s[i+5]=e}getGlobalRotation(){const t=this.usedElemNum-6,e=this.typedArray;return Math.atan2(e[t+1],e[t+0])}setGlobalRotation(t){const e=this.usedElemNum-6,i=this.typedArray,s=this.getGlobalScale(),r=Math.cos(t),n=Math.sin(t);i[e+0]=r*s.x,i[e+1]=n*s.x,i[e+2]=-n*s.y,i[e+3]=r*s.y}getGlobalScale(){const t=this.usedElemNum-6,e=this.typedArray,i=Math.sqrt(e[t+0]*e[t+0]+e[t+1]*e[t+1]),s=Math.sqrt(e[t+2]*e[t+2]+e[t+3]*e[t+3]);return new g(i,s)}setGlobalScale(t,e){if("number"!=typeof t)return void this.setGlobalScale(t.x,t.y);const i=this.getGlobalRotation(),s=Math.cos(i),r=Math.sin(i),n=this.usedElemNum-6,a=this.typedArray;a[n+0]=s*t,a[n+1]=r*t,a[n+2]=-r*e,a[n+3]=s*e}globalToLocal(t){const e=this.getInverse();return new g(e[0]*t.x+e[2]*t.y+e[4],e[1]*t.x+e[3]*t.y+e[5])}localToGlobal(t){return this.apply(t)}toCSSTransform(){const t=this.usedElemNum-6,e=this.typedArray;return`matrix(${e[t+0]}, ${e[t+1]}, ${e[t+2]}, ${e[t+3]}, ${e[t+4]}, ${e[t+5]})`}identity(){const t=this.usedElemNum-6,e=this.typedArray;e[t+0]=1,e[t+1]=0,e[t+2]=0,e[t+3]=1,e[t+4]=0,e[t+5]=0}applyTransform(t,e=0,i=0){(t.saveTransform??1)&&this.pushMat(),t.afterSave&&t.afterSave();const s=t.x||0,r=t.y||0;(s||r)&&this.translate(s,r),t.position&&this.translate(t.position),t.rotation&&this.rotate(t.rotation),t.scale&&this.scale(t.scale);let n=t.offsetX||0,a=t.offsetY||0;t.offset&&(n+=t.offset.x,a+=t.offset.y);const o=t.origin;return o&&("number"==typeof o?(n-=o*e,a-=o*i):(n-=o.x*e,a-=o.y*i)),{offsetX:n,offsetY:a}}applyTransformAfter(t){t.beforRestore&&t.beforRestore(),(t.restoreTransform??1)&&this.popMat()}}class d extends l{constructor(t,e,i,s){super(t,2,t.ELEMENT_ARRAY_BUFFER,t.STATIC_DRAW),this.setMaxSize(e*s);for(let r=0;r<s;r++)this.addObject(r*i);this.bindBuffer(),this.bufferData()}addObject(t){}}const p=class t{constructor(t,e,i,s=255){this._r=t,this._g=e,this._b=i,this._a=s,this.updateUint()}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(t,e,i,s){this.r=t,this.g=e,this.b=i,this.a=s,this.updateUint()}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}clone(){return new t(this._r,this._g,this._b,this._a)}toHexString(t=!0){const e=this.r.toString(16).padStart(2,"0"),i=this.g.toString(16).padStart(2,"0"),s=this.b.toString(16).padStart(2,"0"),r=this.a.toString(16).padStart(2,"0");return`#${e}${i}${s}${t?r:""}`}equal(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static fromHex(e){e.startsWith("#")&&(e=e.slice(1));const i=parseInt(e.slice(0,2),16),s=parseInt(e.slice(2,4),16),r=parseInt(e.slice(4,6),16);let n=255;return e.length>=8&&(n=parseInt(e.slice(6,8),16)),new t(i,s,r,n)}add(e){return new t(Math.min(this.r+e.r,255),Math.min(this.g+e.g,255),Math.min(this.b+e.b,255),Math.min(this.a+e.a,255))}subtract(e){return new t(Math.max(0,this.r-e.r),Math.max(0,this.g-e.g),Math.max(0,this.b-e.b),Math.max(0,this.a-e.a))}divide(e){return e instanceof t?new t(this.r/e.r,this.g/e.g,this.b/e.b,this.a/e.a):new t(this.r/e,this.g/e,this.b/e,this.a/e)}multiply(e){return e instanceof t?new t(this.r*e.r,this.g*e.g,this.b*e.b,this.a*e.a):new t(this.r*e,this.g*e,this.b*e,this.a*e)}clamp(){this.r=Math.max(0,Math.min(255,this.r)),this.g=Math.max(0,Math.min(255,this.g)),this.b=Math.max(0,Math.min(255,this.b)),this.a=Math.max(0,Math.min(255,this.a))}};p.Red=new p(255,0,0,255),p.Green=new p(0,255,0,255),p.Blue=new p(0,0,255,255),p.Yellow=new p(255,255,0,255),p.Purple=new p(128,0,128,255),p.Orange=new p(255,165,0,255),p.Pink=new p(255,192,203,255),p.Gray=new p(128,128,128,255),p.Brown=new p(139,69,19,255),p.Cyan=new p(0,255,255,255),p.Magenta=new p(255,0,255,255),p.Lime=new p(192,255,0,255),p.White=new p(255,255,255,255),p.Black=new p(0,0,0,255),p.TRANSPARENT=new p(0,0,0,0);let f=p;const m=class t{constructor(t,e){this.x=void 0!==t?t:0,this.y=void 0!==e?e:0}set(t,e){return Array.isArray(t)?(this.x=t[0],this.y=t[1]):e?(this.x=t,this.y=e):(this.x=t,this.y=t),this}add(e){return new t(this.x+e.x,this.y+e.y)}subtract(e){return new t(this.x-e.x,this.y-e.y)}multiply(e){return e instanceof t?new t(this.x*e.x,this.y*e.y):new t(this.x*e,this.y*e)}divide(e){return e instanceof t?new t(this.x/e.x,this.y/e.y):new t(this.x/e,this.y/e)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}distanceTo(t){const e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)}clone(){return new t(this.x,this.y)}copy(t){this.x=t.x,this.y=t.y}equal(t){return t.x==this.x&&t.y==this.y}perpendicular(){const t=this.x;return this.x=-this.y,this.y=t,this}invert(){return this.x=-this.x,this.y=-this.y,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}normalize(){const t=this.length();return this.x=this.x/t||0,this.y=this.y/t||0,this}angle(){return Math.atan2(this.y,this.x)}middle(e){return new t((this.x+e.x)/2,(this.y+e.y)/2)}abs(){return new t(Math.abs(this.x),Math.abs(this.y))}floor(){return new t(Math.floor(this.x),Math.floor(this.y))}ceil(){return new t(Math.ceil(this.x),Math.ceil(this.y))}snap(e){return new t(Math.round(this.x/e)*e,Math.round(this.y/e)*e)}stringify(){return`Vec2(${this.x}, ${this.y})`}static FromArray(e){return e.map((e=>new t(e[0],e[1])))}static fromAngle(e){return new t(Math.cos(e),Math.sin(e))}angleBetween(t){const e=this.dot(t),i=this.length()*t.length(),s=Math.max(-1,Math.min(1,e/i));return Math.acos(s)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this}};m.ZERO=new m(0,0),m.ONE=new m(1,1),m.UP=new m(0,1),m.DOWN=new m(0,-1),m.LEFT=new m(-1,0),m.RIGHT=new m(1,0);let g=m;class x{static float(t,e){return Math.random()*(e-t)+t}static int(t,e){return Math.floor(Math.random()*(e-t+1))+t}static angle(){return Math.random()*Math.PI*2}static vector(t,e,i,s){return new g(x.float(t,e),x.float(i,s))}static direction(t){const e=x.angle();return new g(Math.cos(e)*t,Math.sin(e)*t)}static randomColor(t,e){return new f(x.float(t.r,e.r),x.float(t.g,e.g),x.float(t.b,e.b),x.float(t.a,e.a))}static pick(t){return t[x.int(0,t.length-1)]}static pickWeight(t){if(!t||0===t.length)return null;let e=0;for(const r of t)e+=r[1];const i=Math.random()*e;let s=0;for(const r of t)if(s+=r[1],i<=s)return r[0];return t[t.length-1][0]}static scalarOrRange(t,e){if(void 0===t)return e;if(Array.isArray(t)){if("number"==typeof t[0])return x.float(t[0],t[1]);if(t[0]instanceof g)return x.vector(t[0].x,t[1].x,t[0].y,t[1].y);if(t[0]instanceof f)return x.randomColor(t[0],t[1])}return"number"==typeof t?t:t.clone()}}class y{constructor(t){this.render=t}createLightShadowMaskPolygon(t,e,i){const s=[];t.forEach((t=>{for(let e=0;e<t.length;e++){const i=t[e],r=t[(e+1)%t.length];s.push([i,r])}})),i=i||Math.sqrt(Math.pow(this.render.width,2)+Math.pow(this.render.height,2));const r=[];return s.forEach((([t,s])=>{const n=new g(t.x-e.x,t.y-e.y),a=new g(s.x-e.x,s.y-e.y),o=s.subtract(t).perpendicular(),h=Math.abs(o.dot(n))/(o.length()*n.length())+.01,u=Math.abs(o.dot(a))/(o.length()*a.length())+.01,l=i/h,c=i/u,d=new g(n.x,n.y).normalize(),p=new g(a.x,a.y).normalize(),f=new g(t.x+d.x*l,t.y+d.y*l),m=new g(s.x+p.x*c,s.y+p.y*c);r.push([t,s,m,f])})),r}}const T=(t,e,i,s)=>{const r=[],n=s?Math.atan2(e.y,e.x):Math.atan2(-e.y,-e.x),a=Math.PI;for(let o=0;o<10;o++){const e=n+o/10*a,s=n+(o+1)/10*a,h=Math.cos(e)*i,u=Math.sin(e)*i,l=Math.cos(s)*i,c=Math.sin(s)*i;r.push(t),r.push(t.add(new g(h,u))),r.push(t.add(new g(l,c)))}return r},w=t=>{const i=t.points;if(i.length<2)return{vertices:[],uv:[]};const{normals:s,length:r}=((t,e=!1)=>{const i=[];if(t.length<2||e&&t.length<3)return{normals:i,length:0};const s=t.length;let r=0;if(e)for(let a=0;a<s;a++){const e=t[a],i=t[(a+1)%s];r+=e.distanceTo(i)}else for(let a=0;a<s-1;a++)r+=t[a].distanceTo(t[a+1]);const n=(t,e,i)=>{const s=e.subtract(t).normalize(),r=e.subtract(i).normalize(),n=r.dot(s);if(n<-.999)return{normal:s.perpendicular(),miters:1};{let t=r.add(s).normalize();s.cross(r)<0&&(t=t.multiply(-1));let e=1/Math.sqrt((1-n)/2);return{normal:t,miters:Math.min(e,4)}}};if(e){for(let e=0;e<s-1;e++){const r=0===e?t[s-2]:t[e-1],a=t[e],o=t[e+1];i.push(n(r,a,o))}i.push(i[0])}else for(let a=0;a<s;a++)if(0===a){const e=t[1].subtract(t[0]).normalize();i.push({normal:e.perpendicular(),miters:1})}else if(a===s-1){const e=t[a].subtract(t[a-1]).normalize();i.push({normal:e.perpendicular(),miters:1})}else i.push(n(t[a-1],t[a],t[a+1]));return{normals:i,length:r}})(i,t.closed),n=(t.width||1)/2,a=[],o=[],h=t.roundCap||!1,u=t.textureMode||e.STRETCH;let l=0;const c=t.texture?.width||1;for(let d=0;d<i.length-1;d++){const t=i[d],h=s[d].normal,p=s[d].miters,f=t.add(h.multiply(p*n)),m=t.subtract(h.multiply(p*n)),x=i[d+1],y=s[d+1].normal,T=s[d+1].miters,w=x.add(y.multiply(T*n)),b=x.subtract(y.multiply(T*n)),E=t.distanceTo(x);let R=0,v=0;u===e.STRETCH?(R=l/r,v=(l+E)/r):(R=l/c,v=R+E/c);const S=new g(R,0),A=new g(R,1),M=new g(v,0),C=new g(v,1);a.push(f),o.push(S),a.push(m),o.push(A),a.push(w),o.push(M),a.push(w),o.push(M),a.push(b),o.push(C),a.push(m),o.push(A),l+=E}if(h&&!t.closed){const t=i[0],e=s[0].normal,r=T(t,e,n,!0);a.push(...r);const o=i[i.length-1],h=s[i.length-1].normal,u=T(o,h,n,!1);a.push(...u)}return{vertices:a,uv:o}},b="precision mediump float;varying vec2 vRegion;varying vec4 vColor;uniform sampler2D uTexture;uniform int uUseTexture;void main(void){vec4 color;if(uUseTexture>0){color=texture2D(uTexture,vRegion)*vColor;}else{color=vColor;}gl_FragColor=color;}",E="precision mediump float;attribute vec2 aPosition;attribute vec4 aColor;attribute vec2 aRegion;varying vec4 vColor;uniform mat4 uProjectionMatrix;uniform vec4 uColor;varying vec2 vRegion;void main(void){gl_Position=uProjectionMatrix*vec4(aPosition,0.0,1.0);vColor=aColor;vRegion=aRegion;}",R=(t,e,i)=>{const s=t.createShader(i);if(!s)throw new Error("Unable to create webgl shader");t.shaderSource(s,e),t.compileShader(s);if(!t.getShaderParameter(s,t.COMPILE_STATUS)){const i=t.getShaderInfoLog(s);throw console.error("Shader compilation failed:",i),new Error("Unable to compile shader: "+i+e)}return s};function v(t,e,i,s=!1,r=!1,n="clamp"){const a=t.createTexture();if(!a)throw new Error("unable to create texture");let o;switch(t.bindTexture(t.TEXTURE_2D,a),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,i?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,i?t.LINEAR:t.NEAREST),n){case"repeat":o=t.REPEAT;break;case"mirror":o=t.MIRRORED_REPEAT;break;default:o=t.CLAMP_TO_EDGE}return t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,o),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,o),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,r),s?t.texImage2D(t.TEXTURE_2D,0,t.RGBA,e.width,e.height,0,t.RGBA,t.UNSIGNED_BYTE,null):t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),a}const S=5126,A="precision mediump float;uniform sampler2D uTextures[%TEXTURE_NUM%];varying vec2 vRegion;varying float vTextureId;varying vec4 vColor;void main(void){vec4 color;%GET_COLOR%gl_FragColor=color*vColor;}",M="precision mediump float;attribute vec2 aPosition;attribute vec2 aRegion;attribute float aTextureId;attribute vec4 aColor;uniform mat4 uProjectionMatrix;varying vec2 vRegion;varying float vTextureId;varying vec4 vColor;void main(void){vRegion=aRegion;vTextureId=aTextureId;vColor=aColor;gl_Position=uProjectionMatrix*vec4(aPosition,0.0,1.0);}",C=[{name:"aPosition",size:2,type:S,stride:24},{name:"aRegion",size:2,type:S,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:S,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:5121,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}],_=[{name:"aPosition",size:2,type:S,stride:20},{name:"aColor",size:4,type:5121,stride:20,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0},{name:"aRegion",size:2,type:S,stride:20,offset:3*Float32Array.BYTES_PER_ELEMENT}];class P{constructor(t,e,i,s,r=0){this.attributeLoc={},this.uniformLoc={},this.textureUnitNum=0,this.attributes=[];const n=function(t,e){if(t.includes("%TEXTURE_NUM%")&&(t=t.replace("%TEXTURE_NUM%",e.toString())),t.includes("%GET_COLOR%")){let i="";for(let t=0;t<e;t++)i+=0==t?`if(vTextureId == ${t}.0)`:t==e-1?"else":`else if(vTextureId == ${t}.0)`,i+=`{color = texture2D(uTextures[${t}], vRegion);}`;t=t.replace("%GET_COLOR%",i)}return t}(i,t.maxTextureUnits-r);this.program=((t,e,i)=>{var s=t.createProgram(),r=R(t,e,35633),n=R(t,i,35632);if(!s)throw new Error("Unable to create program shader");if(t.attachShader(s,r),t.attachShader(s,n),t.linkProgram(s),!t.getProgramParameter(s,t.LINK_STATUS)){const e=t.getProgramInfoLog(s);throw new Error("Unable to link shader program: "+e)}return s})(t.gl,e,n),this.gl=t.gl,this.textureUnitNum=r,this.parseShader(e),this.parseShader(n),s&&this.setAttributes(s)}setUniforms(t,e){const i=this.gl;for(const s of t.getUnifromNames()){const r=this.getUniform(s);t.bind(i,s,r,e)}}getUniform(t){return this.uniformLoc[t]}use(){this.gl.useProgram(this.program)}parseShader(t){const e=this.gl,i=t.match(/attribute\s+\w+\s+(\w+)/g);if(i)for(const r of i){const t=r.split(" ")[2],i=e.getAttribLocation(this.program,t);-1!=i&&(this.attributeLoc[t]=i)}const s=t.match(/uniform\s+\w+\s+(\w+)/g);if(s)for(const r of s){const t=r.split(" ")[2];this.uniformLoc[t]=e.getUniformLocation(this.program,t)}}setAttribute(t){const e=this.attributeLoc[t.name];if(void 0!==e){const i=this.gl;i.vertexAttribPointer(e,t.size,t.type,t.normalized||!1,t.stride,t.offset||0),i.enableVertexAttribArray(e)}}setAttributes(t){this.attributes=t;for(const e of t)this.setAttribute(e)}updateAttributes(){this.setAttributes(this.attributes)}static createCostumShader(t,e,i,s,r=0){let a={[n.SPRITE]:A,[n.GRAPHIC]:b}[s],o={[n.SPRITE]:M,[n.GRAPHIC]:E}[s];const h={[n.SPRITE]:C,[n.GRAPHIC]:_}[s];return a=a.replace("void main(void) {",i+"\nvoid main(void) {"),o=o.replace("void main(void) {",e+"\nvoid main(void) {"),a=a.replace("// fragment","fragment(color);"),o=o.replace(/\/\/ vertex s[\s\S]*?\/\/ vertex e/,"vec2 position = aPosition;\n vertex(position, vRegion);\n gl_Position = uProjectionMatrix * vec4(position, 0.0, 1.0);"),new P(t,o,a,h,r)}}class F{constructor(t){this.usedTextures=[],this.shaders=new Map,this.isCostumShader=!1,this.freeTextureUnitNum=0,this.rapid=t,this.gl=t.gl,this.webglArrayBuffer=new l(t.gl,h.Float32,t.gl.ARRAY_BUFFER,t.gl.STREAM_DRAW),this.maxTextureUnits=t.maxTextureUnits}getTextureUnitList(){return Array.from({length:this.maxTextureUnits},((t,e)=>e))}addVertex(t,e,...i){const[s,r]=this.rapid.matrixStack.apply(t,e);this.webglArrayBuffer.pushFloat32(s),this.webglArrayBuffer.pushFloat32(r)}useTexture(t){const e=this.usedTextures.indexOf(t);return-1==e?(this.usedTextures.push(t),this.freeTextureUnitNum=this.maxTextureUnits-this.usedTextures.length,[this.usedTextures.length-1,!0]):[e,!1]}enterRegion(t){this.currentShader=t??this.getShader("default"),this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer(),this.currentShader.updateAttributes(),this.updateProjection(),this.isCostumShader=Boolean(t)}updateProjection(){this.gl.uniformMatrix4fv(this.currentShader.uniformLoc.uProjectionMatrix,!1,this.rapid.projection)}isUnifromChanged(t){return!!t&&(this.costumUnifrom!=t||!!t?.isDirty)}setCurrentUniform(t){t.clearDirty(),this.costumUnifrom=t}exitRegion(){}initDefaultShader(t,e,i){this.setShader("default",t,e,i)}setShader(t,e,i,s){this.webglArrayBuffer.bindBuffer(),this.shaders.set(t,new P(this.rapid,e,i,s)),"default"===t&&(this.defaultShader=this.shaders.get(t))}getShader(t){return this.shaders.get(t)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){const t=this.gl;for(let e=0;e<this.usedTextures.length;e++)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this.usedTextures[e]);this.webglArrayBuffer.bufferData()}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures.length=0,this.isCostumShader=!1,this.freeTextureUnitNum=this.maxTextureUnits}hasPendingContent(){return!1}isShaderChanged(t){return(t||this.defaultShader)!=this.currentShader}}class U extends F{constructor(t){super(t),this.vertex=0,this.offset=g.ZERO,this.drawType=t.gl.TRIANGLE_FAN,this.setShader("default",E,b,_)}startRender(t,e,i,s){s&&this.currentShader?.setUniforms(s,this),this.offset=new g(t,e),this.vertex=0,this.webglArrayBuffer.clear(),i&&i.base&&(this.texture=this.useTexture(i.base.texture)[0])}addVertex(t,e,i,s,r){this.webglArrayBuffer.resize(3),super.addVertex(t+this.offset.x,e+this.offset.y),this.webglArrayBuffer.pushUint32(r),this.webglArrayBuffer.pushFloat32(i),this.webglArrayBuffer.pushFloat32(s),this.vertex+=1}executeRender(){super.executeRender();const t=this.gl;t.uniform1i(this.currentShader.uniformLoc.uUseTexture,void 0===this.texture?0:1),this.texture&&t.uniform1i(this.currentShader.uniformLoc.uTexture,this.texture),t.drawArrays(this.drawType,0,this.vertex),this.drawType=this.rapid.gl.TRIANGLE_FAN,this.vertex=0,this.texture=void 0}}const N=Math.floor(16384);class L extends d{constructor(t,e){super(t,6,4,e)}addObject(t){super.addObject(),this.pushUint16(t),this.pushUint16(t+1),this.pushUint16(t+2),this.pushUint16(t),this.pushUint16(t+3),this.pushUint16(t+2)}}class D extends F{constructor(t){const e=t.gl;super(t),this.batchSprite=0,this.spriteTextureUnits=[],this.spriteTextureUnitIndexOffset=0,this.setShader("default",M,A,C),this.indexBuffer=new L(e,N)}addVertex(t,e,i,s,r,n){super.addVertex(t,e),this.webglArrayBuffer.pushFloat32(i),this.webglArrayBuffer.pushFloat32(s),this.webglArrayBuffer.pushFloat32(r),this.webglArrayBuffer.pushUint32(n)}renderSprite(t,e,i,s,r,n,a,o,h,u,l,c,d,p=0){(1+p>this.freeTextureUnitNum||this.batchSprite>=N||this.isUnifromChanged(l)||this.rapid.projectionDirty)&&(this.render(),l&&this.isUnifromChanged(l)&&(this.currentShader.setUniforms(l,this),this.setCurrentUniform(l)),this.rapid.projectionDirty&&this.updateProjection()),this.batchSprite++,this.webglArrayBuffer.resize(20);const[f,m]=this.useTexture(t);m&&(this.spriteTextureUnits.push(f),this.spriteTextureUnitIndexOffset=this.spriteTextureUnits[0]);const g=f-this.spriteTextureUnitIndexOffset,x=c?n:s,y=c?s:n,T=d?a:r,w=d?r:a,b=o,E=o+e,R=h,v=h+i;this.addVertex(b,R,x,T,g,u),this.addVertex(E,R,y,T,g,u),this.addVertex(E,v,y,w,g,u),this.addVertex(b,v,x,w,g,u)}executeRender(){if(super.executeRender(),this.batchSprite<=0)return;const t=this.gl;this.spriteTextureUnits.length>0&&this.gl.uniform1iv(this.currentShader.uniformLoc.uTextures,this.spriteTextureUnits),t.drawElements(t.TRIANGLES,6*this.batchSprite,t.UNSIGNED_SHORT,0)}enterRegion(t){super.enterRegion(t),this.indexBuffer.bindBuffer()}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0,this.spriteTextureUnits.length=0}hasPendingContent(){return this.batchSprite>0}}class I{constructor(t,e){this.cache=new Map,this.render=t,this.antialias=e}async textureFromUrl(t,e=this.antialias,s=i.CLAMP){let r=this.cache.get(t);if(!r){const i=await this.loadImage(t);r=B.fromImageSource(this.render,i,e,s),r.cacheKey=t,this.cache.set(t,r)}return new k(r)}textureFromFrameBufferObject(t){return new k(t)}textureFromSource(t,e=this.antialias,s=i.CLAMP){let r=this.cache.get(t);return r||(r=B.fromImageSource(this.render,t,e,s),r.cacheKey=t,this.cache.set(t,r)),new k(r)}async loadImage(t){return new Promise((e=>{const i=new Image;i.onload=()=>{e(i)},i.src=t}))}createText(t){return new G(this.render,t)}destroy(t){const e=t instanceof k?t.base:t;e&&(e.destroy(this.render.gl),this.removeCache(e))}createFrameBufferObject(t,e,i=this.antialias){return new z(this.render,t,e,i)}removeCache(t){t.cacheKey&&this.cache.delete(t.cacheKey)}}class B{constructor(t,e,s,r=i.CLAMP){this.cacheKey=null,this.texture=t,this.width=e,this.height=s,this.wrapMode=r}static fromImageSource(t,e,s=!1,r=i.CLAMP){return new B(v(t.gl,e,s,!1,!1,r),e.width,e.height)}destroy(t){t.deleteTexture(this.texture)}}class k{constructor(t){this.scale=1,this.setBaseTexture(t)}setBaseTexture(t){t&&(this.base=t,this.setClipRegion(0,0,t.width,t.height))}setClipRegion(t,e,i,s){if(this.base)return this.clipX=t/this.base.width,this.clipY=e/this.base.height,this.clipW=this.clipX+i/this.base.width,this.clipH=this.clipY+s/this.base.height,this.width=i*this.scale,this.height=s*this.scale,this}static fromImageSource(t,e,i=!1){return new k(B.fromImageSource(t,e,i))}static fromFrameBufferObject(t){return new k(t)}createSpritesheet(t,e){if(!this.base)return[];const i=[],s=Math.floor(this.base.width/t),r=Math.floor(this.base.height/e);for(let n=0;n<r;n++)for(let r=0;r<s;r++){const s=this.clone();s.setClipRegion(r*t,n*e,t,e),i.push(s)}return i}clone(){return new k(this.base)}}const O=2.5;class G extends k{constructor(t,e){super(),this.scale=.4,this.rapid=t,this.options=e,this.text=e.text||" ",this.updateTextImage()}updateTextImage(){this.base&&this.base.destroy(this.rapid.gl);const t=this.createTextCanvas();this.setBaseTexture(B.fromImageSource(this.rapid,t,!0))}createTextCanvas(){const t=document.createElement("canvas"),e=t.getContext("2d");if(!e)throw new Error("Failed to get 2D canvas context");const i=this.options.fontSize||16,s=`${i}px ${this.options.fontFamily||"Arial"}`,r=this.text.split("\n");e.font=s;let n=0;for(const h of r){const t=e.measureText(h);n=Math.max(n,t.width)}const a=i*r.length;t.width=Math.ceil(n)*O,t.height=Math.ceil(a)*O,e.scale(O,O),e.font=s,e.fillStyle=this.options.color?this.options.color.toHexString():"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";let o=0;for(const h of r)e.fillText(h,0,o),o+=i;return t}setText(t){this.text!==t&&(this.text=t||" ",this.updateTextImage())}}class z extends B{constructor(t,e,i,s=!1){const r=t.gl,n=v(r,{width:e,height:i},s,!0,!1),a=r.createFramebuffer();if(!a)throw r.deleteTexture(n),new Error("Failed to create WebGL framebuffer");r.bindFramebuffer(r.FRAMEBUFFER,a),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,n,0);const o=r.createRenderbuffer();if(!o)throw r.deleteFramebuffer(a),r.deleteTexture(n),new Error("Failed to create depth-stencil renderbuffer");r.bindRenderbuffer(r.RENDERBUFFER,o),r.renderbufferStorage(r.RENDERBUFFER,r.STENCIL_INDEX8,e,i),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.STENCIL_ATTACHMENT,r.RENDERBUFFER,o),super(n,e,i),this.gl=r,this.framebuffer=a,this.stencilBuffer=o,r.bindTexture(r.TEXTURE_2D,null),r.bindFramebuffer(r.FRAMEBUFFER,null),r.bindRenderbuffer(r.RENDERBUFFER,null)}bind(t){const e=this.gl;e.bindTexture(e.TEXTURE_2D,null),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer),e.clearColor(t.r,t.g,t.b,t.a),e.clear(e.COLOR_BUFFER_BIT|e.STENCIL_BUFFER_BIT)}unbind(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.bindTexture(this.gl.TEXTURE_2D,null)}resize(t,e){if(this.width===t&&this.height===e)return;this.width=t,this.height=e;const i=this.gl;i.bindTexture(i.TEXTURE_2D,this.texture),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,t,e,0,i.RGBA,i.UNSIGNED_BYTE,null),i.bindTexture(i.TEXTURE_2D,null),i.bindRenderbuffer(i.RENDERBUFFER,this.stencilBuffer),i.renderbufferStorage(i.RENDERBUFFER,i.STENCIL_INDEX8,t,e),i.bindRenderbuffer(i.RENDERBUFFER,null)}destroy(t){t.deleteFramebuffer(this.framebuffer),t.deleteRenderbuffer(this.stencilBuffer),super.destroy(t)}}function j(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var X,Y={exports:{}};const W=j((X||(X=1,function(t){var e=Object.prototype.hasOwnProperty,i="~";function s(){}function r(t,e,i){this.fn=t,this.context=e,this.once=i||!1}function n(t,e,s,n,a){if("function"!=typeof s)throw new TypeError("The listener must be a function");var o=new r(s,n||t,a),h=i?i+e:e;return t._events[h]?t._events[h].fn?t._events[h]=[t._events[h],o]:t._events[h].push(o):(t._events[h]=o,t._eventsCount++),t}function a(t,e){0==--t._eventsCount?t._events=new s:delete t._events[e]}function o(){this._events=new s,this._eventsCount=0}Object.create&&(s.prototype=Object.create(null),(new s).__proto__||(i=!1)),o.prototype.eventNames=function(){var t,s,r=[];if(0===this._eventsCount)return r;for(s in t=this._events)e.call(t,s)&&r.push(i?s.slice(1):s);return Object.getOwnPropertySymbols?r.concat(Object.getOwnPropertySymbols(t)):r},o.prototype.listeners=function(t){var e=i?i+t:t,s=this._events[e];if(!s)return[];if(s.fn)return[s.fn];for(var r=0,n=s.length,a=new Array(n);r<n;r++)a[r]=s[r].fn;return a},o.prototype.listenerCount=function(t){var e=i?i+t:t,s=this._events[e];return s?s.fn?1:s.length:0},o.prototype.emit=function(t,e,s,r,n,a){var o=i?i+t:t;if(!this._events[o])return!1;var h,u,l=this._events[o],c=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),c){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,s),!0;case 4:return l.fn.call(l.context,e,s,r),!0;case 5:return l.fn.call(l.context,e,s,r,n),!0;case 6:return l.fn.call(l.context,e,s,r,n,a),!0}for(u=1,h=new Array(c-1);u<c;u++)h[u-1]=arguments[u];l.fn.apply(l.context,h)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(t,l[u].fn,void 0,!0),c){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,e);break;case 3:l[u].fn.call(l[u].context,e,s);break;case 4:l[u].fn.call(l[u].context,e,s,r);break;default:if(!h)for(d=1,h=new Array(c-1);d<c;d++)h[d-1]=arguments[d];l[u].fn.apply(l[u].context,h)}}return!0},o.prototype.on=function(t,e,i){return n(this,t,e,i,!1)},o.prototype.once=function(t,e,i){return n(this,t,e,i,!0)},o.prototype.removeListener=function(t,e,s,r){var n=i?i+t:t;if(!this._events[n])return this;if(!e)return a(this,n),this;var o=this._events[n];if(o.fn)o.fn!==e||r&&!o.once||s&&o.context!==s||a(this,n);else{for(var h=0,u=[],l=o.length;h<l;h++)(o[h].fn!==e||r&&!o[h].once||s&&o[h].context!==s)&&u.push(o[h]);u.length?this._events[n]=1===u.length?u[0]:u:a(this,n)}return this},o.prototype.removeAllListeners=function(t){var e;return t?(e=i?i+t:t,this._events[e]&&a(this,e)):(this._events=new s,this._eventsCount=0),this},o.prototype.off=o.prototype.removeListener,o.prototype.addListener=o.prototype.on,o.prefixed=i,o.EventEmitter=o,t.exports=o}(Y)),Y.exports));class H extends W{constructor(t){super(),this.totalAsset=0,this.loadedAssets=0,this.game=t,this.assets={json:{},audio:{},images:{}}}loadJson(t,e){this.totalAsset++,fetch(e).then((t=>{if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);return t.json()})).then((e=>{this.assets.json[t]=e,this.assetLoaded()})).catch((i=>this.handleError(t,e,i)))}async loadAudio(t,e){this.totalAsset++;try{const i=await this.game.audio.audioFromUrl(e);this.assets.audio[t]=i,this.assetLoaded()}catch(i){this.handleError(t,e,i),this.assetLoaded()}}async loadImage(t,e){this.totalAsset++;try{this.assets.images[t]=await this.game.render.texture.textureFromUrl(e),this.assetLoaded()}catch(i){this.handleError(t,e,i),this.assetLoaded()}}loadAssets(t){if(0===t.length)return this.emit("progress",1,0,0),void this.emit("complete",this.assets);t.forEach((t=>{switch(t.type){case"json":this.loadJson(t.name,t.url);break;case"audio":this.loadAudio(t.name,t.url);break;case"image":this.loadImage(t.name,t.url);break;default:console.warn(`Unknown asset type: ${t.type}`)}}))}assetLoaded(){this.loadedAssets++;const t=this.totalAsset>0?this.loadedAssets/this.totalAsset:1;this.emit("progress",t,this.loadedAssets,this.totalAsset),this.loadedAssets>=this.totalAsset&&this.emit("complete",this.assets)}handleError(t,e,i){this.emit("error",{name:t,url:e,error:i}),console.error(`Failed to load asset '${t}' from ${e}:`,i)}get(t,e){return this.assets[t]?.[e]}getJSON(t){return this.assets.json[t]}getAudio(t){return this.assets.audio[t]}getTexture(t){return this.assets.images[t]}}class $ extends W{constructor(t,e){super(),this.sourceNode=null,this._volume=1,this._loop=!1,this._isPlaying=!1,this.audioContext=t,this.audioBuffer=e,this.gainNode=this.audioContext.createGain(),this.gainNode.connect(this.audioContext.destination)}play(){this.audioContext&&this.audioBuffer&&this.gainNode?(this._isPlaying&&this.stop(),this.sourceNode=this.audioContext.createBufferSource(),this.sourceNode.buffer=this.audioBuffer,this.sourceNode.loop=this._loop,this.sourceNode.connect(this.gainNode),this.sourceNode.onended=()=>{this._isPlaying&&(this._isPlaying=!1,this.sourceNode=null,this.emit("ended"))},this.sourceNode.start(0),this._isPlaying=!0):console.warn("Cannot play audio on a destroyed AudioPlayer.")}stop(){this.sourceNode&&this.sourceNode.stop(),this._isPlaying=!1}get volume(){return this._volume}set volume(t){this._volume=Math.max(0,Math.min(1,t)),this.gainNode&&this.audioContext&&this.gainNode.gain.setTargetAtTime(this._volume,this.audioContext.currentTime,.01)}get loop(){return this._loop}set loop(t){this._loop=t,this.sourceNode&&(this.sourceNode.loop=t)}get isPlaying(){return this._isPlaying}destroy(){this.stop(),this.gainNode&&this.gainNode.disconnect(),this.removeAllListeners(),this.audioBuffer=null,this.audioContext=null,this.gainNode=null,this.sourceNode=null}}class K{constructor(){this.cache=new Map;try{this.audioContext=new(window.AudioContext||window.webkitAudioContext)}catch(t){console.error("Web Audio API is not supported in this browser."),this.audioContext=null}}async audioFromUrl(t){if(!this.audioContext)throw new Error("AudioContext is not available. Cannot process audio.");let e=this.cache.get(t);if(!e){const s=await fetch(t);if(!s.ok)throw new Error(`Failed to fetch audio from ${t}: ${s.statusText}`);const r=await s.arrayBuffer();try{e=await this.audioContext.decodeAudioData(r)}catch(i){throw new Error(`Failed to decode audio from ${t}: ${i}`)}this.cache.set(t,e)}return new $(this.audioContext,e)}destroy(){this.cache.clear(),this.audioContext&&"closed"!==this.audioContext.state&&this.audioContext.close().catch((t=>{console.error("Error closing AudioContext:",t)})),this.audioContext=null}}class q{constructor(t){this.mousePosition=g.ZERO,this.keysDown=new Set,this.keysDownLastFrame=new Set,this.buttonsDown=new Set,this.buttonsDownLastFrame=new Set,this.rapid=t,this.canvas=t.canvas,this.attachEventListeners()}attachEventListeners(){const t=this.canvas.getBoundingClientRect();this.canvas.addEventListener("mousemove",this.handleMouseMove=e=>{this.mousePosition=this.rapid.cssToGameCoords(e.clientX-t.left,e.clientY-t.top)}),window.addEventListener("keydown",this.handleKeyDown=t=>{this.keysDown.add(t.code)}),window.addEventListener("keyup",this.handleKeyUp=t=>{this.keysDown.delete(t.code)}),this.canvas.addEventListener("mousedown",this.handleMouseDown=t=>{this.buttonsDown.add(t.button)}),this.canvas.addEventListener("mouseup",this.handleMouseUp=t=>{this.buttonsDown.delete(t.button)})}updateNextFrame(){this.keysDownLastFrame=new Set(this.keysDown),this.buttonsDownLastFrame=new Set(this.buttonsDown)}isKeyDown(t){return this.keysDown.has(t)}isKeyUp(t){return!this.keysDown.has(t)}wasKeyPressed(t){return this.keysDown.has(t)&&!this.keysDownLastFrame.has(t)}wasKeyReleased(t){return!this.keysDown.has(t)&&this.keysDownLastFrame.has(t)}isButtonDown(t){return this.buttonsDown.has(t)}isButtonUp(t){return!this.buttonsDown.has(t)}wasButtonPressed(t){return this.buttonsDown.has(t)&&!this.buttonsDownLastFrame.has(t)}wasButtonReleased(t){return!this.buttonsDown.has(t)&&this.buttonsDownLastFrame.has(t)}getMouseLocal(t){return t.transform.globalToLocal(this.mousePosition)}getAxis(t,e){let i=0;return this.isKeyDown(e)&&(i+=1),this.isKeyDown(t)&&(i-=1),i}getVector(t,e,i,s){const r=this.getAxis(t,e),n=this.getAxis(i,s);return new g(r,n).normalize()}destroy(){this.canvas.removeEventListener("mousemove",this.handleMouseMove),window.removeEventListener("keydown",this.handleKeyDown),window.removeEventListener("keyup",this.handleKeyUp),this.canvas.removeEventListener("mousedown",this.handleMouseDown),this.canvas.removeEventListener("mouseup",this.handleMouseUp),this.keysDown.clear(),this.keysDownLastFrame.clear(),this.buttonsDown.clear(),this.buttonsDownLastFrame.clear()}}class Q extends W{constructor(t,e,i,s,r){super(),this.elapsed=0,this.isRunning=!1,this.isFinished=!1,this.target=t,this.property=e,this.to=i,this.duration=s,this.easing=r}start(){const t=this.target[this.property];if("number"==typeof t)this.from=t;else{if("function"!=typeof t.clone)return console.error("Tween target property is not a 'number' or does not have a 'clone' method."),void(this.isFinished=!0);this.from=t.clone()}this.elapsed=0,this.isRunning=!0,this.isFinished=!1}update(t){if(!this.isRunning||this.isFinished)return;this.elapsed+=t;const e=Math.min(this.elapsed/this.duration,1),i=this.easing(e);let s;if("number"==typeof this.from&&"number"==typeof this.to)s=this.from+(this.to-this.from)*i;else{const t=this.from,e=this.to.subtract(t).multiply(i);s=t.add(e)}this.target[this.property]=s,e>=1&&(this.isFinished=!0,this.isRunning=!1,this.target[this.property]=this.to,this.emit("complete"))}}const V=class{};V.Linear=t=>t,V.EaseInQuad=t=>t*t,V.EaseOutQuad=t=>t*(2-t),V.EaseInOutQuad=t=>t<.5?2*t*t:(4-2*t)*t-1,V.EaseInCubic=t=>t*t*t,V.EaseOutCubic=t=>--t*t*t+1,V.EaseInOutCubic=t=>t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1,V.EaseInQuart=t=>t*t*t*t,V.EaseOutQuart=t=>1- --t*t*t*t,V.EaseInOutQuart=t=>t<.5?8*t*t*t*t:1-8*--t*t*t*t;let Z=V;class J extends W{constructor(t,e=!1){super(),this.elapsedTime=0,this.isRunning=!1,this.isFinished=!1,this.duration=t,this.repeat=e}start(){this.isRunning=!0}stop(){this.isRunning=!1}update(t){this.isRunning&&!this.isFinished&&(this.elapsedTime+=t,this.elapsedTime>=this.duration&&(this.emit("timeout"),this.repeat?this.elapsedTime-=this.duration:(this.isFinished=!0,this.isRunning=!1)))}destroy(){this.isFinished=!0,this.isRunning=!1}}class tt{constructor(t,e={}){this.parent=null,this.globalZindex=0,this.localZindex=0,this.transform=new c,this.children=[],this.transform.pushIdentity(),this.game=t,this.rapid=t.render,this.tags=e.tags??[],e.position?this.position=e.position:this.position=new g(e.x??0,e.y??0),"number"==typeof e.scale?this.scale=new g(e.scale,e.scale):e.scale?this.scale=e.scale:this.scale=new g(1,1),this.rotation=e.rotation??0}get x(){return this.position.x}get y(){return this.position.y}set x(t){this.position.x=t}set y(t){this.position.y=t}getScene(){return this.game.getMainScene()}getParentTransform(){return this.parent?this.parent.transform:this.rapid.matrixStack}update(t){this.onUpdate(t);for(const e of this.children)e.update(t)}onUpdate(t){}collectRenderables(t){this.updateTransform(),this.onRender!==tt.prototype.onRender&&t.push(this);for(const e of this.children)e.collectRenderables(t)}beforeOnRender(){const t=this.transform;this.rapid.matrixStack.setTransform(t.getTransform())}onRender(t){}updateTransform(t=!1){t&&this.parent&&this.parent.updateTransform(t);const e=this.transform,i=this.getParentTransform();e.setTransform(i.getTransform()),e.translate(this.position),e.rotate(this.rotation),e.scale(this.scale)}addChild(t){t.parent&&t.parent.removeChild(t),t.parent=this,this.children.push(t)}removeChild(t){const e=this.children.indexOf(t);e>-1&&(t.parent=null,this.children.splice(e,1))}findDescendant(t,e=!0){const i=[];for(const s of this.children){if(t(s)){if(e)return s;i.push(s)}const r=s.findDescendant(t,e);if(e){if(r)return r}else i.push(...r)}return e?null:i}findDescendantByTag(t,e=!1){return this.findDescendant((e=>0!==t.length&&t.every((t=>e.tags.includes(t)))),e)}dispose(){this.postDispose(),this.parent&&this.parent.removeChild(this)}postDispose(){this.children.forEach((t=>{t.dispose()}))}getMouseLocalPosition(){return this.game.input.getMouseLocal(this)}getMouseGlobalPosition(){return this.game.input.mousePosition}}class et{constructor(t,e){this.textures=new Map,this.width=t,this.height=e}setTile(t,e){e instanceof k&&(e={texture:e}),this.textures.set(t,e)}getTile(t){return this.textures.get(t)}}class it{constructor(t){this.rapid=t}getOffset(t){let e=(t.errorX??2)+1,i=(t.errorY??2)+1;if("number"==typeof t.error){const s=(t.error??2)+1;e=s,i=s}else t.error&&(e=t.error.x+1,i=t.error.y+1);return{errorX:e,errorY:i}}getTileData(t,e){const i=e.shape??r.SQUARE,s=t.width,n=i===r.ISOMETRIC?t.height/2:t.height,a=this.rapid.matrixStack,{errorX:o,errorY:h}=this.getOffset(e),u=new g(0,0),l=new g(this.rapid.width,0),c=new g(0,this.rapid.height),d=new g(this.rapid.width,this.rapid.height),p=a.globalToLocal(u),f=a.globalToLocal(l),m=a.globalToLocal(c),x=a.globalToLocal(d),y=Math.min(p.x,f.x,m.x,x.x),T=Math.max(p.x,f.x,m.x,x.x),w=Math.min(p.y,f.y,m.y,x.y),b=Math.max(p.y,f.y,m.y,x.y),E=new g(Math.floor(y/s)-o,Math.floor(w/n)-h),R=new g(Math.ceil(T/s)+o,Math.ceil(b/n)+h);return{startTile:E,viewportWidth:R.x-E.x,viewportHeight:R.y-E.y}}renderLayer(t,e){this.rapid.matrixStack.applyTransform(e);const i=e.tileSet,{startTile:s,viewportWidth:r,viewportHeight:n}=this.getTileData(i,e),a=[];e.ySortCallback&&a.push(...e.ySortCallback);for(let o=0;o<n;o++){const n=o+s.y;if(!(n<0||n>=t.length))for(let o=0;o<r;o++){const r=o+s.x;if(r<0||r>=t[n].length)continue;const h=t[n][r],u=i.getTile(h);if(!u)continue;const l=this.mapToLocal(new g(r,n),e),c=l.y+(u.ySortOffset??0),d=e.eachTile&&e.eachTile(h,r,n)||{};a.push({ySort:c,renderSprite:{...u,x:l.x+(u.x||0),y:l.y+(u.y||0),...d}})}}e.ySortCallback&&e.ySortCallback.length>0&&a.sort(((t,e)=>t.ySort-e.ySort));for(const o of a)o.render?o.render():o.entity?o.entity.onRender(this.rapid):o.renderSprite&&this.rapid.renderSprite(o.renderSprite);this.rapid.matrixStack.applyTransformAfter(e)}localToMap(t,e){const i=e.tileSet;if(e.shape===r.ISOMETRIC){let e=0,s=0;const r=i.height/2,n=i.width/2;let a=Math.floor(t.y/r);const o=a%2==0;let h=Math.floor(t.x/n);const u=h%2==0,l=t.x%n/n,c=t.y%r/r,d=c<l,p=c<1-l;return o||(a-=1),d&&!u&&o?a-=1:d||!u||o?p&&u&&o?(h-=2,a-=1):p||u||o||(a+=1):(a+=1,h-=2),e=h,s=a,e=Math.floor(h/2),new g(e,s)}return new g(Math.floor(t.x/i.width),Math.floor(t.y/i.height))}mapToLocal(t,e){const i=e.tileSet;if(e.shape===r.ISOMETRIC){let e=new g(t.x*i.width,t.y*i.height/2);return t.y%2!=0&&(e.x+=i.width/2),e}return new g(t.x*i.width,t.y*i.height)}}const st=class t extends tt{constructor(e,i){super(e,i),this.error=new g(t.DEFAULT_ERROR),this.data=[[]],this.ySortCallback=[],i.error?"number"==typeof i.error?this.error=new g(i.error):this.error=i.error:this.error=new g(i.errorX??t.DEFAULT_ERROR,i.errorY??t.DEFAULT_ERROR),this.tileSet=i.tileSet,this.shape=i.shape??r.SQUARE,this.eachTile=i.eachTile,this.enableYsort=i.enableYsort??!1}collectRenderables(t){this.enableYsort?this.onRender!==tt.prototype.onRender&&t.push(this):super.collectRenderables(t)}setTile(t,e,i){return e<0||e>=this.data.length||t<0||t>=this.data[e].length?(console.warn(`Tilemap.setTile: Coordinates (${t}, ${e}) are out of bounds.`),!1):(this.data[e][t]=i,!0)}getTile(t,e){if(!(e<0||e>=this.data.length||t<0||t>=this.data[e].length))return this.data[e][t]}removeTile(e,i){return this.setTile(e,i,t.EMPTY_TILE)}fill(t,e,i,s,r){const n=e+s,a=i+r;for(let o=i;o<a;o++)for(let i=e;i<n;i++)this.setTile(i,o,t)}setData(t){this.data=t}localToMap(t){this.rapid.tileMap.localToMap(t,{tileSet:this.tileSet})}mapToLocal(t){this.rapid.tileMap.mapToLocal(t,{tileSet:this.tileSet})}onRender(t){const e=[...this.ySortCallback];this.enableYsort&&this.children.forEach((t=>{e.push({ySort:t.localZindex,entity:t})})),t.renderTileMapLayer(this.data,{error:this.error,tileSet:this.tileSet,eachTile:this.eachTile,ySortCallback:e})}};st.DEFAULT_ERROR=0,st.EMPTY_TILE=-1;class rt{constructor(e){this.projectionDirty=!0,this.matrixStack=new c,this.tileMap=new it(this),this.light=new y(this),this.defaultColor=new f(255,255,255,255),this.regions=new Map,this.currentMaskType=[],this.currentTransform=[],this.currentFBO=[],this.lastTime=0;const i=(t=>{const e={stencil:!0},i=t.getContext("webgl2",e)||t.getContext("webgl",e);if(!i)throw new Error("Unable to initialize WebGL. Your browser may not support it.");return i})(e.canvas);this.gl=i,this.canvas=e.canvas,this.texture=new I(this,e.antialias??!1),this.maxTextureUnits=i.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.width=e.width||this.canvas.width,this.height=e.height||this.canvas.height,this.scaleEnable=e.scaleEnable??!1,this.scaleRadio=e.scaleRadio||t.KEEP,this.devicePixelRatio=e.devicePixelRatio??window.devicePixelRatio??1,this.backgroundColor=e.backgroundColor||new f(255,255,255,255),this.registerBuildInRegion(),this.initWebgl(i),this.updateDisplaySize(this.width,this.height),this.projectionDirty=!1,this.canvas.style.display="block"}updateDisplaySize(e,i){const s=this.width,r=this.height;let n,a,o,h;if(this.scaleEnable){const u=s/r,l=e/i;switch(this.scaleRadio){case t.IGNORE:n=s,a=r,o=e*this.devicePixelRatio,h=i*this.devicePixelRatio;break;case t.KEEP:let c,d;n=s,a=r,l>u?(d=i,c=d*u):(c=e,d=c/u),o=c*this.devicePixelRatio,h=d*this.devicePixelRatio;break;case t.EXPAND:l>u?(a=r,n=r*l):(n=s,a=s/l),o=e*this.devicePixelRatio,h=i*this.devicePixelRatio;break;case t.KEEP_W:n=s,a=s/l,o=e*this.devicePixelRatio,h=i*this.devicePixelRatio;break;case t.KEEP_H:a=r,n=r*l,o=e*this.devicePixelRatio,h=i*this.devicePixelRatio;break;default:n=s,a=r,o=e*this.devicePixelRatio,h=i*this.devicePixelRatio}}else n=s,a=r,o=s*this.devicePixelRatio,h=r*this.devicePixelRatio;this.logicWidth=n,this.logicHeight=a,this.physicsWidth=o,this.physicsHeight=h,this.resizeSize(n,a,o,h,!0)}resizeSize(t,e,i,s,r=!1){this.updateProjection(0,t,e,0),this.gl.viewport(0,0,i,s),this.gl.scissor(0,0,i,s),r&&(this.canvas.width=i,this.canvas.height=s,this.canvas.style.width=i/this.devicePixelRatio+"px",this.canvas.style.height=s/this.devicePixelRatio+"px")}updateProjection(t,e,i,s){this.projection=this.createOrthMatrix(t,e,i,s),this.projectionDirty=!0}initWebgl(t){t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA),t.enable(t.STENCIL_TEST),t.enable(t.SCISSOR_TEST)}clearTextureUnit(){for(let t=0;t<this.maxTextureUnits;t++)this.gl.activeTexture(this.gl.TEXTURE0+t),this.gl.bindTexture(this.gl.TEXTURE_2D,null)}registerBuildInRegion(){this.registerRegion("sprite",D),this.registerRegion("graphic",U)}registerRegion(t,e){this.regions.set(t,new e(this))}quitCurrentRegion(){this.currentRegion&&this.currentRegion.hasPendingContent()&&(this.currentRegion.render(),this.currentRegion.exitRegion())}setRegion(t,e){if(t!=this.currentRegionName||this.currentRegion&&this.currentRegion.isShaderChanged(e)){const i=this.regions.get(t);this.quitCurrentRegion(),this.currentRegion=i,this.currentRegionName=t,i.enterRegion(e)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}withTransform(t){this.save(),t(),this.restore()}startRender(t=!0){this.clear(),t&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0;const e=performance.now(),i=this.lastTime?(e-this.lastTime)/1e3:0;return this.lastTime=e,i}endRender(){this.currentRegion?.render(),this.projectionDirty=!1}render(t){t(this.startRender()),this.endRender()}renderTileMapLayer(t,e){this.tileMap.renderLayer(t,e instanceof et?{tileSet:e}:e)}renderSprite(t){const e=t.texture;if(!e||!e.base)return;const{offsetX:i,offsetY:s}=this.startDraw(t,e.width,e.height);this.setRegion("sprite",t.shader),this.currentRegion.renderSprite(e.base.texture,e.width,e.height,e.clipX,e.clipY,e.clipW,e.clipH,i,s,(t.color||this.defaultColor).uint32,t.uniforms,t.flipX,t.flipY),this.afterDraw()}renderTexture(t){t.base&&this.renderSprite({texture:t})}renderLine(t){const e=t.closed?[...t.points,t.points[0]]:t.points,{vertices:i,uv:s}=w({...t,points:e});this.renderGraphic({...t,drawType:this.gl.TRIANGLES,points:i,uv:s})}renderGraphic(t){this.startGraphicDraw(t),t.points.forEach(((e,i)=>{const s=Array.isArray(t.color)?t.color[i]:t.color,r=t.uv?.[i];this.addGraphicVertex(e.x,e.y,r,s)})),this.endGraphicDraw()}startGraphicDraw(t){const{offsetX:e,offsetY:i}=this.startDraw(t);this.setRegion("graphic",t.shader);const s=this.currentRegion;s.startRender(e,i,t.texture,t.uniforms),t.drawType&&(s.drawType=t.drawType)}addGraphicVertex(t,e,i,s){this.currentRegion.addVertex(t,e,i?.x,i?.y,(s||this.defaultColor).uint32)}endGraphicDraw(){this.currentRegion.render(),this.afterDraw()}startDraw(t,e=0,i=0){return this.currentTransform.push(t),this.matrixStack.applyTransform(t,e,i)}afterDraw(){this.currentTransform.length>0&&this.matrixStack.applyTransformAfter(this.currentTransform.pop())}renderRect(t){const{width:e,height:i}=t,s=[new g(0,0),new g(e,0),new g(e,i),new g(0,i)];this.renderGraphic({...t,points:s,drawType:this.gl.TRIANGLE_FAN})}renderCircle(t){const e=t.segments||32,i=t.radius,s=t.color||this.defaultColor,r=[];for(let n=0;n<=e;n++){const t=n/e*Math.PI*2,s=Math.cos(t)*i,a=Math.sin(t)*i;r.push(new g(s,a))}this.renderGraphic({...t,points:r,color:s,drawType:this.gl.TRIANGLE_FAN})}clear(t){const e=this.gl,i=t||this.backgroundColor;e.clearColor(i.r/255,i.g/255,i.b/255,i.a/255),e.clear(e.COLOR_BUFFER_BIT),this.clearMask()}createOrthMatrix(t,e,i,s){return new Float32Array([2/(e-t),0,0,0,0,2/(s-i),0,0,0,0,-1,0,-(e+t)/(e-t),-(s+i)/(s-i),0,1])}drawMask(t=s.Include,e){this.startDrawMask(t),e(),this.endDrawMask()}startDrawMask(t=s.Include){const e=this.gl;this.currentMaskType.push(t),this.setMaskType(t,!0),e.stencilOp(e.KEEP,e.KEEP,e.REPLACE),e.colorMask(!1,!1,!1,!1)}endDrawMask(){const t=this.gl;this.quitCurrentRegion(),t.stencilOp(t.KEEP,t.KEEP,t.KEEP),t.colorMask(!0,!0,!0,!0),this.setMaskType(this.currentMaskType.pop()??s.Include,!1)}setMaskType(t,e=!1){const i=this.gl;if(this.quitCurrentRegion(),e)this.clearMask(),i.stencilFunc(i.ALWAYS,1,255);else switch(t){case s.Include:i.stencilFunc(i.EQUAL,1,255);break;case s.Exclude:i.stencilFunc(i.NOTEQUAL,1,255)}}clearMask(){const t=this.gl;this.quitCurrentRegion(),t.clearStencil(0),t.clear(t.STENCIL_BUFFER_BIT),t.stencilFunc(t.ALWAYS,1,255)}createCostumShader(t,e,i,s=0){return P.createCostumShader(this,t,e,i,s)}startFBO(t,e=this.defaultColor){this.quitCurrentRegion(),t.bind(e),this.clearTextureUnit(),this.resizeSize(t.width,t.height,t.width,t.height),this.updateProjection(0,t.width,0,t.height),this.save(),this.matrixStack.identity(),this.currentFBO.push(t)}endFBO(){if(this.currentFBO.length>0){const t=this.currentFBO.pop();this.quitCurrentRegion(),t.unbind(),this.clearTextureUnit(),this.resizeSize(this.logicWidth,this.logicHeight,this.physicsWidth,this.physicsHeight),this.restore()}}drawToFBO(t,e){this.startFBO(t),e(),this.endFBO()}setBlendMode(t){switch(t){case a.Additive:this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE);break;case a.Subtractive:this.gl.blendFunc(this.gl.ZERO,this.gl.ONE_MINUS_SRC_COLOR);break;case a.Mix:this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA)}}drawLightShadowMask(t){this.startDrawMask(t.type||s.Exclude);this.light.createLightShadowMaskPolygon(t.occlusion,t.lightSource,t.baseProjectionLength).forEach((t=>{this.renderGraphic({points:t,color:f.Black})})),this.endDrawMask()}cssToGameCoords(t,e){const i=t instanceof g?t:new g(t,e),s=this.canvas.getBoundingClientRect(),r=i.x/s.width,n=i.y/s.height,a=r*this.logicWidth,o=n*this.logicHeight;return new g(a,o)}gameToCssCoords(t,e){const i=t instanceof g?t:new g(t,e??0),s=this.canvas.getBoundingClientRect(),r=i.x/this.logicWidth,n=i.y/this.logicHeight,a=r*s.width,o=n*s.height;return new g(a,o)}}const nt=!0;class at{constructor(t,e){this.life=0,this.datas={},this.rapid=t,this.options=e,e.texture instanceof k?this.texture=e.texture:e.texture instanceof Array&&e.texture[0]instanceof Array?this.texture=x.pickWeight(e.texture):e.texture instanceof Array&&(this.texture=x.pick(e.texture)),this.maxLife=x.scalarOrRange(e.life,1),this.datas={speed:this.processAttribute(e.animation.speed,0),rotation:this.processAttribute(e.animation.rotation,0),scale:this.processAttribute(e.animation.scale,1),color:this.processAttribute(e.animation.color,f.White),velocity:this.processAttribute(e.animation.velocity,g.ZERO),acceleration:this.processAttribute(e.animation.acceleration,g.ZERO)},this.position=g.ZERO,this.initializePosition()}processAttribute(t,e){if(!t)return{value:e};if("object"==typeof(i=t)&&null!==i&&Object.getPrototypeOf(i)===Object.prototype){const i=t,s=x.scalarOrRange(i.start,e),r=x.scalarOrRange(i.end||s,e);return{delta:i.delta??this.getDelta(s,r,this.maxLife),value:s,damping:i.damping}}return this.processAttribute({start:t},e);var i}updateDamping(t){for(const e of Object.values(this.datas))if(e.damping){const i=e.value,s=Math.pow(e.damping,t);"number"==typeof i?e.value*=s:i.multiply&&(e.value=i.multiply(s))}}updateDelta(t){const e=this.datas;for(const s of Object.values(e))if(s.delta){const e=s.value;"number"==typeof e?s.value+=t*s.delta:e.add&&(s.value=e.add(s.delta.multiply(t)))}e.color.value.clamp(),e.velocity.value=e.velocity.value.add(e.acceleration.value.multiply(t));const i=g.fromAngle(e.rotation.value).multiply(e.speed.value*t);this.position=this.position.add(i).add(e.velocity.value.multiply(t))}getDelta(t,e,i){return 0===i?t:"number"==typeof t&&"number"==typeof e?(e-t)/i:t instanceof g&&e instanceof g||t instanceof f&&e instanceof f?e.subtract(t).divide(i):t}update(t){return this.life+=t,!(this.life>=this.maxLife)&&(this.updateDamping(t),this.updateDelta(t),!0)}render(){const t=this.getPosition();this.rapid.renderSprite({...this.options,position:t,scale:this.datas.scale.value,rotation:this.datas.rotation.value,color:this.datas.color.value,texture:this.texture})}getPosition(){return this.position}initializePosition(){switch(this.options.emitShape){case o.POINT:this.position=g.ZERO;break;case o.CIRCLE:const t=Math.random()*Math.PI*2,e=(this.options.emitRadius||0)*Math.sqrt(Math.random());this.position=new g(Math.cos(t)*e,Math.sin(t)*e);break;case o.RECT:this.position=new g((Math.random()-.5)*(this.options.emitRect?.width||0),(Math.random()-.5)*(this.options.emitRect?.height||0))}!this.options.localSpace&&this.options.position&&(this.position=this.position.add(this.options.position))}}exports.ArrayType=h,exports.BaseTexture=B,exports.BlendMode=a,exports.Camera=class extends tt{constructor(t,e={}){super(t,e),this.enable=!1,this.center=!1,this.positionSmoothingSpeed=0,this.rotationSmoothingSpeed=0,this.center=e.center??!0,this.positionSmoothingSpeed=e.positionSmoothingSpeed??0,this.rotationSmoothingSpeed=e.rotationSmoothingSpeed??0,this._currentRenderPosition=this.position.clone(),this._currentRenderRotation=this.rotation,this.setEnable(e.enable??!1)}setEnable(t){this.enable=t,t?this.game.setMainCamera(this):this.game.mainCamera===this&&this.game.setMainCamera(null)}onUpdate(t){if(this.positionSmoothingSpeed>0){const e=1-Math.exp(-this.positionSmoothingSpeed*t);this._currentRenderPosition.lerp(this.position,e)}else this._currentRenderPosition.copy(this.position);if(this.rotationSmoothingSpeed>0){const e=1-Math.exp(-this.rotationSmoothingSpeed*t);let i=this.rotation-this._currentRenderRotation;for(;i<-Math.PI;)i+=2*Math.PI;for(;i>Math.PI;)i-=2*Math.PI;this._currentRenderRotation+=i*e}else this._currentRenderRotation=this.rotation}updateTransform(){const t=this.getParentTransform(),e=this.transform;e.setTransform(t.getTransform()),e.translate(this._currentRenderPosition),e.rotate(this._currentRenderRotation),e.scale(this.scale);const i=e.getInverse();if(this.center){const t=this.rapid.logicWidth/2,e=this.rapid.logicHeight/2;i[4]=i[0]*t+i[2]*e+i[4],i[5]=i[1]*t+i[3]*e+i[5]}this.transform.setTransform(i)}},exports.CanvasLayer=class extends tt{constructor(t,e){super(t,e)}updateTransform(){this.transform.identity()}},exports.Color=f,exports.DynamicArrayBuffer=u,exports.Entity=tt,exports.FrameBufferObject=z,exports.GLShader=P,exports.Game=class{constructor(t){this.mainScene=null,this.isRunning=!1,this.lastTime=0,this.tweens=[],this.timers=[],this.mainCamera=null,this.renderQueue=[],this.worldTransform=new c,this.render=new rt(t),this.input=new q(this.render),this.asset=new H(this),this.audio=new K,this.texture=this.render.texture}getMainScene(){return this.mainScene}setMainCamera(t){this.mainCamera=t}switchScene(t){this.mainScene&&this.mainScene.dispose(),this.mainScene=t,t.create()}start(){this.isRunning||(this.isRunning=!0,this.lastTime=performance.now(),this.gameLoop())}stop(){this.isRunning=!1}addEntityRenderQueue(t){this.renderQueue.push(t)}gameLoop(){if(!this.isRunning)return;const t=performance.now(),e=(t-this.lastTime)/1e3;this.lastTime=t,this.render.startRender(),this.mainScene&&(this.mainCamera&&this.mainCamera.enable&&this.render.matrixStack.setTransform(this.mainCamera.transform.getTransform()),this.worldTransform.setTransform(this.render.matrixStack.getTransform()),this.mainScene.update(e),this.mainScene.collectRenderables(this.renderQueue),this.renderQueue.sort(((t,e)=>{const i=t.parent&&t.parent===e.parent,s=t.globalZindex-e.globalZindex;return 0!==s?s:i?t.localZindex-e.localZindex:0})),this.renderQueue.forEach((t=>{t.beforeOnRender(),t.onRender(this.render)})),this.renderQueue.length=0),this.render.endRender(),this.input.updateNextFrame(),this.updateTweens(e),this.updateTimers(e),requestAnimationFrame(this.gameLoop.bind(this))}destroy(){this.audio.destroy(),this.input.destroy()}createTimer(t,e=!1){const i=new J(t,e);return this.timers.push(i),i.start(),i}updateTimers(t){for(const e of this.timers)e.update(t);this.timers=this.timers.filter((t=>!t.isFinished))}createTween(t,e,i,s,r=Z.Linear){const n=new Q(t,e,i,s,r);return this.tweens.push(n),n.start(),n}updateTweens(t){for(const e of this.tweens)e.update(t);this.tweens=this.tweens.filter((t=>!t.isFinished))}},exports.InputManager=q,exports.Label=class extends tt{constructor(t,e){super(t,e),this.text=new G(t.render,e)}onRender(t){t.renderSprite({texture:this.text})}setText(t){this.text.setText(t)}},exports.LineTextureMode=e,exports.MaskType=s,exports.MathUtils=class{static deg2rad(t){return t*(Math.PI/180)}static rad2deg(t){return t/(Math.PI/180)}static normalizeDegrees(t){return(t%360+360)%360}},exports.MatrixStack=c,exports.ParticleEmitter=class extends tt{constructor(t,e){super(t,e),this.particles=[],this.emitting=!1,this.emitTimer=0,this.emitRate=10,this.emitTime=0,this.emitTimeCounter=0,this.localSpace=nt,this.options=e,this.emitRate=e.emitRate??10,this.emitTime=e.emitTime??0,this.localSpace=e.localSpace??nt}getTransform(){return this.options}setEmitRate(t){this.emitRate=t}setEmitTime(t){this.emitTime=t}start(){this.emitting=!0,this.emitTimer=0,this.emitTimeCounter=0}stop(){this.emitting=!1}clear(){this.particles=[],this.emitTimer=0,this.emitTimeCounter=0}emit(t){const e=Math.floor(Math.min(t,(this.options.maxParticles||1/0)-this.particles.length));for(let i=0;i<e;i++){const t=this.localSpace?this.position:this.transform.getGlobalPosition(),e=new at(this.rapid,{...this.options,position:t,localSpace:this.localSpace});this.particles.unshift(e)}}onUpdate(t){if(this.emitting&&this.emitRate>0)if(this.emitTime>0)for(this.emitTimeCounter+=t;this.emitTimeCounter>=this.emitTime;)this.emit(this.emitRate),this.emitTimeCounter-=this.emitTime;else{this.emitTimer+=t;const e=1/this.emitRate;for(;this.emitTimer>=e;)this.emit(1),this.emitTimer-=e}for(let e=this.particles.length-1;e>=0;e--)this.particles[e].update(t)||this.particles.splice(e,1)}onRender(){if(this.rapid.save(),!this.localSpace){const t=this.game.worldTransform;this.rapid.matrixStack.setTransform(t.getTransform())}for(const t of this.particles)t.render();this.rapid.restore()}getParticleCount(){return this.particles.length}isActive(){return this.emitting||this.particles.length>0}oneShot(){this.emit(this.emitRate)}},exports.ParticleShape=o,exports.Random=x,exports.Rapid=rt,exports.SCALEFACTOR=O,exports.ScaleRadio=t,exports.Scene=class extends tt{create(){}},exports.ShaderType=n,exports.Sprite=class extends tt{constructor(t,e={}){super(t,e),this.animations=new Map,this.currentAnimation=null,this.currentFrame=0,this.frameTimer=0,this.isPlaying=!1,this.texture=e.texture??null,this.flipX=e.flipX??!1,this.flipY=e.flipY??!1,this.color=e.color??f.White,this.offset=e.offset??g.ZERO,e.animations&&this.setAnimations(e.animations)}setAnimations(t){this.animations=new Map(Object.entries(t))}addAnimation(t,e,i=10,s=!0){this.animations.set(t,{name:t,frames:e,fps:i,loop:s})}play(t,e=!1){const i=this.animations.get(t);i?this.currentAnimation!==i||e?(this.currentAnimation=i,this.currentFrame=0,this.frameTimer=0,this.isPlaying=!0,this.texture=this.currentAnimation.frames[this.currentFrame]):this.isPlaying||(this.isPlaying=!0):console.warn(`Animation "${t}" not found.`)}stop(){this.isPlaying=!1}onUpdate(t){if(!this.isPlaying||!this.currentAnimation)return;const e=1/this.currentAnimation.fps;for(this.frameTimer+=t;this.frameTimer>=e;)if(this.frameTimer-=e,this.currentFrame++,this.currentFrame>=this.currentAnimation.frames.length){if(!this.currentAnimation.loop){this.currentFrame=this.currentAnimation.frames.length-1,this.isPlaying=!1;break}this.currentFrame=0}this.texture=this.currentAnimation.frames[this.currentFrame]}onRender(t){this.texture&&t.renderSprite({texture:this.texture,flipX:this.flipX,flipY:this.flipY,offset:this.offset,color:this.color})}},exports.Text=G,exports.Texture=k,exports.TextureCache=I,exports.TextureWrapMode=i,exports.TileMapRender=it,exports.TileSet=et,exports.TilemapShape=r,exports.Uniform=class{constructor(t){this.isDirty=!1,this.data=t}setUniform(t,e){this.data[t]!=e&&(this.isDirty=!0),this.data[t]=e}clearDirty(){this.isDirty=!1}getUnifromNames(){return Object.keys(this.data)}bind(t,e,i,s){if(!i)return;const r=this.data[e];if("number"==typeof r)t.uniform1f(i,r);else if(Array.isArray(r))switch(r.length){case 1:Number.isInteger(r[0])?t.uniform1i(i,r[0]):t.uniform1f(i,r[0]);break;case 2:Number.isInteger(r[0])?t.uniform2iv(i,r):t.uniform2fv(i,r);break;case 3:Number.isInteger(r[0])?t.uniform3iv(i,r):t.uniform3fv(i,r);break;case 4:Number.isInteger(r[0])?t.uniform4iv(i,r):t.uniform4fv(i,r);break;case 9:t.uniformMatrix3fv(i,!1,r);break;case 16:t.uniformMatrix4fv(i,!1,r);break;default:console.error(`Unsupported uniform array length for ${e}:`,r.length)}else if("boolean"==typeof r)t.uniform1i(i,r?1:0);else if(r.base?.texture){const e=s.useTexture(r.base.texture)[0];t.uniform1i(i,e)}else console.error(`Unsupported uniform type for ${e}:`,typeof r)}},exports.Vec2=g,exports.WebglBufferArray=l,exports.WebglElementBufferArray=d,exports.graphicAttributes=_,exports.spriteAttributes=C;
package/dist/render.d.ts CHANGED
@@ -1,8 +1,10 @@
1
- import { IGraphicOptions, IRapiadOptions, IRenderLineOptions, IRenderSpriteOptions, WebGLContext } from "./interface";
2
- import { Color, MatrixStack, Vec2 } from "./math";
3
- import RenderRegion from "./regions/region";
4
- import { Texture, TextureCache } from "./texture";
5
- import GLShader from "./webgl/glshader";
1
+ import { ICircleRenderOptions, IGraphicRenderOptions, ILayerRenderOptions, IRapidOptions, IRectRenderOptions, IRenderLineOptions, ISpriteRenderOptions, ShaderType as ShaderType, MaskType, WebGLContext, BlendMode, ILightRenderOptions, IPolygonGraphicRenderOptions } from './interface';
2
+ import { LightManager } from './light';
3
+ import { Color, MatrixStack, Vec2 } from './math';
4
+ import { default as RenderRegion } from './regions/region';
5
+ import { FrameBufferObject, Texture, TextureCache } from './texture';
6
+ import { TileMapRender, TileSet } from './tilemap';
7
+ import { default as GLShader } from './webgl/glshader';
6
8
  /**
7
9
  * The `Rapid` class provides a WebGL-based rendering engine.
8
10
  */
@@ -12,27 +14,49 @@ declare class Rapid {
12
14
  projection: Float32Array;
13
15
  projectionDirty: boolean;
14
16
  matrixStack: MatrixStack;
15
- textures: TextureCache;
17
+ texture: TextureCache;
18
+ tileMap: TileMapRender;
19
+ light: LightManager;
16
20
  width: number;
17
21
  height: number;
18
22
  backgroundColor: Color;
19
- readonly devicePixelRatio: number;
23
+ devicePixelRatio: number;
24
+ private physicsWidth;
25
+ private physicsHeight;
26
+ logicWidth: number;
27
+ logicHeight: number;
28
+ private scaleEnable;
29
+ private scaleRadio;
20
30
  readonly maxTextureUnits: number;
21
31
  private readonly defaultColor;
22
- private readonly defaultColorBlack;
23
32
  private currentRegion?;
24
33
  private currentRegionName?;
25
34
  private regions;
35
+ private currentMaskType;
36
+ private currentTransform;
37
+ private currentFBO;
38
+ private lastTime;
26
39
  /**
27
40
  * Constructs a new `Rapid` instance with the given options.
28
41
  * @param options - Options for initializing the `Rapid` instance.
29
42
  */
30
- constructor(options: IRapiadOptions);
43
+ constructor(options: IRapidOptions);
44
+ /**
45
+ * @param displayWdith css px size
46
+ * @param displayHeight css px size
47
+ */
48
+ updateDisplaySize(displayWdith: number, displayHeight: number): void;
49
+ private resizeSize;
50
+ private updateProjection;
31
51
  /**
32
52
  * Initializes WebGL context settings.
33
53
  * @param gl - The WebGL context.
34
54
  */
35
55
  private initWebgl;
56
+ /**
57
+ * @ignore
58
+ */
59
+ clearTextureUnit(): void;
36
60
  /**
37
61
  * Registers built-in regions such as sprite and graphic regions.
38
62
  */
@@ -43,10 +67,12 @@ declare class Rapid {
43
67
  * @param regionClass - The class of the region to register.
44
68
  */
45
69
  registerRegion(name: string, regionClass: typeof RenderRegion): void;
70
+ private quitCurrentRegion;
46
71
  /**
47
72
  * Sets the current render region by name and optionally a custom shader.
48
73
  * @param regionName - The name of the region to set as current.
49
74
  * @param customShader - An optional custom shader to use with the region.
75
+ * @param hasUnifrom - have costum unifrom
50
76
  */
51
77
  setRegion(regionName: string, customShader?: GLShader): void;
52
78
  /**
@@ -57,69 +83,94 @@ declare class Rapid {
57
83
  * Restores the matrix state from the stack.
58
84
  */
59
85
  restore(): void;
86
+ /**
87
+ * Executes a callback function within a saved and restored matrix state scope.
88
+ * @param cb - The callback function to execute within the saved and restored matrix state scope.
89
+ */
90
+ withTransform(cb: () => void): void;
60
91
  /**
61
92
  * Starts the rendering process, resetting the matrix stack and clearing the current region.
62
93
  * @param clear - Whether to clear the matrix stack. Defaults to true.
63
94
  */
64
- startRender(clear?: boolean): void;
95
+ startRender(clear?: boolean): number;
65
96
  /**
66
97
  * Ends the rendering process by rendering the current region.
67
98
  */
68
99
  endRender(): void;
69
100
  /**
70
- * Renders a sprite with the specified texture, offset, and options.
71
- * @param texture - The texture to render.
72
- * @param offsetX - The X offset for the sprite. Defaults to 0.
73
- * @param offsetY - The Y offset for the sprite. Defaults to 0.
74
- * @param options - Rendering options including color and custom shader.
101
+ * Render
102
+ * @param cb - The function to render.
75
103
  */
76
- renderSprite(texture: Texture, offsetX?: number, offsetY?: number, options?: IRenderSpriteOptions | Color): void;
104
+ render(cb: (dt: number) => void): void;
77
105
  /**
78
- * Renders a line with the specified options.
106
+ * Render a tile map layer.
107
+ * @param data - The map data to render.
108
+ * @param options - The options for rendering the tile map layer.
109
+ */
110
+ renderTileMapLayer(data: (number | string)[][], options: ILayerRenderOptions | TileSet): void;
111
+ /**
112
+ * Renders a sprite with the specified options.
79
113
  *
80
- * @param offsetX - The X offset to apply when rendering the line. Defaults to 0.
81
- * @param offsetY - The Y offset to apply when rendering the line. Defaults to 0.
82
- * @param options - The options for rendering the line, including points and color.
114
+ * @param options - The rendering options for the sprite, including texture, position, color, and shader.
83
115
  */
84
- renderLine(offsetX: number | undefined, offsetY: number | undefined, options: IRenderLineOptions): void;
116
+ renderSprite(options: ISpriteRenderOptions): void;
85
117
  /**
86
- * Renders graphics based on the provided options or array of Vec2 points.
118
+ * Renders a texture directly without additional options.
119
+ * This is a convenience method that calls renderSprite with just the texture.
87
120
  *
88
- * @param offsetX - The X offset to apply when rendering the graphics. Defaults to 0.
89
- * @param offsetY - The Y offset to apply when rendering the graphics. Defaults to 0.
90
- * @param options - Either an object containing graphic options or an array of Vec2 points.
121
+ * @param texture - The texture to render at the current transformation position.
122
+ */
123
+ renderTexture(texture: Texture): void;
124
+ /**
125
+ * Renders a line with the specified options.
91
126
  *
92
- * @remarks
93
- * If `options` is an array of `Vec2`, it will be converted to an object with `points` property.
94
- * If `options` is an object, it should contain `points` (array of `Vec2`) and optionally `color` and `drawType`.
127
+ * @param options - The options for rendering the line, including points, color, width, and join/cap types.
95
128
  */
96
- renderGraphic(offsetX: number | undefined, offsetY: number | undefined, options: IGraphicOptions | Vec2[]): void;
129
+ renderLine(options: IRenderLineOptions): void;
97
130
  /**
98
- * Starts a graphic drawing process with an optional custom shader.
99
- * @param customShader - An optional custom shader to use.
131
+ * Renders graphics based on the provided options.
132
+ *
133
+ * @param options - The options for rendering the graphic, including points, color, texture, and draw type.
134
+ */
135
+ renderGraphic(options: IPolygonGraphicRenderOptions): void;
136
+ /**
137
+ * Starts the graphic drawing process.
138
+ *
139
+ * @param options - The options for the graphic drawing, including shader, texture, and draw type.
100
140
  */
101
- startGraphicDraw(customShader?: GLShader): void;
141
+ startGraphicDraw(options: IGraphicRenderOptions): void;
102
142
  /**
103
- * Adds a vertex to the current graphic drawing with a specified position and color.
104
- * @param x - The X position of the vertex.
105
- * @param y - The Y position of the vertex.
106
- * @param color - The color of the vertex.
143
+ * Adds a vertex to the current graphic being drawn.
144
+ *
145
+ * @param offsetX - The X coordinate of the vertex.
146
+ * @param offsetY - The Y coordinate of the vertex.
147
+ * @param uv - The texture UV coordinates for the vertex.
148
+ * @param color - The color of the vertex. Defaults to the renderer's default color.
107
149
  */
108
- addGraphicVertex(x: number | Vec2, y?: number | Color, color?: Color): void;
150
+ addGraphicVertex(offsetX: number, offsetY: number, uv: Vec2, color?: Color): void;
109
151
  /**
110
- * Ends the graphic drawing process by rendering the current graphic region.
152
+ * Completes the graphic drawing process and renders the result.
111
153
  */
112
154
  endGraphicDraw(): void;
155
+ private startDraw;
156
+ private afterDraw;
113
157
  /**
114
- * Resizes the canvas and updates the viewport and projection matrix.
115
- * @param width - The new width of the canvas.
116
- * @param height - The new height of the canvas.
158
+ * Renders a rectangle with the specified options.
159
+ *
160
+ * @param options - The options for rendering the rectangle, including width, height, position, and color.
161
+ */
162
+ renderRect(options: IRectRenderOptions): void;
163
+ /**
164
+ * Renders a circle with the specified options.
165
+ *
166
+ * @param options - The options for rendering the circle, including radius, position, color, and segment count.
117
167
  */
118
- resize(width: number, height: number): void;
168
+ renderCircle(options: ICircleRenderOptions): void;
119
169
  /**
120
170
  * Clears the canvas with the background color.
171
+ * @param bgColor - The background color to clear the canvas with.
121
172
  */
122
- clear(): void;
173
+ clear(bgColor?: Color): void;
123
174
  /**
124
175
  * Creates an orthogonal projection matrix.
125
176
  * @param left - The left bound of the projection.
@@ -130,11 +181,71 @@ declare class Rapid {
130
181
  */
131
182
  private createOrthMatrix;
132
183
  /**
133
- * Transforms a point by applying the current matrix stack.
134
- * @param x - The X coordinate of the point.
135
- * @param y - The Y coordinate of the point.
136
- * @returns The transformed point as an array `[newX, newY]`.
184
+ * Draw a mask. Automatically calls startDrawMask.
185
+ * @param type - The type of mask to draw.
186
+ * @param cb - The callback function to execute.
187
+ */
188
+ drawMask(type: MaskType | undefined, cb: () => void): void;
189
+ /**
190
+ * Start drawing a mask using the stencil buffer.
191
+ * This method configures the WebGL context to begin defining a mask area.
192
+ */
193
+ startDrawMask(type?: MaskType): void;
194
+ /**
195
+ * End the mask drawing process.
196
+ * This method configures the WebGL context to use the defined mask for subsequent rendering.
197
+ */
198
+ endDrawMask(): void;
199
+ /**
200
+ * Set the mask type for rendering
201
+ * @param type - The mask type to apply
202
+ * @param start - Whether this is the start of mask drawing
203
+ */
204
+ private setMaskType;
205
+ /**
206
+ * Clear the current mask by clearing the stencil buffer.
207
+ * This effectively removes any previously defined mask.
208
+ */
209
+ clearMask(): void;
210
+ /**
211
+ * Creates a custom shader.
212
+ * @param vs - Vertex shader code.
213
+ * @param fs - Fragment shader code.
214
+ * @param type - Shader type.
215
+ * @returns The created shader object.
216
+ */
217
+ createCostumShader(vs: string, fs: string, type: ShaderType, textureUnitNum?: number): GLShader;
218
+ /**
219
+ * Starts rendering to a Frame Buffer Object (FBO)
220
+ * Sets up the FBO for rendering by binding it, adjusting viewport size and projection
221
+ * @param fbo - The Frame Buffer Object to render to
222
+ */
223
+ startFBO(fbo: FrameBufferObject, color?: Color): void;
224
+ /**
225
+ * Ends rendering to a Frame Buffer Object
226
+ * Restores the default framebuffer and original viewport settings
227
+ * @param fbo - The Frame Buffer Object to unbind
228
+ */
229
+ endFBO(): void;
230
+ /**
231
+ * Convenience method to render to a Frame Buffer Object
232
+ * Handles starting and ending the FBO rendering automatically
233
+ * @param fbo - The Frame Buffer Object to render to
234
+ * @param cb - Callback function containing render commands to execute on the FBO
235
+ */
236
+ drawToFBO(fbo: FrameBufferObject, cb: () => void): void;
237
+ /**
238
+ * Set the blend mode for rendering
239
+ * @param mode - The blend mode to apply
240
+ */
241
+ setBlendMode(mode: BlendMode): void;
242
+ /**
243
+ * Render light shadow
244
+ * @param occlusion - The occlusion polygon
245
+ * @param lightSource - The light source position
137
246
  */
138
- transformPoint(x: number, y: number): number[] | Vec2;
247
+ drawLightShadowMask(options: ILightRenderOptions): void;
248
+ cssToGameCoords(x: number | Vec2, y?: number): Vec2;
249
+ gameToCssCoords(x: number | Vec2, y?: number): Vec2;
139
250
  }
140
251
  export default Rapid;