From 7241bf809d2e40f9a789157ed6aad5d40766f311 Mon Sep 17 00:00:00 2001 From: Quinton Ashley Date: Tue, 4 Jul 2023 21:23:36 -0500 Subject: [PATCH] 1.1.588 --- .gitignore | 1 + package.json | 2 +- tests/SpriteAnimation.test.js | 8 ++++---- v3/p5play.js | 3 ++- v3/p5play.min.js | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 832cd0e0..7d317b6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules testing/experiments +testing/assets testing/test* package-lock.json dev diff --git a/package.json b/package.json index e18d0f34..272e41fd 100644 --- a/package.json +++ b/package.json @@ -77,5 +77,5 @@ "make": "electron-forge make", "publish": "electron-forge publish" }, - "version": "1.1.587" + "version": "1.1.588" } diff --git a/tests/SpriteAnimation.test.js b/tests/SpriteAnimation.test.js index 6838d42b..6666ffd6 100644 --- a/tests/SpriteAnimation.test.js +++ b/tests/SpriteAnimation.test.js @@ -46,7 +46,7 @@ test('SpriteAnimation : properties', () => { ani0.frame = 1; expect(ani0.frame).toBe(1); - const images1 = [p.createImage(32, 32), p.createImage(32, 32), p.createImage(32, 32)]; + const images1 = [p.createImage(32, 32)]; const ani1 = new p.SpriteAnimation('custom', ...images1); expect(ani1).toBeInstanceOf(p.SpriteAnimation); @@ -54,17 +54,17 @@ test('SpriteAnimation : properties', () => { // test that sprite s0 is the parent of ani2 const s0 = new p.Sprite(); - const images2 = [p.createImage(32, 32), p.createImage(32, 32), p.createImage(32, 32)]; + const images2 = [p.createImage(32, 32), p.createImage(32, 32)]; const ani2 = new p.SpriteAnimation(s0, ...images2); - expect(s0.ani).toBe(ani2); + expect(s0.ani.length).toBe(ani2.length); // test that group g0 is the parent of ani3 const g0 = new p.Group(); const images3 = [p.createImage(32, 32), p.createImage(32, 32), p.createImage(32, 32)]; const ani3 = new p.SpriteAnimation(g0, ...images3); - expect(g0.ani).toBe(ani3); + expect(g0.ani.length).toBe(ani3.length); }; }; new p5(sketch); diff --git a/v3/p5play.js b/v3/p5play.js index 80c8e497..680be993 100644 --- a/v3/p5play.js +++ b/v3/p5play.js @@ -3659,7 +3659,8 @@ p5.prototype.registerMethod('init', function p5PlayInit() { if (args.length == 0 || typeof args[0] == 'number') return; - owner.addAni(this); + owner.animations[this.name] = this; + owner._ani = this; // list mode images can be added as a list of arguments or an array if (Array.isArray(args[0]) && typeof args[0][0] == 'string') { diff --git a/v3/p5play.min.js b/v3/p5play.min.js index a766be6f..bd5a458a 100644 --- a/v3/p5play.min.js +++ b/v3/p5play.min.js @@ -4,4 +4,4 @@ * @author quinton-ashley * @license gpl-v3-only */ -p5.prototype.registerMethod("init",(function(){if(void 0===window.planck)throw"planck.js must be loaded before p5play";const t=this,e=console.log;this.log=console.log;const i=planck,s=60;this.p5play??={},this.p5play.os??={},this.p5play.context??="web",this.p5play.standardizeKeyboard??=!1,this.p5play.sprites={},this.p5play.groups={},this.p5play.groupsCreated=0,this.p5play.spritesCreated=0,this.angleMode("degrees");const r=(t,e,r)=>new i.Vec2(t*r/s,e*r/s),o=(t,e,r)=>new i.Vec2(t/r*s,e/r*s),h=t=>Math.abs(t)<=i.Settings.linearSlop,n=t=>Math.abs(t-Math.round(t))<=i.Settings.linearSlop?Math.round(t):t,a={_collisions:["_collides","_colliding","_collided"],_overlappers:["_overlaps","_overlapping","_overlapped"]};this.Sprite=class{constructor(e,r,o,h,a){this.p=t,this.idNum,this.watch,this.mod=[];let p,c,f=[...arguments];if(void 0!==f[0]&&f[0]instanceof this.p.Group&&(p=f[0],f=f.slice(1)),f.length||(this._noArgs=!0),void 0!==f[0]&&isNaN(f[0])&&("string"==typeof f[0]||f[0]instanceof this.p.SpriteAnimation||f[0]instanceof p5.Image)&&(c=f[0],f=f.slice(1)),1==f.length&&"number"==typeof f[0])throw new x("Sprite",0,[f[0]]);if(e=f[0],r=f[1],o=f[2],h=f[3],a=f[4],this._originMode="center",Array.isArray(e)&&(e=void 0,r=void 0,o=f[0],h=f[1],a=f[2]),Array.isArray(o)||"string"==typeof h){if(isNaN(o)||(o=Number(o)),"number"!=typeof o&&Array.isArray(o[0])&&(this._originMode="start"),void 0!==h){if(Array.isArray(h))throw new x("Sprite",1,[`[[${o}], [${h}]]`]);!function(t){let e=t.slice(0,2);return"d"==t||"s"==t||"k"==t||"n"==t||"dy"==e||"st"==e||"ki"==e||"no"==e}(h)?o=u(o,h):a=h,h=void 0}}else isNaN(o)&&(a=o,o=void 0);if(this.idNum=this.p.p5play.spritesCreated,this._uid=1e3+this.idNum,this.p.p5play.sprites[this._uid]=this,this.p.p5play.spritesCreated++,this.groups=[],this.p.allSprites.push(this),this.animations=new this.p.SpriteAnimations,this.joints=[],this.removed=!1,p){if(p.push(this),!c)for(let t in p.animations){c=t;break}}else p=this.p.allSprites;p.dynamic&&(a??="dynamic"),p.kinematic&&(a??="kinematic"),p.static&&(a??="static"),a??=p.collider,this._shape=p.shape,this._life=2147483647,this._visible=!0,this._aniChangeCount=0,this._collides={},this._colliding={},this._collided={},this._hasOverlap={},this._overlaps={},this._overlapping={},this._overlapped={},this._collisions={},this._overlappers={},this.tileSize=p.tileSize||1;let _=this;if(this._position={x:0,y:0},this._pos=t.createVector.call(t),Object.defineProperty(this._pos,"x",{get(){if(!_.body)return _._position.x;let t=_.body.getPosition().x/_.tileSize*s;return n(t)},set(t){if(_.body){let e=new i.Vec2(t*_.tileSize/s,_.body.getPosition().y);_.body.setPosition(e)}_._position.x=t}}),Object.defineProperty(this._pos,"y",{get(){if(!_.body)return _._position.y;let t=_.body.getPosition().y/_.tileSize*s;return n(t)},set(t){if(_.body){let e=new i.Vec2(_.body.getPosition().x,t*_.tileSize/s);_.body.setPosition(e)}_._position.y=t}}),this._velocity={x:0,y:0},this._vel=t.createVector.call(t),Object.defineProperties(this._vel,{x:{get(){let t;return t=_.body?_.body.getLinearVelocity().x:_._velocity.x,n(t/_.tileSize)},set(t){t*=_.tileSize,_.body?_.body.setLinearVelocity(new i.Vec2(t,_.body.getLinearVelocity().y)):_._velocity.x=t}},y:{get(){let t;return t=_.body?_.body.getLinearVelocity().y:_._velocity.y,n(t/_.tileSize)},set(t){t*=_.tileSize,_.body?_.body.setLinearVelocity(new i.Vec2(_.body.getLinearVelocity().x,t)):_._velocity.y=t}}}),this._mirror={_x:1,_y:1,get x(){return this._x<0},set x(t){_.watch&&(_.mod[22]=!0),this._x=t?-1:1},get y(){return this._y<0},set y(t){_.watch&&(_.mod[22]=!0),this._y=t?-1:1}},this._heading="right",this._layer=p._layer,this._layer??=this.p.allSprites._getTopLayer()+1,a??=p.collider,a&&"string"==typeof a||(a="dynamic"),this.collider=a,e??=p.x,void 0===e&&(e=this.p.width/this.p.allSprites.tileSize/2,this._vertexMode=!0),r??=p.y,void 0===r&&(r=this.p.height/this.p.allSprites.tileSize/2),o??=p.w||p.width||p.d||p.diameter,h??=p.h||p.height,"function"==typeof e&&(e=e(p.length-1)),"function"==typeof r&&(r=r(p.length-1)),this.x=e,this.y=r,c){c instanceof p5.Image?this.addAni(c):"string"==typeof c?this._changeAni(c):this._ani=c.clone();let t=this.tileSize;o||1==this._ani.w&&1==this._ani.h||(o=this._ani.w/t,"circle"!=this.shape&&(h=this._ani.h/t))}if(this.mouse=new this.p._SpriteMouse,"none"!=this.collider)this._vertexMode?this.addCollider(o,h):this.addCollider(0,0,o,h);else{if(this.w=o||(this.tileSize>1?1:50),this.h=h||this.w,Array.isArray(o))throw new Error('Cannot set the collider type of a sprite with a polygon or chain shape to "none". Try having the sprite overlap with other sprites instead.');this._shape=void 0!==o&&void 0===h?"circle":"box"}this._scale=new l,Object.defineProperty(this._scale,"x",{get(){return this._x},set(t){if(t==this._x)return;_.watch&&(_.mod[28]=!0);let e=t/this._x;_._w*=e,_._hw*=e,_._resizeCollider({x:e,y:1}),this._x=t,this._avg=.5*(this._x+this._y)}}),Object.defineProperty(this._scale,"y",{get(){return this._y},set(t){if(t==this._y)return;_.watch&&(_.mod[28]=!0);let e=t/this._y;_._h&&(this._h*=e,this._hh*=e),_._resizeCollider({x:1,y:e}),this._y=t,this._avg=.5*(this._x+this._y)}}),this._offset={_x:0,_y:0,get x(){return this._x},set x(t){t!=this._x&&(_.watch&&(_.mod[23]=!0),_._offsetCenterBy(t-this._x,0))},get y(){return this._y},set y(t){t!=this._y&&(_.watch&&(_.mod[23]=!0),_._offsetCenterBy(0,t-this._y))}},this.prevPos={x:e,y:r},this.prevRotation=0,this._dest={x:e,y:r},this._destIdx=0,this.drag=0,this.debug=!1,this._shift={};let g=p.vel.x||0,y=p.vel.y||0;"function"==typeof g&&(g=g(p.length-1)),"function"==typeof y&&(y=y(p.length-1)),this.vel.x=g,this.vel.y=y;let m=["ani","collider","vel","x","y"];for(let t of this.p.Sprite.propsAll){if(m.includes(t))continue;let e=p[t];void 0!==e&&("function"==typeof e&&d(e)&&(e=e(p.length-1)),this[t]="object"==typeof e?Object.assign({},e):e)}m=["add","animation","animations","autoCull","contains","GroupSprite","Group","idNum","length","mod","mouse","p","parent","Sprite","Subgroup","subgroups","velocity"];for(let t=0;t1?1:50,o??=s),"box"!=a&&"circle"!=a||(l=r(s-.08,o-.08,this.tileSize)),"box"==a)p=i.Box(l.x/2,l.y/2,r(t,e,this.tileSize),0);else if("circle"==a)p=i.Circle(r(t,e,this.tileSize),l.x/2);else if(n){let c,f,_=[{x:0,y:0}],g={x:0,y:0},y={x:0,y:0},m={x:0,y:0},w=Array.isArray(n[0]);function x(){g.xm.x&&(m.x=g.x),g.y>m.y&&(m.y=g.y)}if(w){this._vertexMode&&(c=n[0][0],f=n[0][1],this.body?(c=this.x-this._relativeOrigin.x,f=this.y-this._relativeOrigin.y,_.pop()):(this.x=c,this.y=f));for(let b=0;b0?1:-1;S=Math.abs(S);let C=0;for(let k=0;ki.Settings.maxPolygonVertices||"chain"==this._shape)&&(a="chain"),"polygon"==a?p=i.Polygon(_):"chain"==a&&(p=i.Chain(_,!1))}return this._shape||(this._shape=a),this._w=s,this._hw=.5*s,"circle"==this._shape?this._diameter=s:(this._h=o,this._hh=.5*o),p}removeColliders(){this._collides={},this._colliding={},this._collided={},this._removeFixtures(!1)}removeSensors(){this._hasOverlap={},this._overlaps={},this._overlapping={},this._overlapped={},this._removeFixtures(!0)}_removeFixtures(t){let e;for(let i=this.fixtureList;i;i=i.getNext())if(void 0===t||i.m_isSensor==t){let t=i.m_next;i.destroyProxies(this.p.world.m_broadPhase),e?e.m_next=t:this.body.m_fixtureList=t}else e=i}_offsetCenterBy(t,e){if(!t&&!e)return;if(this._offset._x+=t,this._offset._y+=e,!this.body)return;let i=r(t,e,this.tileSize);for(let t=this.body.m_fixtureList;t;t=t.m_next){let e=t.m_shape;if("circle"!=e.m_type){let t=e.m_vertices;for(let e of t)e.x+=i.x,e.y+=i.y}else e.m_p.x+=i.x,e.m_p.y+=i.y}}_cloneBodyProps(){let t={},e=["bounciness","density","drag","friction","heading","isSuperFast","rotation","rotationDrag","rotationLock","rotationSpeed","scale","vel","x","y"];this._massUndefinedByUser&&this._dimensionsUndefinedByUser||e.push("mass");for(let i of e)"object"==typeof this[i]?t[i]=Object.assign({},this[i]):t[i]=this[i];return t}get animation(){return this._ani}set animation(t){this.changeAni(t)}get ani(){return this._ani}set ani(t){this.changeAni(t)}get anis(){return this.animations}get autoDraw(){return this._autoDraw}set autoDraw(t){this.watch&&(this.mod[6]=!0),this._autoDraw=t}get allowSleeping(){return this.body?.isSleepingAllowed()}set allowSleeping(t){this.watch&&(this.mod[7]=!0),this.body&&this.body.setSleepingAllowed(t)}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){this.watch&&(this.mod[8]=!0),this._autoUpdate=t}get bounciness(){if(this.fixture)return this.fixture.getRestitution()}set bounciness(t){this.watch&&(this.mod[9]=!0);for(let e=this.fixtureList;e;e=e.getNext())e.setRestitution(t)}get centerOfMass(){let t=this.body.getWorldCenter();return o(t.x,t.y,this.tileSize)}get collider(){return this._collider}set collider(t){let e=(t=t.toLowerCase())[0];if("d"==e&&(t="dynamic"),"s"==e&&(t="static"),"k"==e&&(t="kinematic"),"n"==e&&(t="none"),t==this._collider)return;if(this.__collider=["d","s","k","n"].indexOf(e),void 0===this._collider)return void(this._collider=t);if("none"==t&&("chain"==this._shape||"polygon"==this._shape))throw new Error('Cannot set the collider type of a polygon or chain collider to "none". Try having the sprite overlap with other sprites instead.');this.watch&&(this.mod[10]=!0);let i=this._collider;this._collider=t,void 0!==i&&this._reset()}_reset(){let t,e=this._cloneBodyProps();"chain"!=this._shape&&"polygon"!=this._shape||(t=this._getVertices(!0),this._vertexMode=!0),this.body&&(this.p.world.destroyBody(this.body),this.body=void 0),"none"!=this._collider&&(t?this.addCollider(0,0,t):this.addCollider(),this._hasSensors&&this.addDefaultSensors());for(let t in e)void 0!==e[t]&&(this[t]=e[t]);let i=this._offset._x,s=this._offset._y;this._offset._x=0,this._offset._y=0,this._offsetCenterBy(i,s)}_parseColor(t){if(t instanceof p5.Color)return t;if("object"!=typeof t)return"string"==typeof t&&1==t.length?this.p.colorPal(t):this.p.color(t);if(t.levels)return this.p.color(...t.levels);if(void 0!==t._r)return this.p.color(t._r,t._g,t._b,255*t._a);if(void 0!==t._h)return this.p.color(t._h,t._s,t._v,255*t._a);throw new Error("Invalid color")}get color(){return this._color}set color(t){this.watch&&(this.mod[11]=!0),this._color=this._parseColor(t)}get colour(){return this._color}set colour(t){this.color=t}get shapeColor(){return console.warn("sprite.shapeColor is deprecated, use sprite.color instead"),this._color}set shapeColor(t){console.warn("sprite.shapeColor is deprecated, use sprite.color instead"),this.color=t}get fill(){return this._color}set fill(t){this.color=t}get fillColor(){return this._color}set fillColor(t){this.color=t}get stroke(){return this._stroke}set stroke(t){this.watch&&(this.mod[31]=!0),this._stroke=this._parseColor(t)}get strokeColor(){return this._stroke}set strokeColor(t){this.stroke=t}get strokeWeight(){return this._strokeWeight}set strokeWeight(t){this.watch&&(this.mod[32]=!0),this._strokeWeight=t}get textColor(){return this._textColor}set textColor(t){this.watch&&(this.mod[34]=!0),this._textColor=this._parseColor(t)}get debug(){return this._debug}set debug(t){this.watch&&(this.mod[12]=!0),this._debug=t}get density(){if(this.fixture)return this.fixture.getDensity()}set density(t){this.watch&&(this.mod[13]=!0);for(let e=this.fixtureList;e;e=e.getNext())e.setDensity(t)}get depth(){return console.warn("sprite.depth is deprecated, use sprite.layer instead"),this._layer}set depth(t){console.warn("sprite.depth is deprecated, use sprite.layer instead"),this.layer=t}_getDirectionAngle(t){t=t.toLowerCase().replaceAll(/[ _-]/g,"");let e={up:-90,down:90,left:180,right:0,upright:-45,rightup:-45,upleft:-135,leftup:-135,downright:45,rightdown:45,downleft:135,leftdown:135,forward:this.rotation,backward:this.rotation+180}[t];return"radians"==this.p._angleMode&&(e=this.p.radians(e)),e}get direction(){return 0!==this.vel.x||0!==this.vel.y?this.p.atan2(this.vel.y,this.vel.x):void 0===this._direction?this.rotation:this._direction}set direction(t){this.watch&&(this.mod[14]=!0),"string"==typeof t&&(this._heading=t,t=this._getDirectionAngle(t)),this._direction=t;let e=this.speed;this.vel.x=this.p.cos(t)*e,this.vel.y=this.p.sin(t)*e}get drag(){return this.body?.getLinearDamping()}set drag(t){this.watch&&(this.mod[15]=!0),this.body&&this.body.setLinearDamping(t)}get draw(){return this._display}set draw(t){this._draw=t}get dynamic(){return this.body?.isDynamic()}set dynamic(t){this.collider=t?"dynamic":"kinematic"}get fixture(){return this.fixtureList}get fixtureList(){return this.body?this.body.m_fixtureList:null}get friction(){if(this.fixture)return this.fixture.getFriction()}set friction(t){this.watch&&(this.mod[16]=!0);for(let e=this.fixtureList;e;e=e.getNext())e.setFriction(t)}get heading(){return this._heading}set heading(t){this.direction=t}get immovable(){return console.warn("sprite.immovable is deprecated, use sprite.static instead"),this.body.isStatic()}set immovable(t){console.warn("sprite.immovable is deprecated, use sprite.static instead"),t&&this.body.setStatic()}get img(){return this._ani?.frameImage}set img(t){this.changeAni(t)}get image(){return this._ani?.frameImage}set image(t){this.changeAni(t)}get isMoving(){return 0!=this.vel.x||0!=this.vel.y}get isSuperFast(){return this.body?.isBullet()}set isSuperFast(t){this.watch&&(this.mod[18]=!0),this.body&&this.body.setBullet(t)}get kinematic(){return this.body?.isKinematic()}set kinematic(t){this.collider=t?"kinematic":"dynamic"}get layer(){return this._layer}set layer(t){this.watch&&(this.mod[19]=!0),this._layer=t}get life(){return this._life}set life(t){this.watch&&(this.mod[20]=!0),this._life=t}get mass(){return this.body?.getMass()}set mass(t){if(!this.body)return;this.watch&&(this.mod[21]=!0);let e=this.massData;e.mass=t,this.body.setMassData(e),delete this._massUndefinedByUser}get massData(){const t={I:0,center:new i.Vec2(0,0),mass:0};return this.body.getMassData(t),t.center=o(t.center.x,t.center.y,this.tileSize),t}get mirror(){return this._mirror}set mirror(t){this.watch&&(this.mod[22]=!0),void 0!==t.x&&(this._mirror.x=t.x),void 0!==t.y&&(this._mirror.y=t.y)}get offset(){return this._offset}set offset(t){t.x??=this._offset._x,t.y??=this._offset._y,t.x==this._offset._x&&t.y==this._offset._y||(this.watch&&(this.mod[23]=!0),this._offsetCenterBy(t.x-this._offset._x,t.y-this._offset._y))}get previousPosition(){return this.prevPos}set previousPosition(t){this.prevPos=t}get previousRotation(){return this.prevRotation}set previousRotation(t){this.prevRotation=t}get pixelPerfect(){return this._pixelPerfect}set pixelPerfect(t){this.watch&&(this.mod[24]=!0),this._pixelPerfect=t}get rotation(){if(!this.body)return this._angle||0;let t=this.body.getAngle();return"degrees"===this.p._angleMode?this.p.degrees(t):t}set rotation(t){this.body?("degrees"===this.p._angleMode&&(t=this.p.radians(t)),this.body.setAngle(t)):this._angle=t}get rotationDrag(){return this.body?.getAngularDamping()}set rotationDrag(t){this.body&&(this.watch&&(this.mod[26]=!0),this.body.setAngularDamping(t))}get rotationLock(){return this.body?.isFixedRotation()}set rotationLock(t){this.body&&(this.watch&&(this.mod[27]=!0),this.body.setFixedRotation(t))}get rotationSpeed(){return this.body?this.body.getAngularVelocity():this._rotationSpeed||0}set rotationSpeed(t){this.body?this.body.setAngularVelocity(t):this._rotationSpeed=t}get scale(){return this._scale}set scale(t){if(t<=0&&(t=.01),"number"==typeof t?t={x:t,y:t}:(t.x??=this._scale._x,t.y??=this._scale._y),t.x==this._scale._x&&t.y==this._scale._y)return;this.watch&&(this.mod[28]=!0);let e={x:t.x/this._scale._x,y:t.y/this._scale._y};this._w*=e.x,this._hw*=e.x,this._h&&(this._h*=e.y,this._hh*=e.y),this._resizeCollider(e),this._scale._x=t.x,this._scale._y=t.y,this._scale._avg=t.x}get sleeping(){if(this.body)return!this.body.isAwake()}set sleeping(t){this.body&&(this.watch&&(this.mod[30]=!0),this.body.setAwake(!t))}get speed(){return this.p.createVector(this.vel.x,this.vel.y).mag()}set speed(t){let e=this.direction;this.vel.x=this.p.cos(e)*t,this.vel.y=this.p.sin(e)*t}get static(){return this.body?.isStatic()}set static(t){this.collider=t?"static":"dynamic"}get vertices(){return this._getVertices()}_getVertices(e){let i=this.fixture;for(;i.m_next;)i=i.m_next;let r=i.getShape(),o=[...r.m_vertices];"polygon"==r.m_type&&o.unshift(o.at(-1));let h=this.x,a=this.y;for(let i=0;i=1e3?this.p.p5play.sprites[i]:this.p.p5play.groups[i];let o=t[e][i]+1;if(this[e][i]=o,r instanceof this.p.Group&&(r[e][t._uid]=o),!r||0==o){delete t[e][i],r instanceof this.p.Group&&delete r[e][t._uid];continue}if(s=-1==o?a[e][2]:1==o?a[e][0]:a[e][1],r instanceof this.p.Group)continue;let h=this.p.world._findContactCB(s,t,r);"function"==typeof h&&h(t,r,o)}this.removed&&0==Object.keys(this._collisions).length&&0==Object.keys(this._overlappers).length&&delete this.p.p5play.sprites[this._uid]}_draw(){if(void 0!==this.strokeWeight&&this.p.strokeWeight(this.strokeWeight),this._ani&&"colliders"!=this.debug&&this._ani.draw(this._offset._x,this._offset._y,0,this._scale._x,this._scale._y),!this._ani||this.debug)if(this.debug&&"colliders"!=this.debug&&(this.p.noFill(),this.p.stroke(0,255,0),this.p.line(0,-2,0,2),this.p.line(-2,0,2,0)),null!=this.fixture){"chain"==this._shape?this.p.stroke(this.stroke||this.color):this._stroke&&this.p.stroke(this._stroke);for(let t=this.fixtureList;t;t=t.getNext())this._drawFixture(t)}else this.p.stroke(this._stroke||120),"box"==this._shape?this.p.rect(this._offset._x,this._offset._y,this.w*this.tileSize,this.h*this.tileSize):"circle"==this._shape&&this.p.circle(this._offset._x,this._offset._y,this.d*this.tileSize);void 0!==this.text&&(this.p.textAlign(this.p.CENTER,this.p.CENTER),this.p.fill(this.textColor),this.p.textSize(this.textSize*this.tileSize),this.p.text(this.text,0,0))}_display(){let t=.5*this.p.width-this.p.world.origin.x+this.x*this.tileSize,e=.5*this.p.height-this.p.world.origin.y+this.y*this.tileSize;if("chain"!=this.shape&&this.p.camera.active&&(t+this.wthis.p.camera.bound.max.x||e+this.hthis.p.camera.bound.max.y))this._visible=null;else{this._visible=!0,t=n(t),e=n(e),this._pixelPerfect&&(this._w%2!=0&&h(t%1-.5)||(t=Math.round(t)),this._h%2!=0&&h(e%1-.5)||(e=Math.round(e)));for(let t of this.joints)t.visible?this._uid==t.spriteA._uid?(!t.spriteB._visible||this.layer<=t.spriteB.layer)&&t._display():(!t.spriteA._visible||this.layer1?(r=Math.round(r),o=Math.round(o)):e%90==0&&(r=n(r),o=n(o)),this.moveTo(r,o,i)}moveTo(e,i,s){if(null==e)return;if("number"!=typeof e){let t=e;if(t==this.p.mouse&&!this.p.mouse.active)return;if(void 0===t.x||void 0===t.y)return void console.error("sprite.moveTo ERROR: movement destination not defined, object given with no x or y properties");s=i,i=t.y,e=t.x}if(this._dest.x=this.x,this._dest.y=this.y,e==this.x?e=!1:(this._dest.x=e,e=!0),i==this.y?i=!1:(this._dest.y=i,i=!0),this._destIdx++,!e&&!i)return Promise.resolve(!0);if(this.speed&&(s??=this.speed),this.tileSize>1&&(s??=.1),s??=1,s<=0)return console.warn("sprite.move: speed should be a positive number"),Promise.resolve(!1);let r=this._dest.y-this.y,o=this._dest.x-this.x,h=s/Math.sqrt(r*r+o*o);this.vel.x=o*h,this.vel.y=r*h;let n=this.direction,a=n-.1,l=n+.1,p=s+.01,d=this._destIdx,u=Math.max(this.p.world.velocityThreshold,.25*p)/this.tileSize;return(async()=>{let s=p+p,r=p+p;do{if(d!=this._destIdx)return!1;await t.delay();let e=this.direction;if(e<=a||e>=l||Math.abs(this.vel.x)<=u&&Math.abs(this.vel.y)<=u)return!1;s=Math.abs(this.x-this._dest.x),r=Math.abs(this.y-this._dest.y)}while(e&&s>p||i&&r>p);return s2&&(i=o[0],s=o[1],e=o[2],r=o[3]),void 0!==i?t=this.angleToFace(i,s,r):t-=this.rotation,e??=.1,this.rotationSpeed=t*e}angleTo(t,e){if("object"==typeof t){let i=t;if(i==this.p.mouse&&!this.p.mouse.active)return 0;if(void 0===i.x||void 0===i.y)return console.error("sprite.angleTo ERROR: rotation destination not defined, object given with no x or y properties"),0;e=i.y,t=i.x}return this.p.atan2(e-this.y,t-this.x)}angleToFace(t,e,i){if("object"==typeof t&&(i=e,e=t.y,t=t.x),Math.abs(t-this.x)<.01&&Math.abs(e-this.y)<.01)return 0;let s=this.angleTo(t,e);i??=0,s+=i;let r=s-this.rotation%360,o=360-Math.abs(r);return o*=r<0?1:-1,Math.abs(r)2&&(i=o[0],s=o[1],e=o[2],r=o[3]),void 0!==i)t=this.angleToFace(i,s,r);else{if(t==this.rotation)return;t-=this.rotation}return this.rotate(t,e)}rotate(e,i){if(1==this.__collider)throw new x(0);if(isNaN(e))throw new x(1,[e]);if(0==e)return;let s=Math.abs(e);i??=1,i>s&&(i=s);let r=this.rotation+e,o=e>0;this.rotationSpeed=i*(o?1:-1);let h=Math.floor(s/i)-1;this._rotateIdx??=0,this._rotateIdx++;let n=this._rotateIdx;return(async()=>{if(h>1){let e=Math.abs(this.rotationSpeed)+.01;do{if(this._rotateIdx!=n)return!1;if(await t.delay(),o&&this.rotationSpeed<.01||!o&&this.rotationSpeed>-.01)return!1}while((o&&r>this.rotation||!o&&r.01&&(this.rotationSpeed=r-this.rotation,await t.delay())}else await t.delay();return this._rotateIdx==n&&(this.rotationSpeed=0,this.rotation=r,!0)})()}async changeAni(t){if(this.p.p5play.disableImages)return;if(arguments.length>1)t=[...arguments];else if(t instanceof this.p.SpriteAnimation){if(t==this._ani)return;t=[t]}else if(!Array.isArray(t)){if(t==this._ani?.name)return;t=[t]}let e,i;this._aniChangeCount++;for(let s=0;s1&&("!"==r.name[0]&&(r.name=r.name.slice(1),r.start=-1,r.end=0),"<"!=r.name[0]&&">"!=r.name[0]||(r.name=r.name.slice(1),r.flipX=!0),"^"==r.name[0]&&(r.name=r.name.slice(1),r.flipY=!0),"**"==r.name&&(e=!0,t=t.slice(0,-1)),";;"==r.name&&(i=!0,t=t.slice(0,-1)))}let s=this._aniChangeCount;do{for(let e=0;e1&&(i.start=0),await this._playSequencedAni(i)}}while(e&&s==this._aniChangeCount);1!=t.length&&i&&this._ani.stop()}_playSequencedAni(t){return new Promise((e=>{let{name:i,start:s,end:r,flipX:o,flipY:h}=t;this._changeAni(i),o&&(this._ani.scale.x=-this._ani.scale.x),h&&(this._ani.scale.y=-this._ani.scale.y),s<0&&(s=this._ani.length+s),void 0!==s&&(this._ani.frame=s),void 0!==r?this._ani.goToFrame(r):this._ani.frame==this._ani.lastFrame&&e(),this._ani._onComplete=this._ani._onChange=()=>{o&&(this._ani.scale.x=-this._ani.scale.x),h&&(this._ani.scale.y=-this._ani.scale.y),this._ani._onComplete=this._ani._onChange=null,e()}}))}changeAnimation(){return this.changeAni(...arguments)}_changeAni(t){this._ani?._onChange&&this._ani._onChange(),this._ani?.onChange&&this._ani.onChange();let e=this.animations[t];if(!e)for(let i=this.groups.length-1;i>=0;i--){if(e=this.groups[i].animations[t],e){e=e.clone();break}}if(!e)throw this.p.noLoop(),new x("Sprite.changeAnimation",[t]);this._ani=e,this._ani.name=t,this.resetAnimationsOnChange&&(this._ani.frame=0)}remove(){this.removed=!0}_remove(){this.body&&this.p.world.destroyBody(this.body),this.body=null;for(let t of this.groups)t.remove(this);0==Object.keys(this._collisions).length&&0==Object.keys(this._overlappers).length&&delete this.p.p5play.sprites[this._uid]}get removed(){return this._removed}set removed(t){t&&!this._removed&&(this.watch&&(this.mod[25]=!0),this._removed=!0,this._remove())}toString(){return"s"+this.idNum}_ensureCollide(t,e){if(!t)throw new x("Sprite.collide",2);if(!(t instanceof this.p.Sprite||t instanceof this.p.Group))throw new x("Sprite.collide",0,[t]);if(e&&"function"!=typeof e)throw new x("Sprite.collide",1,[e]);if(!1!==this._hasOverlap[t._uid]&&(this._hasOverlap[t._uid]=!1),!1!==t._hasOverlap[this._uid]&&(t._hasOverlap[this._uid]=!1,t instanceof this.p.Group))for(let e of t)e._hasOverlap[this._uid]=!1}collide(t,e){return this.collides(t,e)}collides(t,e){return this._ensureCollide(t,e),this._collides[t._uid]=e||!0,1==this._collisions[t._uid]}colliding(t,e){this._ensureCollide(t,e),this._colliding[t._uid]=e||!0;let i=this._collisions[t._uid];return i>0?i:0}collided(t,e){return this._ensureCollide(t,e),this._collided[t._uid]=e||!0,-1==this._collisions[t._uid]}_removeContactsWith(t){if(t instanceof this.p.Group)for(let e of t)this._removeContactsWith(e);else this.__removeContactsWith(t)}__removeContactsWith(t){if(this.body)for(let e=this.body.getContactList();e;e=e.next){let i=e.contact;i.m_fixtureA.m_body.sprite._uid!=t._uid&&i.m_fixtureB.m_body.sprite._uid!=t._uid||this.p.world.destroyContact(i)}}_ensureOverlap(t,e){if(!t)throw new x("Sprite.overlap",2);if(!(t instanceof this.p.Sprite||t instanceof this.p.Group))throw new x("Sprite.overlap",0,[t]);if(e&&"function"!=typeof e)throw new x("Sprite.overlap",1,[e]);if(this._hasSensors||this.addDefaultSensors(),!t._hasSensors)if(t instanceof this.p.Sprite)t.addDefaultSensors();else{for(let e of t)e._hasSensors||e.addDefaultSensors();t._hasSensors=!0}if(1!=this._hasOverlap[t._uid]&&(this._removeContactsWith(t),this._hasOverlap[t._uid]=!0),1!=t._hasOverlap[this._uid]&&(t._removeContactsWith(this),t._hasOverlap[this._uid]=!0,t instanceof this.p.Group))for(let e of t)e._hasOverlap[this._uid]=!0}overlap(t,e){return this.overlaps(t,e)}overlaps(t,e){return this._ensureOverlap(t,e),this._overlaps[t._uid]=e||!0,1==this._overlappers[t._uid]}overlapping(t,e){this._ensureOverlap(t,e),this._overlapping[t._uid]=e||!0;let i=this._overlappers[t._uid];return i>0?i:0}overlapped(t,e){return this._ensureOverlap(t,e),this._overlapped[t._uid]=e||!0,-1==this._overlappers[t._uid]}addDefaultSensors(){let t;if(this.body)for(let e=this.fixtureList;e;e=e.getNext())e.m_isSensor||(t=e.m_shape,this.body.createFixture({shape:t,isSensor:!0}));else this.addSensor();this._hasSensors=!0}},this.Sprite.propTypes={x:"Float64",y:"Float64",vel:"Vec2",rotation:"number",rotationSpeed:"number",ani:"string",autoDraw:"boolean",allowSleeping:"boolean",autoUpdate:"boolean",bounciness:"number",collider:"Uint8",color:"color",debug:"boolean",density:"number",direction:"number",drag:"number",friction:"number",h:"number",isSuperFast:"boolean",layer:"number",life:"Int32",mass:"number",mirror:"Vec2_boolean",offset:"Vec2",pixelPerfect:"boolean",removed:"boolean",rotationDrag:"number",rotationLock:"boolean",scale:"Vec2",shape:"Uint8",sleeping:"boolean",stroke:"color",strokeWeight:"number",text:"string",textColor:"color",tile:"string",tileSize:"number",visible:"boolean",w:"number"},this.Sprite.props=Object.keys(this.Sprite.propTypes),this.Sprite.propsAll=this.Sprite.props.concat(["d","diameter","dynamic","fill","height","heading","kinematic","resetAnimationsOnChange","speed","static","width"]),this.Sprite.colliderTypes=["d","s","k","n"],this.Sprite.shapeTypes=["box","circle","chain","polygon"],this.Turtle=function(e){if(t.allSprites.tileSize>1)throw new Error("Turtle can't be used when allSprites.tileSize is greater than 1.");e??=25;let i=new t.Sprite(e,e,[[e,.4*e],[-e,.4*e],[0,.8*-e]]);i.color="green",i._isTurtleSprite=!0,i._prevPos={x:i.x,y:i.y};let s=i.move;return i.move=async function(){this._prevPos.x=this.x,this._prevPos.y=this.y,await s.call(this,...arguments)},i},this.SpriteAnimation=class extends Array{constructor(){super(),this.p=t;let e,i=[...arguments];if(this.name="default",(i[0]instanceof this.p.Sprite||i[0]instanceof this.p.Group)&&(e=i[0],i=i.slice(1)),e??=this.p.allSprites,"string"!=typeof i[0]||1!=i[0].length&&i[0].includes(".")||(this.name=i[0],i=i.slice(1)),this.frame=0,this._cycles=0,this.targetFrame=-1,this.offset={x:e.anis.offset.x||0,y:e.anis.offset.y||0},this._frameDelay=e.anis.frameDelay||4,this.demoMode=e.anis.demoMode||!1,this.playing=!0,this.visible=!0,this.looping=e.anis.looping,this.looping??=!0,this.endOnFirstFrame=!1,this.frameChanged=!1,this.onComplete=this.onChange=null,this._onComplete=this._onChange=null,this.rotation=e.anis.rotation||0,this._scale=new l,0!=i.length&&"number"!=typeof i[0])if(e.addAni(this),Array.isArray(i[0])&&"string"==typeof i[0][0]&&(i=[...i[0]]),2!=i.length||"string"!=typeof i[0]||"string"!=typeof i[1]&&"number"!=typeof i[1])if("string"==typeof i[i.length-1]||i[i.length-1]instanceof p5.Image)for(let s=0;s=3)throw new x("SpriteAnimation",1);o=i[0],r=i[1]}else r=i[0];let h=this;if(o instanceof p5.Image&&1!=o.width&&1!=o.height)this.spriteSheet=o,n();else{let a;a="string"==typeof o?o:o.url,this.spriteSheet=this.p.loadImage(a,(()=>{n()}))}function n(){if(Array.isArray(r)||Array.isArray(r.frames)){if("number"!=typeof r[0]){let t=r;if(Array.isArray(r.frames)){t=r.frames,delete r.frames;for(let e=0;e=h.spriteSheet.width&&(u=0,c+=i,c>=h.spriteSheet.height&&(c=0))}}else{let p,d,u=i[0];if(isNaN(i[1])?p=i[1]:d=Number(i[1]),".png"!=u.slice(-4)||p&&".png"!=p.slice(-4))throw new x("SpriteAnimation",0,[u]);let c=0,f=0;for(let y=u.length-5;y>=0&&!isNaN(u.charAt(y));y--)c++;if(p)for(let m=p.length-5;m>=0&&!isNaN(p.charAt(m));m--)f++;let _,g=u.slice(0,-4-c);if(p&&(_=p.slice(0,-4-f)),p&&g!=_)this.push(this.p.loadImage(u)),this.push(this.p.loadImage(p));else{let w,v=parseInt(u.slice(-4-c,-4),10);if(d??=parseInt(p.slice(-4-f,-4),10),dthis.frame&&-1!==this.targetFrame?this.frame++:this.targetFrame=this.lastFrame?this.frame=0:this.frame++:this.frame{this._onComplete=()=>{this._onComplete=null,t()}}))}pause(t){this.playing=!1,t&&(this.frame=t)}stop(t){this.playing=!1,t&&(this.frame=t)}rewind(){return this.looping=!1,this.goToFrame(0)}loop(){this.looping=!0,this.playing=!0}noLoop(){this.looping=!1}nextFrame(){this.frame0?this.frame=this.frame-1:this.looping&&(this.frame=this.length-1),this.targetFrame=-1,this.playing=!1}goToFrame(t){if(!(t<0||t>=this.length))return this.targetFrame=t,this.targetFrame!==this.frame&&(this.playing=!0),new Promise((t=>{this._onComplete=()=>{this._onComplete=null,t()}}))}get lastFrame(){return this.length-1}get frameImage(){let t=this[this.frame];if(t instanceof p5.Image)return t;let{x:e,y:i,w:s,h:r}=t,o=createGraphics(s,r);return o.image(this.spriteSheet,this.offset.x,this.offset.y,s,r,e,i,s,r),o}get w(){return this.width}get width(){return this[this.frame]instanceof p5.Image?this[this.frame].width:this[this.frame]?this[this.frame].w:1}get h(){return this.height}get height(){return this[this.frame]instanceof p5.Image?this[this.frame].height:this[this.frame]?this[this.frame].h:1}get frames(){let t=[];for(let e=0;ee.#t[t],set(i){e.#t[t]=i;for(let s in e){let r=e[s];r instanceof SpriteAnimation&&(r[t]=i)}}});for(let t of s){this.#t[t]={_x:0,_y:0};for(let i of["x","y"])Object.defineProperty(this.#t[t],i,{get:()=>e.#t[t]["_"+i],set(s){e.#t[t]["_"+i]=s;for(let r in e){let o=e[r];o instanceof SpriteAnimation&&(o[t][i]=s)}}})}}},this.Group=class extends Array{constructor(...e){let i;if(e[0]instanceof t.Group&&(i=e[0],e=e.slice(1)),super(...e),this.p=t,"number"==typeof e[0])return;for(let t of this)if(!(t instanceof this.p.Sprite))throw new Error("A group can only contain sprites");if(this.idNum=this.p.p5play.groupsCreated,this._uid=this.idNum,this.p.p5play.groups[this._uid]=this,this.p.p5play.groupsCreated++,this.p.allSprites||(this._isAllSpritesGroup=!0),this.subgroups=[],i instanceof this.p.Group){i.subgroups.push(this);let t=i;do{t=this.p.p5play.groups[t.parent],t.subgroups.push(this)}while(!t._isAllSpritesGroup);this.parent=i._uid}else this._isAllSpritesGroup||(this.p.allSprites.subgroups.push(this),this.parent=0);this.animations=new this.p.SpriteAnimations,this._collides={},this._colliding={},this._collided={},this._hasOverlap={},this._overlaps={},this._overlapping={},this._overlapped={},this._collisions={},this._overlappers={};let s=this;this.Sprite=class extends this.p.Sprite{constructor(){super(s,...arguments)}},this.GroupSprite=this.Sprite,this.Group=class extends this.p.Group{constructor(){super(s,...arguments)}},this.Subgroup=this.Group,this.mouse={presses:null,pressing:null,pressed:null,holds:null,holding:null,held:null,released:null,hovers:null,hovering:null,hovered:null};for(let t in this.mouse)this.mouse[t]=function(e){for(let i of s)if(i.mouse[t](e))return!0;return!1};let r=[...this.p.Sprite.propsAll,"spriteSheet"];for(let t of r)"ani"!=t&&"velocity"!=t&&Object.defineProperty(this,t,{get(){let e=s["_"+t],i=s.length-1;if(void 0===e&&!s._isAllSpritesGroup){let r=this.p.p5play.groups[s.parent];r&&(e=r[t],i=r.length-1)}return e},set(e){s["_"+t]=e;for(let i=0;it&&(t=e._layer);return t}get ani(){return this._ani}set ani(t){this.addAni(t);for(let e of this)e.changeAni(t)}get animation(){return this._ani}set animation(t){this.ani=t}get anis(){return this.animations}get img(){return this._ani.frameImage}set img(t){this.ani=t}get image(){return this._ani.frameImage}set image(t){this.ani=t}set amount(t){let e=t-this.length,i=e>0;e=Math.abs(e);for(let t=0;t0?i:0}collided(t,e){return this._ensureCollide(t,e),this._collided[t._uid]=e||!0,-1==this._collisions[t._uid]}_removeContactsWith(t){for(let e of this)e._removeContactsWith(t)}_ensureOverlap(t,e){if(!t)throw new x("Group.overlap",2);if(!(t instanceof this.p.Sprite||t instanceof this.p.Group))throw new x("Group.overlap",0,[t]);if(e&&"function"!=typeof e)throw new x("Group.overlap",1,[e]);if(!this._hasSensors){for(let t of this)t._hasSensors||t.addDefaultSensors();this._hasSensors=!0}if(!t._hasSensors)if(t instanceof this.p.Sprite)t.addDefaultSensors();else{for(let e of t)e._hasSensors||e.addDefaultSensors();t._hasSensors=!0}if(1!=this._hasOverlap[t._uid]){this._removeContactsWith(t),this._hasOverlap[t._uid]=!0;for(let e of this)e._hasOverlap[t._uid]=!0}if(1!=t._hasOverlap[this._uid]&&(t._removeContactsWith(this),t._hasOverlap[this._uid]=!0,t instanceof this.p.Group))for(let e of t)e._hasOverlap[this._uid]=!0}overlap(t,e){return this.overlaps(t,e)}overlaps(t,e){return this._ensureOverlap(t,e),this._overlaps[t._uid]=e||!0,1==this._overlappers[t._uid]}overlapping(t,e){this._ensureOverlap(t,e),this._overlapping[t._uid]=e||!0;let i=this._overlappers[t._uid];return i>0?i:0}overlapped(t,e){return this._ensureOverlap(t,e),this._overlapped[t._uid]=e||!0,-1==this._overlappers[t._uid]}applyForce(t,e,i,s){for(let r of this)r.applyForce(t,e,i,s)}move(t,e,i){let s=[];for(let r of this)s.push(r.move(t,e,i));return Promise.all(s)}moveTo(t,e,i){if("number"!=typeof t){let s=t;if(s==this.p.mouse&&!this.p.mouse.active)return;i=e,e=s.y,t=s.x}let s=this._resetCentroid(),r=[];for(let o of this){let h={x:o.x-s.x+t,y:o.y-s.y+e};r.push(o.moveTo(h.x,h.y,i))}return Promise.all(r)}moveTowards(t,e,i){if("number"!=typeof t){let s=t;if(s==this.p.mouse&&!this.p.mouse.active)return;i=e,e=s.y,t=s.x}if(void 0!==t||void 0!==e){this._resetCentroid();for(let s of this){void 0===s.distCentroid&&this._resetDistancesFromCentroid();let r={x:s.distCentroid.x+t,y:s.distCentroid.y+e};s.moveTowards(r.x,r.y,i)}}}moveAway(t,e,i){if("number"!=typeof t){let s=t;if(s==this.p.mouse&&!this.p.mouse.active)return;i=e,e=s.y,t=s.x}if(void 0!==t||void 0!==e){this._resetCentroid();for(let s of this){void 0===s.distCentroid&&this._resetDistancesFromCentroid();let r={x:s.distCentroid.x+t,y:s.distCentroid.y+e};s.moveAway(r.x,r.y,i)}}}get(t){return console.warn("Deprecated: use group[i] instead of group.get(i)"),this[t]}push(...t){for(let e of t){if(!(e instanceof this.p.Sprite))throw new Error("you can only add sprites to a group, no "+typeof e+"s");super.push(e),this.parent&&this.p.p5play.groups[this.parent].push(e),e.groups.push(this)}return this.length}size(){return this.length}toString(){return"g"+this.idNum}cull(t,e,i,s,r){if(void 0===i){r=e,t=e=i=s=t}if(isNaN(t)||isNaN(e)||isNaN(i)||isNaN(s))throw new TypeError("The culling boundary must be defined with numbers");if(r&&"function"!=typeof r)throw new TypeError("The callback to group.cull must be a function");let o=this.p.camera.x-this.p.world.hw/this.p.camera.zoom,h=this.p.camera.y-this.p.world.hh/this.p.camera.zoom,n=-i+o,a=-t+h,l=this.p.width+s+o,p=this.p.height+e+h,d=0;for(let t=0;tl||e.y>p)&&(d++,r?r(e,d):e.remove(),e.removed&&t--))}return d}remove(t){if(void 0===t){for(;this.length>0;)this[0].remove();return}let e;if(e="number"==typeof t?t>=0?t:this.length+t:this.indexOf(t),-1!=e){let t=this[e];if(!t.removed){let e=t.groups.findIndex((t=>t._uid==this._uid));t.groups.splice(e,1)}return this.splice(e,1),t}throw new Error("Sprite not found in group")}removeAll(){this.remove()}draw(){let t=[...this];t.sort(((t,e)=>t._layer-e._layer));for(let e=0;e(t.getShape().testPoint(t.getBody().getTransform(),h)&&a.push(t),!0))),r??=this.p.allSprites;let l=[];if(a.length>0)for(let t of r)t.body&&a.includes(t.body.m_fixtureList)&&t._cameraActiveWhenDrawn==o&&l.push(t);return l}getSpriteAt(t,e,i){let s=this.getSpritesAt(t,e,i);return s.sort(((t,e)=>-1*(t._layer-e._layer))),s[0]}_beginContact(t){let e=t.m_fixtureA,i=t.m_fixtureB,s="_collisions";e.m_isSensor&&(s="_overlappers"),e=e.m_body.sprite,i=i.m_body.sprite,e[s][i._uid]=0,i[s][e._uid]=0;for(let t of i.groups)(!e[s][t._uid]||e[s][t._uid]<0)&&(t[s][e._uid]=0,e[s][t._uid]=0);for(let t of e.groups){(!i[s][t._uid]||i[s][t._uid]<0)&&(t[s][i._uid]=0,i[s][t._uid]=0);for(let e of i.groups)(!t[s][e._uid]||t[s][e._uid]<0)&&(t[s][e._uid]=0,e[s][t._uid]=0)}}_endContact(t){let e=t.m_fixtureA,i=t.m_fixtureB,s="_collisions";e.m_isSensor&&(s="_overlappers"),e=e.m_body.sprite,i=i.m_body.sprite,e[s][i._uid]=-2,i[s][e._uid]=-2;for(let t of i.groups){let i=!1;for(let r of t)if(r[s][e._uid]>=0){i=!0;break}i||(t[s][e._uid]=-2,e[s][t._uid]=-2)}for(let t of e.groups){let e=!1;for(let r of t)if(r[s][i._uid]>=0){e=!0;break}if(!e){t[s][i._uid]=-2,i[s][t._uid]=-2;for(let e of i.groups)t[s][e._uid]=-2,e[s][t._uid]=-2}}}_findContactCB(t,e,i){let s=e[t][i._uid];if(s)return s;let r=i instanceof this.p.Sprite;if(r)for(let r of i.groups)if(s=e[t][r._uid],s)return s;if(e instanceof this.p.Sprite)for(let o of e.groups){if(s=o[t][i._uid],s)return s;if(r)for(let e of i.groups)if(s=o[t][e._uid],s)return s}return!1}get allowSleeping(){return this.getAllowSleeping()}set allowSleeping(t){this.setAllowSleeping(t)}},this.Camera=class{constructor(e,i,s){this.p=t;this._pos={x:0,y:0},this.__pos={x:0,y:0},this.mouse={x:this.p.mouseX,y:this.p.mouseY},this.active=!1,this.bound={min:{x:0,y:0},max:{x:0,y:0}},this._zoomIdx=-1,this._zoom=s||1,this.x=e||0,this.y=i||0}get pos(){return this._pos}set pos(t){this.x=t.x,this.y=t.y}get position(){return this._pos}set position(t){this.x=t.x,this.y=t.y}get x(){return this._pos.x}set x(t){this._pos.x=t;let e=-t+this.p.world.hw/this._zoom;this.p.allSprites.pixelPerfect&&(e=Math.round(e)),this.__pos.x=e,this.bound.min.x=t-this.p.world.hw/this._zoom-100,this.bound.max.x=t+this.p.world.hw/this._zoom+100}get y(){return this._pos.y}set y(t){this._pos.y=t;let e=-t+this.p.world.hh/this._zoom;this.p.allSprites.pixelPerfect&&(e=Math.round(e)),this.__pos.y=e,this.bound.min.y=t-this.p.world.hh/this._zoom-100,this.bound.max.y=t+this.p.world.hh/this._zoom+100}get zoom(){return this._zoom}set zoom(t){this._zoom=t;let e=-this._pos.x+this.p.world.hw/t,i=-this._pos.y+this.p.world.hh/t;this.p.allSprites.pixelPerfect&&(e=Math.round(e),i=Math.round(i)),this.__pos.x=e,this.__pos.y=i}zoomTo(t,e){if(t==this._zoom)return Promise.resolve(!0);e??=.1;let i=Math.abs(t-this._zoom),s=Math.round(i/e);t{for(let t=0;t0&&t<=.1?t=this.p.map(t,0,.1,30,4):t<=.5?t=this.p.map(t,.1,.5,4,2.5):t<=.8?t=this.p.map(t,.5,.8,2.5,1):t<=.9?t=this.p.map(t,.8,.9,1,.5):t<=1&&(t=this.p.map(t,.9,1,.5,.2)),this._springiness=t,"wheel"==this.type?this._j.setSpringFrequencyHz(t):this._j.setFrequency(t)}get damping(){return"wheel"!=this.type?this._j.getDampingRatio():this._j.getSpringDampingRatio()}set damping(t){"wheel"==this.type?this._j.setSpringDampingRatio(t):this._j.setDampingRatio(t)}get speed(){return this._j.getJointSpeed()}set speed(t){this._j.isMotorEnabled()||this._j.enableMotor(!0),this._j.setMotorSpeed(t)}get motorSpeed(){return this._j.getMotorSpeed()}get enableMotor(){return this._j.isMotorEnabled()}set enableMotor(t){this._j.enableMotor(t)}get maxPower(){return this._j.getMaxMotorTorque()}set maxPower(t){!this._j.isMotorEnabled()&&t&&this._j.enableMotor(!0),this._j.setMaxMotorTorque(t),t||this._j.enableMotor(!1)}get power(){return this._j.getMotorTorque()}remove(){this._removed||(this.spriteA.joints.splice(this.spriteA.joints.indexOf(this),1),this.spriteB.joints.splice(this.spriteB.joints.indexOf(this),1),this.p.world.destroyJoint(this._j),this._removed=!0)}},this.GlueJoint=class extends this.Joint{constructor(t,e){super(...arguments,"glue")}},this.DistanceJoint=class extends this.Joint{constructor(t,e){super(...arguments,"distance");let s=i.DistanceJoint({},t.body,e.body,t.body.getWorldCenter(),e.body.getWorldCenter());this._createJoint(s)}_display(){this._draw(this.spriteA.x+this.offsetA.x,this.spriteA.y+this.offsetA.y,this.spriteB.x+this.offsetB.x,this.spriteB.y+this.offsetB.y),this.visible=null}},this.WheelJoint=class extends this.Joint{constructor(t,e){super(...arguments,"wheel");let s=i.WheelJoint({maxMotorTorque:1e3,frequencyHz:4,dampingRatio:.7},t.body,e.body,e.body.getWorldCenter(),new i.Vec2(0,1));this._createJoint(s),this._angle="degrees"==this.p._angleMode?90:1.5707963267948966}_display(){let t=this.spriteA.x,e=this.spriteA.y,i=this.spriteB.x+this.offsetB.x,s=this.spriteB.y+this.offsetB.y,r=this.p.tan(this.spriteA.rotation),o=this.p.tan(this._angle+this.spriteA.rotation),h=(s-e+r*t-o*i)/(r-o),n=r*(h-t)+e;this._draw(h,n,i,s),this.visible=null}get angle(){return this._angle}set angle(t){t!=this._angle&&(this._angle=t,this._j.m_localXAxisA=new i.Vec2(this.p.cos(t),this.p.sin(t)),this._j.m_localXAxisA.normalize(),this._j.m_localYAxisA=i.Vec2.crossNumVec2(1,this._j.m_localXAxisA))}},this.HingeJoint=class extends this.Joint{constructor(t,e){super(...arguments,"hinge");let s=i.RevoluteJoint({},t.body,e.body,t.body.getWorldCenter());this._createJoint(s)}_display(){this._draw(this.spriteA.x+this.offsetA.x,this.spriteA.y+this.offsetA.y),this.visible=null}get range(){return this.upperLimit-this.lowerLimit}set range(t){t/=2,this.upperLimit=t,this.lowerLimit=-t}get lowerLimit(){let t=this._j.getLowerLimit();return"radians"==this.p._angleMode?t:this.p.degrees(t)}set lowerLimit(t){this._j.isLimitEnabled()||this._j.enableLimit(!0),this.spriteA.body.setAwake(!0),this.spriteB.body.setAwake(!0),"degrees"==this.p._angleMode&&(t=this.p.radians(t)),this._j.m_lowerAngle=t}get upperLimit(){let t=this._j.getUpperLimit();return"radians"==this.p._angleMode?t:this.p.degrees(t)}set upperLimit(t){this._j.isLimitEnabled()||this._j.enableLimit(!0),this.spriteA.body.setAwake(!0),this.spriteB.body.setAwake(!0),"degrees"==this.p._angleMode&&(t=this.p.radians(t)),this._j.m_upperAngle=t}get angle(){let e=this._j.getJointAngle();return"radians"==this.p._angleMode?e:t.radians(e)}},this.RevoluteJoint=this.HingeJoint,this.SliderJoint=class extends this.Joint{constructor(t,e){super(...arguments,"slider");let s=i.PrismaticJoint({lowerTranslation:-1,upperTranslation:1,enableLimit:!0,maxMotorForce:50,motorSpeed:0,enableMotor:!0},t.body,e.body,t.body.getWorldCenter(),new i.Vec2(1,0));this._createJoint(s),this._angle=0}get angle(){return this._angle}set angle(t){t!=this._angle&&(this._angle=t,this._j.m_localXAxisA=new i.Vec2(this.p.cos(t),this.p.sin(t)),this._j.m_localXAxisA.normalize(),this._j.m_localYAxisA=i.Vec2.crossNumVec2(1,this._j.m_localXAxisA))}get range(){return this.upperLimit-this.lowerLimit}set range(t){t/=2,this.upperLimit=t,this.lowerLimit=-t}get lowerLimit(){return this._j.getLowerLimit()/this.spriteA.tileSize*s}set lowerLimit(t){this._j.isLimitEnabled()||this._j.enableLimit(!0),t=t*this.spriteA.tileSize/s,this._j.setLimits(t,this._j.getUpperLimit())}get upperLimit(){return this._j.getUpperLimit()/this.spriteA.tileSize*s}set upperLimit(t){this._j.isLimitEnabled()||this._j.enableLimit(!0),t=t*this.spriteA.tileSize/s,this._j.setLimits(this._j.getLowerLimit(),t)}},this.PrismaticJoint=this.SliderJoint,this.RopeJoint=class extends this.Joint{constructor(t,e){super(...arguments,"rope");let s=i.RopeJoint({maxLength:1},t.body,e.body,t.body.getWorldCenter(),e.body.getWorldCenter());this._createJoint(s)}get maxLength(){return this._j.getMaxLength()}set maxLength(t){this._j.setMaxLength(t)}};class l{constructor(){let t=this;Object.defineProperties(this,{x:{get:()=>t._x,set(e){e!=t._x&&(t._x=e,t._avg=.5*(t._x+t._y))},configurable:!0,enumerable:!0},y:{get:()=>t._y,set(e){e!=t._y&&(t._y=e,t._avg=.5*(t._x+t._y))},configurable:!0,enumerable:!0},_x:{value:1,enumerable:!1,writable:!0},_y:{value:1,enumerable:!1,writable:!0},_avg:{value:1,enumerable:!1,writable:!0}})}valueOf(){return this._avg}}const p=function(){let t=new Float32Array(1),e=new Int32Array(t.buffer);return function(i){t[0]=i;let s=e[0],r=s>>16&32768,o=s>>12&2047,h=s>>23&255;return h<103?r:h>142?(r|=31744,r|=(255==h?0:1)&&8388607&s,r):h<113?(o|=2048,r|=(o>>114-h)+(o>>113-h&1),r):(r|=h-112<<10|o>>1,r+=1&o,r)}}();function d(t){return!/^(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*\s*(?:(?:(?:async\s(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*\s*)?function|class)(?:\s|(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*)|(?:[_$\w][\w0-9_$]*\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*\()|(?:\[\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*(?:(?:['][^']+['])|(?:["][^"]+["]))\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*\]\())/.test(t.toString())}function u(t,e){return"triangle"==e?t=[t,-120,3]:"square"==e?t=[t,-90,4]:"pentagon"==e?t=[t,-72,5]:"hexagon"==e?t=[t,-60,6]:"septagon"==e?t=[t,-51.4285714286,7]:"octagon"==e?t=[t,-45,8]:"enneagon"==e?t=[t,-40,9]:"decagon"==e?t=[t,-36,10]:"hendecagon"==e?t=[t,-32.7272727273,11]:"dodecagon"==e&&(t=[t,-30,12]),t}this.Netcode=class{constructor(){this.typeSizes={boolean:1,Uint8:1,Vec2_boolean:1,Float16:2,number:2,color:4,Float32:4,Int32:4,Vec2:4,Float64:8},this.player=0}connect(){}disconnect(){}spriteToBinary(e){const i=t.Sprite.props;let s=3;for(let r=0;ro.setUint16(t,p(e)),o.setUint16(0,e._uid);let h=2;for(let s=0;sfunction(t){let e=(31744&t)>>10,i=1023&t;return(t>>15?-1:1)*(e?31===e?i?NaN:1/0:Math.pow(2,e-15)*(1+i/1024):i/1024*6103515625e-14)}(s.getUint16(t));let r=i||0,o=s.getUint16(r);r+=2;let h=t.p5play.sprites[o]||new t.Sprite;for(;r!==s.byteLength;){const e=s.getUint8(r);if(255===e)break;r+=1;const i=t.Sprite.props[e],o=t.Sprite.propTypes[i];if("boolean"===o)h[i]=0!==s.getUint8(r);else if("number"==o||"Float16"===o)h[i]=s.getFloat16(r);else if("Float32"===o)h[i]=s.getFloat32(r);else if("Float64"===o)h[i]=s.getFloat64(r);else{if("string"===o){const t=s.getUint16(r);r+=2;const e=new Uint8Array(s.buffer,r,t);h[i]=(new TextDecoder).decode(e),r+=t;continue}if("color"===o){const t=s.getUint8(r),e=s.getUint8(r+1),o=s.getUint8(r+2),n=s.getUint8(r+3);h[i]=color(t,e,o,n)}else if("Vec2"===o){const t=s.getFloat16(r),e=s.getFloat16(r+2);h[i]={x:t,y:e}}else if("Vec2_boolean"===o){const t=s.getUint8(r);h[i]={x:1==(1&t),y:2==(2&t)}}else if("Uint8"===o){let e=s.getUint8(r);"collider"===i?h.collider=t.Sprite.colliderTypes[e]:"shape"===i?h.shape=t.Sprite.shapeTypes[e]:h[i]=e}else"Int32"===o&&(h[i]=s.getInt32(r))}r+=this.typeSizes[o]}return s.offset=r,h}inputToJSON(){}},this.netcode=new this.Netcode,this.updateSprites=function(){1==this.frameCount&&console.warn("updateSprites() is deprecated, use world.step() instead."),this.world.step(...arguments),this.allSprites.update()},this.p5play.palettes??=[{a:"aqua",b:"black",c:"crimson",d:"dark blue",f:"fuchsia",g:"green",h:"hot pink",i:"blue",k:"black",l:"lavender",m:"magenta",n:"brown",o:"orange",p:"pink",r:"red",s:"sky blue",t:"turquoise",u:"blue",v:"violet",w:"white",y:"yellow"}],this.colorPal=(e,i)=>{if(e instanceof p5.Color)return e;let s;return"number"==typeof i&&(i=t.p5play.palettes[i]),i??=t.p5play.palettes[0],i&&(s=i[e]),""===s||"."===e||" "===e?t.color(0,0,0,0):t.color(s||e)},this.spriteArt=(e,i,s)=>{i??=1,"number"==typeof s&&(s=t.p5play.palettes[s]),s??=t.p5play.palettes[0];let r=e;"string"==typeof e&&(r=(e=(e=(e=e.trim()).replace(/\r*\n\t+/g,"\n")).replace(/\s+$/g,"")).split("\n"));let o=0;for(let t of r)t.length>o&&(o=t.length);let h=r.length,n=t.createImage(o*i,h*i);n.loadPixels();for(let t=0;tnew Promise(t?e=>{setTimeout(e,t)}:requestAnimationFrame),this.sleep=t=>this.delay(t),this.play=t=>{if(!t.play)throw new Error("Tried to play a sound but the sound is not a sound object: "+t);return new Promise(((e,i)=>{t.play(),t.onended((()=>e()))}))},this.p5play.playIntro=async function(){if(document.getElementById("p5play-intro"))return;t._incrementPreload();let e=document.createElement("div");e.id="p5play-intro",e.style="position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 1000; background-color: black;";let i=document.createElement("img");i.src="https://p5play.org/v3/made_with_p5play.png",i.style="position: absolute; top: 50%; left: 50%; width: 40vh; height: 20vh; margin-left: -20vh; margin-top: -10vh; z-index: 1000; opacity: 0; transition: opacity 0.1s ease-in-out;",document.body.append(e),e.append(i),await t.delay(100),i.style.opacity="1",i.style.transition="scale 2s, opacity 0.4s ease-in-out",i.style.scale="1.1",await t.delay(1200),i.style.opacity="0",await t.delay(400),e.style.display="none",e.remove(),document.getElementById("p5play-intro")?.remove(),t._decrementPreload()};{let t=location.hostname;switch(t){case"":case"127.0.0.1":case"localhost":case"p5play.org":case"openprocessing.org":case"preview.openprocessing.org":case"editor.p5js.org":case"codepen.io":case"cdpn.io":case"glitch.com":case"replit.com":case"stackblitz.com":case"jsfiddle.net":break;default:if(t.endsWith("stackblitz.io")||t.endsWith("glitch.me")||t.endsWith("repl.co")||location.origin.endsWith("preview.p5js.org"))break;this.p5play.playIntro()}}let c=p5.disableFriendlyErrors;p5.disableFriendlyErrors=!0,this.canvas=this.canvas;const f=this.createCanvas;this.createCanvas=function(){let e,i,s,r,o=[...arguments],h=!1,n=!1;if("string"==typeof o[0]&&(o[0].includes(":")?s=o[0].split(":"):(o[2]=o[0],o[0]=void 0),"fullscreen"==o[1]&&(h=!0)),o[0]?"number"==typeof o[0]&&"number"!=typeof o[1]&&(o[2]=o[1],o[1]=o[0]):(o[0]=window.innerWidth,o[1]=window.innerHeight,h=!0),"string"==typeof o[2]&&(o[2]=o[2].toLowerCase(),"p2d"!=o[2]&&"webgl"!=o[2]&&(o[2]=o[2].split(" ")),"pixelated"==o[2][0]&&(n=!0,o[2][1]?r=Number(o[2][1].slice(1)):h=!0,s=[o[0],o[1]]),"fullscreen"==o[2][0]&&(h=!0)),s){let t=Number(s[0]),h=Number(s[1]);r?(e=t*r,i=h*r):(e=window.innerWidth,i=window.innerWidth*(h/t),i>window.innerHeight&&(e=window.innerHeight*(t/h),i=window.innerHeight)),e=Math.round(e),i=Math.round(i),n||(o[0]=e,o[1]=i)}o.length<3&&(o[2]="p2d");let a=f.call(t,...o);this.canvas.tabIndex=0,this.canvas.w=o[0],this.canvas.h=o[1],this.canvas.addEventListener("keydown",(function(t){" "!=t.key&&"/"!=t.key&&"ArrowUp"!=t.key&&"ArrowDown"!=t.key&&"ArrowLeft"!=t.key&&"ArrowRight"!=t.key||t.preventDefault()})),this.canvas.addEventListener("mouseover",(()=>{this.mouse.isOnCanvas=!0,this.mouse.active=!0})),this.canvas.addEventListener("mouseleave",(()=>{this.mouse.isOnCanvas=!1})),this.canvas.addEventListener("touchstart",(t=>{t.preventDefault()})),this.world.resize(),c||(p5.disableFriendlyErrors=!1);let l="\ncanvas { \n\toutline: none;\n\t-webkit-touch-callout: none;\n\t-webkit-text-size-adjust: none;\n\t-webkit-user-select: none;\n\toverscroll-behavior: none;\n}\nmain{\n\toverscroll-behavior: none;\n}";h&&(l="html,\nbody,\n"+l,l+="\nhtml, body {\n\tmargin: 0;\n\tpadding: 0;\n\toverflow: hidden;\n\theight: 100%;\n}\nmain {\n\tmargin: auto;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-content: center;\n\tjustify-content: center;\n\theight: 100%;\n}"),n&&(l+=`\ncanvas {\n\timage-rendering: pixelated;\n\twidth: ${e}px!important;\n\theight: ${i}px!important;\n}`);let p=document.createElement("style");p.innerHTML=l,document.head.appendChild(p),n&&(t.pixelDensity(1),t.noSmooth());let d=navigator.userAgent.indexOf("iPhone OS");if(d>-1){let e=navigator.userAgent.substring(d+10,d+12);this.p5play.version=e,e<16&&t.pixelDensity(1),this.p5play.os.platform="iOS",this.p5play.os.version=e}else void 0!==navigator.userAgentData&&(this.p5play.os.platform=navigator.userAgentData.platform);return a},this.Canvas=function(){return t.createCanvas(...arguments)};const _=this.background;this.background=function(){let t,e=arguments;1==e.length&&("string"==typeof e[0]||e[0]instanceof p5.Color)&&(t=this.colorPal(e[0])),void 0!==t?_.call(this,t):_.call(this,...e)};const g=this.fill;this.fill=function(){let t,e=arguments;1==e.length&&(t=this.colorPal(e[0])),void 0!==t?g.call(this,t):g.call(this,...e)};const y=this.stroke;this.stroke=function(){let t,e=arguments;1==e.length&&(t=this.colorPal(e[0])),void 0!==t?y.call(this,t):y.call(this,...e)},this.p5play.images={onLoad:t=>{}},this.p5play.disableImages=!1;const m=this.loadImage;this.loadImg=this.loadImage=function(){if(this.p5play.disableImages)return;let e,i=arguments,s=i[0],r=t.p5play.images[s];if("function"==typeof i[i.length-1]&&(e=i[i.length-1]),r)return 1==r.width&&1==r.height||!r.pixels.length?e?(r.cbs.push(e),r.calls++):t._decrementPreload():(e&&e(),t._decrementPreload()),r;return r=m.call(t,s,(e=>{e.w=e.width,e.h=e.height;for(let t of e.cbs)t(e);for(let i=1;ii[e])),o+=h,p5._friendlyError(o,t)}}this.allSprites=new this.Group,this.world=new this.World,this.camera=new this.Camera,this.InputDevice=class{constructor(){this.holdThreshold=12}init(t){for(let e of t)this[e]=0}ac(t){return t}presses(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),1==this[t]||-2==this[t]}pressing(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),-2==this[t]?1:this[t]>0?this[t]:0}pressed(t){return this.released(t)}holds(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),this[t]==this.holdThreshold}holding(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),this[t]>=this.holdThreshold?this[t]:0}held(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),-3==this[t]}released(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),this[t]<=-1}releases(t){return this.released(t)}},this._Mouse=class extends this.InputDevice{constructor(){super();let t=this;this._position={get x(){return t.x},set x(e){t.x=e},get y(){return t.y},set y(e){t.y=e}};this.init(["x","y","left","center","right"]),this.default="left",this.drag={left:0,center:0,right:0},this.isOnCanvas=!1,this.active=!1,this.x,this.y}get pos(){return this._position}get position(){return this._position}ac(t){return t=t.slice(0,4)?"left":"right"==t.slice(0,5)?"right":"middle"==t.slice(0,6)?"center":t.toLowerCase()}drags(t){return t??=this.default,1==this.drag[t]}dragging(t){return t??=this.default,this.drag[t]>0?this.drag[t]:0}dragged(t){return t??=this.default,-1==this.drag[t]}},this.mouse=new this._Mouse,this._SpriteMouse=class extends this._Mouse{constructor(){super(),this.hover=0}hovers(){return 1==this.hover}hovering(){return this.hover>0?this.hover:0}hovered(){return-1==this.hover}};const v=function(t){if(this.mouse[t]++,this.mouse.active=!0,this.world.mouseSprites.length){let e=this.world.mouseSprite;e&&(e.mouse[t]=0,e.mouse.drag[t]=0),e=this.world.mouseSprites[0],e.mouse[t]=1,this.world.mouseSprite=e}},b=this._onmousedown;this._onmousedown=function(t){let e="left";1===t.button?e="center":2===t.button&&(e="right"),v.call(this,e),b.call(this,t)};const S=this._ontouchstart;this._ontouchstart=function(t){v.call(this,"left"),S.call(this,t)};const A=function(t){let e=this.mouse;if(e[t]>0&&e.drag[t]<=0){e.drag[t]=1,e._isDragging=!0;let i=this.world.mouseSprite?.mouse;i&&(i.drag[t]=1,i._isDragging=!0)}},C=this._onmousemove;this._onmousemove=function(t){let e="left";1===t.button?e="center":2===t.button&&(e="right"),A.call(this,e),C.call(this,t)};const k=function(t){let e=this.mouse;e[t]>=e.holdThreshold?e[t]=-3:e[t]>1?e[t]=-1:e[t]=-2;let i=this.world.mouseSprite?.mouse;i&&(i.hover>1?(i[t]>=this.mouse.holdThreshold?i[t]=-3:i[t]>1?i[t]=-1:i[t]=-2,i.drag[t]>0&&(i.drag[t]=i[t])):(i[t]=0,i.drag[t]=0))},z=this._onmouseup;this._onmouseup=function(t){let e="left";1===t.button?e="center":2===t.button&&(e="right"),k.call(this,e),z.call(this,t)};const M=this._ontouchend;if(this._ontouchend=function(t){k.call(this,"left"),M.call(this,t)},this._KeyBoard=class extends this.InputDevice{constructor(){super(),this.default=" "}ac(t){if(1==t.length)return t.toLowerCase();if(!isNaN(t)){if(38==t)return"ArrowUp";if(40==t)return"ArrowDown";if(37==t)return"ArrowLeft";if(39==t)return"ArrowRight";if(t<10)return t+"";throw new Error('Use key names with the keyboard input functions, not key codes! If you are trying to detect if the user pressed a number key make it a string. For example: "5"')}return"space"==t||"spacebar"==t?" ":t[0].toUpperCase()+t.slice(1).toLowerCase()}get space(){return this[" "]}get spacebar(){return this[" "]}},this.kb=new this._KeyBoard,delete this._KeyBoard,this.keyboard=this.kb,navigator.keyboard){const t=navigator.keyboard;window==window.top?t.getLayoutMap().then((t=>{"w"!=t.get("KeyW")&&(this.p5play.standardizeKeyboard=!0)})):this.p5play.standardizeKeyboard=!0}else this.p5play.standardizeKeyboard=!0;function T(t){let e=t.code;return 4==e.length&&"Key"==e.slice(0,3)?e[3].toLowerCase():t.key}this.keyIsDown=function(t){throw new Error("The p5.js keyIsDown function is outdated and can't be used in p5play. Trust me, you'll see that the p5play kb.pressing function is much better. It uses key name strings that are easier to write and easier to read! https://p5play.org/learn/input_devices.html The p5.js keyIsDown function relies on key codes and custom constants for key codes, which are not only hard to remember but were also deprecated in the JavaScript language standards over six years ago and shouldn't be used in new projects. More info: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode")};let j={w:"up",s:"down",a:"left",d:"right",ArrowUp:"up",ArrowDown:"down",ArrowLeft:"left",ArrowRight:"right",i:"up2",k:"down2",j:"left2",l:"right2"};const F=this._onkeydown;this._onkeydown=function(t){let e=t.key;this.p5play.standardizeKeyboard&&(e=T(t));let i=[e],s=j[e];s&&i.push(s);for(let t of i)(!this.kb[t]||this.kb[t]<0)&&(this.kb[t]=1);F.call(this,t)};const D=this._onkeyup;this._onkeyup=function(t){let e=t.key;this.p5play.standardizeKeyboard&&(e=T(t));let i=[e],s=j[e];s&&i.push(s);for(let t of i)this.kb[t]>=this.kb.holdThreshold?this.kb[t]=-3:this.kb[t]>1?this.kb[t]=-1:this.kb[t]=-2;D.call(this,t)},this._Contro=class extends this.InputDevice{constructor(t){super();this.init(["a","b","x","y","l","r","lt","rt","select","start","up","down","left","right","leftTrigger","rightTrigger"]),this.leftStick={x:0,y:0,btn:0},this.rightStick={x:0,y:0,btn:0},this._btns={a:0,b:1,x:2,y:3,l:4,r:5,lt:6,rt:7,select:8,start:9,leftStickButton:10,rightStickButton:11,up:12,down:13,left:14,right:15},this._axes={leftStick:{x:0,y:1},rightStick:{x:2,y:3},leftTrigger:4,rightTrigger:5},t.id.includes("GuliKit")&&(this._btns.a=1,this._btns.b=0,this._btns.x=3,this._btns.y=2),e(t),this.gamepad=t,this.id=t.id}ac(t){return t.toLowerCase()}_update(){if(this.gamepad=navigator.getGamepads()[this.gamepad.index],!this.gamepad)return;let t=this.gamepad;for(let e in this._btns){let i=this._btns[e];t.buttons[i].pressed?this[e]++:this[e]=0}return this.leftStick.x=t.axes[this._axes.leftStick.x],this.leftStick.y=t.axes[this._axes.leftStick.y],this.rightStick.x=t.axes[this._axes.rightStick.x],this.rightStick.y=t.axes[this._axes.rightStick.y],void 0!==t.axes[this._axes.leftTrigger]?(this.leftTrigger=t.axes[this._axes.leftTrigger],this.rightTrigger=t.axes[this._axes.rightTrigger]):(this.leftTrigger=t.buttons[this._btns.lt].value,this.rightTrigger=t.buttons[this._btns.rt].value),!0}},this._Contros=class extends Array{constructor(){super();let t=this;window.addEventListener("gamepadconnected",(e=>{t._addContro(e.gamepad)})),window.addEventListener("gamepaddisconnected",(e=>{t._removeContro(e.gamepad)})),this.default="a";let e=["presses","pressing","pressed","holds","holding","held","released"];for(let t of e)this[t]=e=>{if(this[0])return this[0][t](e)};let i=["a","b","x","y","l","r","lt","rt","select","start","leftStickButton","rightStickButton","up","down","left","right"];for(let e of i)Object.defineProperty(this,e,{get:()=>t[0]?t[0][e]:0});let s=["leftStick","rightStick"];for(let e of s){this[e]={};for(let i of["x","y"])Object.defineProperty(this[e],i,{get:()=>t[0]?t[0][e][i]:0})}if(!navigator?.getGamepads)return;let r=navigator.getGamepads();for(let t of r)t&&this._addContro(t)}_addContro(i){i&&(e("controller "+this.length+" connected: "+i.id),this.push(new t._Contro(i)))}_removeContro(t){if(t){e("controller "+this.length+" disconnected: "+t.id);for(let e=0;ethis.p5play._fps,this.loadAds=t=>{t??={},void 0!==window.webkit&&webkit.messageHandlers.loadAds.postMessage(JSON.stringify(t))},this.showAd=t=>{t&&(t=t.toLowerCase()),t??="interstitial",void 0!==window.webkit&&confirm("p5play:"+t)}})),p5.prototype.registerMethod("pre",(function(){this.p5play._fps&&(this.p5play._preDrawFrameTime=performance.now()),1==this.frameCount&&(this.camera.x||(this.camera.x=this.world.hw),this.camera.y||(this.camera.y=this.world.hh),this.camera.init=!0,this.canvas.addEventListener("contextmenu",(t=>t.preventDefault()))),this.mouse.x=(this.mouseX-this.world.hw)/this.camera.zoom+this.camera.x,this.mouse.y=(this.mouseY-this.world.hh)/this.camera.zoom+this.camera.y,this.camera.mouse.x=this.mouseX,this.camera.mouse.y=this.mouseY,this.contro._update()})),p5.prototype.registerMethod("post",(function(){this.p5play._inPostDraw=!0,this.allSprites.autoCull&&this.allSprites.cull(1e4),this.allSprites._autoDraw&&(this.camera.on(),this.allSprites.draw(),this.camera.off()),this.allSprites._autoDraw??=!0,this.world.autoStep&&this.world.step(),this.world.autoStep??=!0,this.allSprites._autoUpdate&&this.allSprites.update(),this.allSprites._autoUpdate??=!0;for(let t of this.allSprites)t.autoDraw??=!0,t.autoUpdate??=!0;for(let t in this.kb)"holdThreshold"!=t&&(this.kb[t]<0?this.kb[t]=0:this.kb[t]>0&&this.kb[t]++);let t=this.mouse,e=this.world.mouseSprite?.mouse;for(let i of["left","center","right"])t[i]<0?t[i]=0:t[i]>0&&t[i]++,e&&(e[i]=t[i]);if(this.world.mouseTracking){let i=this.world.getSpritesAt(t.x,t.y);i.sort(((t,e)=>-1*(t._layer-e._layer)));let s=this.world.getSpritesAt(this.camera.mouse.x,this.camera.mouse.y,this.allSprites,!1);s.sort(((t,e)=>-1*(t._layer-e._layer))),i=i.concat(s);for(let t=0;t0?e.mouse.hover=-1:e.mouse.hover<0&&(e.mouse.hover=0):e.mouse.hover++}let r=this.world.mouseSprite;if(t.left<=0&&t.center<=0&&t.right<=0)r=null,this.world.mouseSprite=null;else for(let i of["left","center","right"])t.drag[i]<0?t.drag[i]=0:t.drag[i]>0&&t.drag[i]++,e&&(e.drag[i]=t.drag[i],e.x=r.x-t.x,e.y=r.y-t.y);for(let t of this.world.mouseSprites)if(!(e?._isDragging&&t==r||i.includes(t))){let e=t.mouse;e.hover=-1,e.left=e.center=e.right=0}this.world.mouseSprites=i}this.camera.off(),this.p5play._fps&&(this.p5play._postDrawFrameTime=performance.now(),this.p5play._fps=Math.round(1e3/(this.p5play._postDrawFrameTime-this.p5play._preDrawFrameTime))||1),this.p5play._inPostDraw=!1})); +p5.prototype.registerMethod("init",(function(){if(void 0===window.planck)throw"planck.js must be loaded before p5play";const t=this,e=console.log;this.log=console.log;const i=planck,s=60;this.p5play??={},this.p5play.os??={},this.p5play.context??="web",this.p5play.standardizeKeyboard??=!1,this.p5play.sprites={},this.p5play.groups={},this.p5play.groupsCreated=0,this.p5play.spritesCreated=0,this.angleMode("degrees");const r=(t,e,r)=>new i.Vec2(t*r/s,e*r/s),o=(t,e,r)=>new i.Vec2(t/r*s,e/r*s),h=t=>Math.abs(t)<=i.Settings.linearSlop,n=t=>Math.abs(t-Math.round(t))<=i.Settings.linearSlop?Math.round(t):t,a={_collisions:["_collides","_colliding","_collided"],_overlappers:["_overlaps","_overlapping","_overlapped"]};this.Sprite=class{constructor(e,r,o,h,a){this.p=t,this.idNum,this.watch,this.mod=[];let p,c,f=[...arguments];if(void 0!==f[0]&&f[0]instanceof this.p.Group&&(p=f[0],f=f.slice(1)),f.length||(this._noArgs=!0),void 0!==f[0]&&isNaN(f[0])&&("string"==typeof f[0]||f[0]instanceof this.p.SpriteAnimation||f[0]instanceof p5.Image)&&(c=f[0],f=f.slice(1)),1==f.length&&"number"==typeof f[0])throw new x("Sprite",0,[f[0]]);if(e=f[0],r=f[1],o=f[2],h=f[3],a=f[4],this._originMode="center",Array.isArray(e)&&(e=void 0,r=void 0,o=f[0],h=f[1],a=f[2]),Array.isArray(o)||"string"==typeof h){if(isNaN(o)||(o=Number(o)),"number"!=typeof o&&Array.isArray(o[0])&&(this._originMode="start"),void 0!==h){if(Array.isArray(h))throw new x("Sprite",1,[`[[${o}], [${h}]]`]);!function(t){let e=t.slice(0,2);return"d"==t||"s"==t||"k"==t||"n"==t||"dy"==e||"st"==e||"ki"==e||"no"==e}(h)?o=u(o,h):a=h,h=void 0}}else isNaN(o)&&(a=o,o=void 0);if(this.idNum=this.p.p5play.spritesCreated,this._uid=1e3+this.idNum,this.p.p5play.sprites[this._uid]=this,this.p.p5play.spritesCreated++,this.groups=[],this.p.allSprites.push(this),this.animations=new this.p.SpriteAnimations,this.joints=[],this.removed=!1,p){if(p.push(this),!c)for(let t in p.animations){c=t;break}}else p=this.p.allSprites;p.dynamic&&(a??="dynamic"),p.kinematic&&(a??="kinematic"),p.static&&(a??="static"),a??=p.collider,this._shape=p.shape,this._life=2147483647,this._visible=!0,this._aniChangeCount=0,this._collides={},this._colliding={},this._collided={},this._hasOverlap={},this._overlaps={},this._overlapping={},this._overlapped={},this._collisions={},this._overlappers={},this.tileSize=p.tileSize||1;let _=this;if(this._position={x:0,y:0},this._pos=t.createVector.call(t),Object.defineProperty(this._pos,"x",{get(){if(!_.body)return _._position.x;let t=_.body.getPosition().x/_.tileSize*s;return n(t)},set(t){if(_.body){let e=new i.Vec2(t*_.tileSize/s,_.body.getPosition().y);_.body.setPosition(e)}_._position.x=t}}),Object.defineProperty(this._pos,"y",{get(){if(!_.body)return _._position.y;let t=_.body.getPosition().y/_.tileSize*s;return n(t)},set(t){if(_.body){let e=new i.Vec2(_.body.getPosition().x,t*_.tileSize/s);_.body.setPosition(e)}_._position.y=t}}),this._velocity={x:0,y:0},this._vel=t.createVector.call(t),Object.defineProperties(this._vel,{x:{get(){let t;return t=_.body?_.body.getLinearVelocity().x:_._velocity.x,n(t/_.tileSize)},set(t){t*=_.tileSize,_.body?_.body.setLinearVelocity(new i.Vec2(t,_.body.getLinearVelocity().y)):_._velocity.x=t}},y:{get(){let t;return t=_.body?_.body.getLinearVelocity().y:_._velocity.y,n(t/_.tileSize)},set(t){t*=_.tileSize,_.body?_.body.setLinearVelocity(new i.Vec2(_.body.getLinearVelocity().x,t)):_._velocity.y=t}}}),this._mirror={_x:1,_y:1,get x(){return this._x<0},set x(t){_.watch&&(_.mod[22]=!0),this._x=t?-1:1},get y(){return this._y<0},set y(t){_.watch&&(_.mod[22]=!0),this._y=t?-1:1}},this._heading="right",this._layer=p._layer,this._layer??=this.p.allSprites._getTopLayer()+1,a??=p.collider,a&&"string"==typeof a||(a="dynamic"),this.collider=a,e??=p.x,void 0===e&&(e=this.p.width/this.p.allSprites.tileSize/2,this._vertexMode=!0),r??=p.y,void 0===r&&(r=this.p.height/this.p.allSprites.tileSize/2),o??=p.w||p.width||p.d||p.diameter,h??=p.h||p.height,"function"==typeof e&&(e=e(p.length-1)),"function"==typeof r&&(r=r(p.length-1)),this.x=e,this.y=r,c){c instanceof p5.Image?this.addAni(c):"string"==typeof c?this._changeAni(c):this._ani=c.clone();let t=this.tileSize;o||1==this._ani.w&&1==this._ani.h||(o=this._ani.w/t,"circle"!=this.shape&&(h=this._ani.h/t))}if(this.mouse=new this.p._SpriteMouse,"none"!=this.collider)this._vertexMode?this.addCollider(o,h):this.addCollider(0,0,o,h);else{if(this.w=o||(this.tileSize>1?1:50),this.h=h||this.w,Array.isArray(o))throw new Error('Cannot set the collider type of a sprite with a polygon or chain shape to "none". Try having the sprite overlap with other sprites instead.');this._shape=void 0!==o&&void 0===h?"circle":"box"}this._scale=new l,Object.defineProperty(this._scale,"x",{get(){return this._x},set(t){if(t==this._x)return;_.watch&&(_.mod[28]=!0);let e=t/this._x;_._w*=e,_._hw*=e,_._resizeCollider({x:e,y:1}),this._x=t,this._avg=.5*(this._x+this._y)}}),Object.defineProperty(this._scale,"y",{get(){return this._y},set(t){if(t==this._y)return;_.watch&&(_.mod[28]=!0);let e=t/this._y;_._h&&(this._h*=e,this._hh*=e),_._resizeCollider({x:1,y:e}),this._y=t,this._avg=.5*(this._x+this._y)}}),this._offset={_x:0,_y:0,get x(){return this._x},set x(t){t!=this._x&&(_.watch&&(_.mod[23]=!0),_._offsetCenterBy(t-this._x,0))},get y(){return this._y},set y(t){t!=this._y&&(_.watch&&(_.mod[23]=!0),_._offsetCenterBy(0,t-this._y))}},this.prevPos={x:e,y:r},this.prevRotation=0,this._dest={x:e,y:r},this._destIdx=0,this.drag=0,this.debug=!1,this._shift={};let g=p.vel.x||0,y=p.vel.y||0;"function"==typeof g&&(g=g(p.length-1)),"function"==typeof y&&(y=y(p.length-1)),this.vel.x=g,this.vel.y=y;let m=["ani","collider","vel","x","y"];for(let t of this.p.Sprite.propsAll){if(m.includes(t))continue;let e=p[t];void 0!==e&&("function"==typeof e&&d(e)&&(e=e(p.length-1)),this[t]="object"==typeof e?Object.assign({},e):e)}m=["add","animation","animations","autoCull","contains","GroupSprite","Group","idNum","length","mod","mouse","p","parent","Sprite","Subgroup","subgroups","velocity"];for(let t=0;t1?1:50,o??=s),"box"!=a&&"circle"!=a||(l=r(s-.08,o-.08,this.tileSize)),"box"==a)p=i.Box(l.x/2,l.y/2,r(t,e,this.tileSize),0);else if("circle"==a)p=i.Circle(r(t,e,this.tileSize),l.x/2);else if(n){let c,f,_=[{x:0,y:0}],g={x:0,y:0},y={x:0,y:0},m={x:0,y:0},w=Array.isArray(n[0]);function x(){g.xm.x&&(m.x=g.x),g.y>m.y&&(m.y=g.y)}if(w){this._vertexMode&&(c=n[0][0],f=n[0][1],this.body?(c=this.x-this._relativeOrigin.x,f=this.y-this._relativeOrigin.y,_.pop()):(this.x=c,this.y=f));for(let b=0;b0?1:-1;S=Math.abs(S);let C=0;for(let k=0;ki.Settings.maxPolygonVertices||"chain"==this._shape)&&(a="chain"),"polygon"==a?p=i.Polygon(_):"chain"==a&&(p=i.Chain(_,!1))}return this._shape||(this._shape=a),this._w=s,this._hw=.5*s,"circle"==this._shape?this._diameter=s:(this._h=o,this._hh=.5*o),p}removeColliders(){this._collides={},this._colliding={},this._collided={},this._removeFixtures(!1)}removeSensors(){this._hasOverlap={},this._overlaps={},this._overlapping={},this._overlapped={},this._removeFixtures(!0)}_removeFixtures(t){let e;for(let i=this.fixtureList;i;i=i.getNext())if(void 0===t||i.m_isSensor==t){let t=i.m_next;i.destroyProxies(this.p.world.m_broadPhase),e?e.m_next=t:this.body.m_fixtureList=t}else e=i}_offsetCenterBy(t,e){if(!t&&!e)return;if(this._offset._x+=t,this._offset._y+=e,!this.body)return;let i=r(t,e,this.tileSize);for(let t=this.body.m_fixtureList;t;t=t.m_next){let e=t.m_shape;if("circle"!=e.m_type){let t=e.m_vertices;for(let e of t)e.x+=i.x,e.y+=i.y}else e.m_p.x+=i.x,e.m_p.y+=i.y}}_cloneBodyProps(){let t={},e=["bounciness","density","drag","friction","heading","isSuperFast","rotation","rotationDrag","rotationLock","rotationSpeed","scale","vel","x","y"];this._massUndefinedByUser&&this._dimensionsUndefinedByUser||e.push("mass");for(let i of e)"object"==typeof this[i]?t[i]=Object.assign({},this[i]):t[i]=this[i];return t}get animation(){return this._ani}set animation(t){this.changeAni(t)}get ani(){return this._ani}set ani(t){this.changeAni(t)}get anis(){return this.animations}get autoDraw(){return this._autoDraw}set autoDraw(t){this.watch&&(this.mod[6]=!0),this._autoDraw=t}get allowSleeping(){return this.body?.isSleepingAllowed()}set allowSleeping(t){this.watch&&(this.mod[7]=!0),this.body&&this.body.setSleepingAllowed(t)}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){this.watch&&(this.mod[8]=!0),this._autoUpdate=t}get bounciness(){if(this.fixture)return this.fixture.getRestitution()}set bounciness(t){this.watch&&(this.mod[9]=!0);for(let e=this.fixtureList;e;e=e.getNext())e.setRestitution(t)}get centerOfMass(){let t=this.body.getWorldCenter();return o(t.x,t.y,this.tileSize)}get collider(){return this._collider}set collider(t){let e=(t=t.toLowerCase())[0];if("d"==e&&(t="dynamic"),"s"==e&&(t="static"),"k"==e&&(t="kinematic"),"n"==e&&(t="none"),t==this._collider)return;if(this.__collider=["d","s","k","n"].indexOf(e),void 0===this._collider)return void(this._collider=t);if("none"==t&&("chain"==this._shape||"polygon"==this._shape))throw new Error('Cannot set the collider type of a polygon or chain collider to "none". Try having the sprite overlap with other sprites instead.');this.watch&&(this.mod[10]=!0);let i=this._collider;this._collider=t,void 0!==i&&this._reset()}_reset(){let t,e=this._cloneBodyProps();"chain"!=this._shape&&"polygon"!=this._shape||(t=this._getVertices(!0),this._vertexMode=!0),this.body&&(this.p.world.destroyBody(this.body),this.body=void 0),"none"!=this._collider&&(t?this.addCollider(0,0,t):this.addCollider(),this._hasSensors&&this.addDefaultSensors());for(let t in e)void 0!==e[t]&&(this[t]=e[t]);let i=this._offset._x,s=this._offset._y;this._offset._x=0,this._offset._y=0,this._offsetCenterBy(i,s)}_parseColor(t){if(t instanceof p5.Color)return t;if("object"!=typeof t)return"string"==typeof t&&1==t.length?this.p.colorPal(t):this.p.color(t);if(t.levels)return this.p.color(...t.levels);if(void 0!==t._r)return this.p.color(t._r,t._g,t._b,255*t._a);if(void 0!==t._h)return this.p.color(t._h,t._s,t._v,255*t._a);throw new Error("Invalid color")}get color(){return this._color}set color(t){this.watch&&(this.mod[11]=!0),this._color=this._parseColor(t)}get colour(){return this._color}set colour(t){this.color=t}get shapeColor(){return console.warn("sprite.shapeColor is deprecated, use sprite.color instead"),this._color}set shapeColor(t){console.warn("sprite.shapeColor is deprecated, use sprite.color instead"),this.color=t}get fill(){return this._color}set fill(t){this.color=t}get fillColor(){return this._color}set fillColor(t){this.color=t}get stroke(){return this._stroke}set stroke(t){this.watch&&(this.mod[31]=!0),this._stroke=this._parseColor(t)}get strokeColor(){return this._stroke}set strokeColor(t){this.stroke=t}get strokeWeight(){return this._strokeWeight}set strokeWeight(t){this.watch&&(this.mod[32]=!0),this._strokeWeight=t}get textColor(){return this._textColor}set textColor(t){this.watch&&(this.mod[34]=!0),this._textColor=this._parseColor(t)}get debug(){return this._debug}set debug(t){this.watch&&(this.mod[12]=!0),this._debug=t}get density(){if(this.fixture)return this.fixture.getDensity()}set density(t){this.watch&&(this.mod[13]=!0);for(let e=this.fixtureList;e;e=e.getNext())e.setDensity(t)}get depth(){return console.warn("sprite.depth is deprecated, use sprite.layer instead"),this._layer}set depth(t){console.warn("sprite.depth is deprecated, use sprite.layer instead"),this.layer=t}_getDirectionAngle(t){t=t.toLowerCase().replaceAll(/[ _-]/g,"");let e={up:-90,down:90,left:180,right:0,upright:-45,rightup:-45,upleft:-135,leftup:-135,downright:45,rightdown:45,downleft:135,leftdown:135,forward:this.rotation,backward:this.rotation+180}[t];return"radians"==this.p._angleMode&&(e=this.p.radians(e)),e}get direction(){return 0!==this.vel.x||0!==this.vel.y?this.p.atan2(this.vel.y,this.vel.x):void 0===this._direction?this.rotation:this._direction}set direction(t){this.watch&&(this.mod[14]=!0),"string"==typeof t&&(this._heading=t,t=this._getDirectionAngle(t)),this._direction=t;let e=this.speed;this.vel.x=this.p.cos(t)*e,this.vel.y=this.p.sin(t)*e}get drag(){return this.body?.getLinearDamping()}set drag(t){this.watch&&(this.mod[15]=!0),this.body&&this.body.setLinearDamping(t)}get draw(){return this._display}set draw(t){this._draw=t}get dynamic(){return this.body?.isDynamic()}set dynamic(t){this.collider=t?"dynamic":"kinematic"}get fixture(){return this.fixtureList}get fixtureList(){return this.body?this.body.m_fixtureList:null}get friction(){if(this.fixture)return this.fixture.getFriction()}set friction(t){this.watch&&(this.mod[16]=!0);for(let e=this.fixtureList;e;e=e.getNext())e.setFriction(t)}get heading(){return this._heading}set heading(t){this.direction=t}get immovable(){return console.warn("sprite.immovable is deprecated, use sprite.static instead"),this.body.isStatic()}set immovable(t){console.warn("sprite.immovable is deprecated, use sprite.static instead"),t&&this.body.setStatic()}get img(){return this._ani?.frameImage}set img(t){this.changeAni(t)}get image(){return this._ani?.frameImage}set image(t){this.changeAni(t)}get isMoving(){return 0!=this.vel.x||0!=this.vel.y}get isSuperFast(){return this.body?.isBullet()}set isSuperFast(t){this.watch&&(this.mod[18]=!0),this.body&&this.body.setBullet(t)}get kinematic(){return this.body?.isKinematic()}set kinematic(t){this.collider=t?"kinematic":"dynamic"}get layer(){return this._layer}set layer(t){this.watch&&(this.mod[19]=!0),this._layer=t}get life(){return this._life}set life(t){this.watch&&(this.mod[20]=!0),this._life=t}get mass(){return this.body?.getMass()}set mass(t){if(!this.body)return;this.watch&&(this.mod[21]=!0);let e=this.massData;e.mass=t,this.body.setMassData(e),delete this._massUndefinedByUser}get massData(){const t={I:0,center:new i.Vec2(0,0),mass:0};return this.body.getMassData(t),t.center=o(t.center.x,t.center.y,this.tileSize),t}get mirror(){return this._mirror}set mirror(t){this.watch&&(this.mod[22]=!0),void 0!==t.x&&(this._mirror.x=t.x),void 0!==t.y&&(this._mirror.y=t.y)}get offset(){return this._offset}set offset(t){t.x??=this._offset._x,t.y??=this._offset._y,t.x==this._offset._x&&t.y==this._offset._y||(this.watch&&(this.mod[23]=!0),this._offsetCenterBy(t.x-this._offset._x,t.y-this._offset._y))}get previousPosition(){return this.prevPos}set previousPosition(t){this.prevPos=t}get previousRotation(){return this.prevRotation}set previousRotation(t){this.prevRotation=t}get pixelPerfect(){return this._pixelPerfect}set pixelPerfect(t){this.watch&&(this.mod[24]=!0),this._pixelPerfect=t}get rotation(){if(!this.body)return this._angle||0;let t=this.body.getAngle();return"degrees"===this.p._angleMode?this.p.degrees(t):t}set rotation(t){this.body?("degrees"===this.p._angleMode&&(t=this.p.radians(t)),this.body.setAngle(t)):this._angle=t}get rotationDrag(){return this.body?.getAngularDamping()}set rotationDrag(t){this.body&&(this.watch&&(this.mod[26]=!0),this.body.setAngularDamping(t))}get rotationLock(){return this.body?.isFixedRotation()}set rotationLock(t){this.body&&(this.watch&&(this.mod[27]=!0),this.body.setFixedRotation(t))}get rotationSpeed(){return this.body?this.body.getAngularVelocity():this._rotationSpeed||0}set rotationSpeed(t){this.body?this.body.setAngularVelocity(t):this._rotationSpeed=t}get scale(){return this._scale}set scale(t){if(t<=0&&(t=.01),"number"==typeof t?t={x:t,y:t}:(t.x??=this._scale._x,t.y??=this._scale._y),t.x==this._scale._x&&t.y==this._scale._y)return;this.watch&&(this.mod[28]=!0);let e={x:t.x/this._scale._x,y:t.y/this._scale._y};this._w*=e.x,this._hw*=e.x,this._h&&(this._h*=e.y,this._hh*=e.y),this._resizeCollider(e),this._scale._x=t.x,this._scale._y=t.y,this._scale._avg=t.x}get sleeping(){if(this.body)return!this.body.isAwake()}set sleeping(t){this.body&&(this.watch&&(this.mod[30]=!0),this.body.setAwake(!t))}get speed(){return this.p.createVector(this.vel.x,this.vel.y).mag()}set speed(t){let e=this.direction;this.vel.x=this.p.cos(e)*t,this.vel.y=this.p.sin(e)*t}get static(){return this.body?.isStatic()}set static(t){this.collider=t?"static":"dynamic"}get vertices(){return this._getVertices()}_getVertices(e){let i=this.fixture;for(;i.m_next;)i=i.m_next;let r=i.getShape(),o=[...r.m_vertices];"polygon"==r.m_type&&o.unshift(o.at(-1));let h=this.x,a=this.y;for(let i=0;i=1e3?this.p.p5play.sprites[i]:this.p.p5play.groups[i];let o=t[e][i]+1;if(this[e][i]=o,r instanceof this.p.Group&&(r[e][t._uid]=o),!r||0==o){delete t[e][i],r instanceof this.p.Group&&delete r[e][t._uid];continue}if(s=-1==o?a[e][2]:1==o?a[e][0]:a[e][1],r instanceof this.p.Group)continue;let h=this.p.world._findContactCB(s,t,r);"function"==typeof h&&h(t,r,o)}this.removed&&0==Object.keys(this._collisions).length&&0==Object.keys(this._overlappers).length&&delete this.p.p5play.sprites[this._uid]}_draw(){if(void 0!==this.strokeWeight&&this.p.strokeWeight(this.strokeWeight),this._ani&&"colliders"!=this.debug&&this._ani.draw(this._offset._x,this._offset._y,0,this._scale._x,this._scale._y),!this._ani||this.debug)if(this.debug&&"colliders"!=this.debug&&(this.p.noFill(),this.p.stroke(0,255,0),this.p.line(0,-2,0,2),this.p.line(-2,0,2,0)),null!=this.fixture){"chain"==this._shape?this.p.stroke(this.stroke||this.color):this._stroke&&this.p.stroke(this._stroke);for(let t=this.fixtureList;t;t=t.getNext())this._drawFixture(t)}else this.p.stroke(this._stroke||120),"box"==this._shape?this.p.rect(this._offset._x,this._offset._y,this.w*this.tileSize,this.h*this.tileSize):"circle"==this._shape&&this.p.circle(this._offset._x,this._offset._y,this.d*this.tileSize);void 0!==this.text&&(this.p.textAlign(this.p.CENTER,this.p.CENTER),this.p.fill(this.textColor),this.p.textSize(this.textSize*this.tileSize),this.p.text(this.text,0,0))}_display(){let t=.5*this.p.width-this.p.world.origin.x+this.x*this.tileSize,e=.5*this.p.height-this.p.world.origin.y+this.y*this.tileSize;if("chain"!=this.shape&&this.p.camera.active&&(t+this.wthis.p.camera.bound.max.x||e+this.hthis.p.camera.bound.max.y))this._visible=null;else{this._visible=!0,t=n(t),e=n(e),this._pixelPerfect&&(this._w%2!=0&&h(t%1-.5)||(t=Math.round(t)),this._h%2!=0&&h(e%1-.5)||(e=Math.round(e)));for(let t of this.joints)t.visible?this._uid==t.spriteA._uid?(!t.spriteB._visible||this.layer<=t.spriteB.layer)&&t._display():(!t.spriteA._visible||this.layer1?(r=Math.round(r),o=Math.round(o)):e%90==0&&(r=n(r),o=n(o)),this.moveTo(r,o,i)}moveTo(e,i,s){if(null==e)return;if("number"!=typeof e){let t=e;if(t==this.p.mouse&&!this.p.mouse.active)return;if(void 0===t.x||void 0===t.y)return void console.error("sprite.moveTo ERROR: movement destination not defined, object given with no x or y properties");s=i,i=t.y,e=t.x}if(this._dest.x=this.x,this._dest.y=this.y,e==this.x?e=!1:(this._dest.x=e,e=!0),i==this.y?i=!1:(this._dest.y=i,i=!0),this._destIdx++,!e&&!i)return Promise.resolve(!0);if(this.speed&&(s??=this.speed),this.tileSize>1&&(s??=.1),s??=1,s<=0)return console.warn("sprite.move: speed should be a positive number"),Promise.resolve(!1);let r=this._dest.y-this.y,o=this._dest.x-this.x,h=s/Math.sqrt(r*r+o*o);this.vel.x=o*h,this.vel.y=r*h;let n=this.direction,a=n-.1,l=n+.1,p=s+.01,d=this._destIdx,u=Math.max(this.p.world.velocityThreshold,.25*p)/this.tileSize;return(async()=>{let s=p+p,r=p+p;do{if(d!=this._destIdx)return!1;await t.delay();let e=this.direction;if(e<=a||e>=l||Math.abs(this.vel.x)<=u&&Math.abs(this.vel.y)<=u)return!1;s=Math.abs(this.x-this._dest.x),r=Math.abs(this.y-this._dest.y)}while(e&&s>p||i&&r>p);return s2&&(i=o[0],s=o[1],e=o[2],r=o[3]),void 0!==i?t=this.angleToFace(i,s,r):t-=this.rotation,e??=.1,this.rotationSpeed=t*e}angleTo(t,e){if("object"==typeof t){let i=t;if(i==this.p.mouse&&!this.p.mouse.active)return 0;if(void 0===i.x||void 0===i.y)return console.error("sprite.angleTo ERROR: rotation destination not defined, object given with no x or y properties"),0;e=i.y,t=i.x}return this.p.atan2(e-this.y,t-this.x)}angleToFace(t,e,i){if("object"==typeof t&&(i=e,e=t.y,t=t.x),Math.abs(t-this.x)<.01&&Math.abs(e-this.y)<.01)return 0;let s=this.angleTo(t,e);i??=0,s+=i;let r=s-this.rotation%360,o=360-Math.abs(r);return o*=r<0?1:-1,Math.abs(r)2&&(i=o[0],s=o[1],e=o[2],r=o[3]),void 0!==i)t=this.angleToFace(i,s,r);else{if(t==this.rotation)return;t-=this.rotation}return this.rotate(t,e)}rotate(e,i){if(1==this.__collider)throw new x(0);if(isNaN(e))throw new x(1,[e]);if(0==e)return;let s=Math.abs(e);i??=1,i>s&&(i=s);let r=this.rotation+e,o=e>0;this.rotationSpeed=i*(o?1:-1);let h=Math.floor(s/i)-1;this._rotateIdx??=0,this._rotateIdx++;let n=this._rotateIdx;return(async()=>{if(h>1){let e=Math.abs(this.rotationSpeed)+.01;do{if(this._rotateIdx!=n)return!1;if(await t.delay(),o&&this.rotationSpeed<.01||!o&&this.rotationSpeed>-.01)return!1}while((o&&r>this.rotation||!o&&r.01&&(this.rotationSpeed=r-this.rotation,await t.delay())}else await t.delay();return this._rotateIdx==n&&(this.rotationSpeed=0,this.rotation=r,!0)})()}async changeAni(t){if(this.p.p5play.disableImages)return;if(arguments.length>1)t=[...arguments];else if(t instanceof this.p.SpriteAnimation){if(t==this._ani)return;t=[t]}else if(!Array.isArray(t)){if(t==this._ani?.name)return;t=[t]}let e,i;this._aniChangeCount++;for(let s=0;s1&&("!"==r.name[0]&&(r.name=r.name.slice(1),r.start=-1,r.end=0),"<"!=r.name[0]&&">"!=r.name[0]||(r.name=r.name.slice(1),r.flipX=!0),"^"==r.name[0]&&(r.name=r.name.slice(1),r.flipY=!0),"**"==r.name&&(e=!0,t=t.slice(0,-1)),";;"==r.name&&(i=!0,t=t.slice(0,-1)))}let s=this._aniChangeCount;do{for(let e=0;e1&&(i.start=0),await this._playSequencedAni(i)}}while(e&&s==this._aniChangeCount);1!=t.length&&i&&this._ani.stop()}_playSequencedAni(t){return new Promise((e=>{let{name:i,start:s,end:r,flipX:o,flipY:h}=t;this._changeAni(i),o&&(this._ani.scale.x=-this._ani.scale.x),h&&(this._ani.scale.y=-this._ani.scale.y),s<0&&(s=this._ani.length+s),void 0!==s&&(this._ani.frame=s),void 0!==r?this._ani.goToFrame(r):this._ani.frame==this._ani.lastFrame&&e(),this._ani._onComplete=this._ani._onChange=()=>{o&&(this._ani.scale.x=-this._ani.scale.x),h&&(this._ani.scale.y=-this._ani.scale.y),this._ani._onComplete=this._ani._onChange=null,e()}}))}changeAnimation(){return this.changeAni(...arguments)}_changeAni(t){this._ani?._onChange&&this._ani._onChange(),this._ani?.onChange&&this._ani.onChange();let e=this.animations[t];if(!e)for(let i=this.groups.length-1;i>=0;i--){if(e=this.groups[i].animations[t],e){e=e.clone();break}}if(!e)throw this.p.noLoop(),new x("Sprite.changeAnimation",[t]);this._ani=e,this._ani.name=t,this.resetAnimationsOnChange&&(this._ani.frame=0)}remove(){this.removed=!0}_remove(){this.body&&this.p.world.destroyBody(this.body),this.body=null;for(let t of this.groups)t.remove(this);0==Object.keys(this._collisions).length&&0==Object.keys(this._overlappers).length&&delete this.p.p5play.sprites[this._uid]}get removed(){return this._removed}set removed(t){t&&!this._removed&&(this.watch&&(this.mod[25]=!0),this._removed=!0,this._remove())}toString(){return"s"+this.idNum}_ensureCollide(t,e){if(!t)throw new x("Sprite.collide",2);if(!(t instanceof this.p.Sprite||t instanceof this.p.Group))throw new x("Sprite.collide",0,[t]);if(e&&"function"!=typeof e)throw new x("Sprite.collide",1,[e]);if(!1!==this._hasOverlap[t._uid]&&(this._hasOverlap[t._uid]=!1),!1!==t._hasOverlap[this._uid]&&(t._hasOverlap[this._uid]=!1,t instanceof this.p.Group))for(let e of t)e._hasOverlap[this._uid]=!1}collide(t,e){return this.collides(t,e)}collides(t,e){return this._ensureCollide(t,e),this._collides[t._uid]=e||!0,1==this._collisions[t._uid]}colliding(t,e){this._ensureCollide(t,e),this._colliding[t._uid]=e||!0;let i=this._collisions[t._uid];return i>0?i:0}collided(t,e){return this._ensureCollide(t,e),this._collided[t._uid]=e||!0,-1==this._collisions[t._uid]}_removeContactsWith(t){if(t instanceof this.p.Group)for(let e of t)this._removeContactsWith(e);else this.__removeContactsWith(t)}__removeContactsWith(t){if(this.body)for(let e=this.body.getContactList();e;e=e.next){let i=e.contact;i.m_fixtureA.m_body.sprite._uid!=t._uid&&i.m_fixtureB.m_body.sprite._uid!=t._uid||this.p.world.destroyContact(i)}}_ensureOverlap(t,e){if(!t)throw new x("Sprite.overlap",2);if(!(t instanceof this.p.Sprite||t instanceof this.p.Group))throw new x("Sprite.overlap",0,[t]);if(e&&"function"!=typeof e)throw new x("Sprite.overlap",1,[e]);if(this._hasSensors||this.addDefaultSensors(),!t._hasSensors)if(t instanceof this.p.Sprite)t.addDefaultSensors();else{for(let e of t)e._hasSensors||e.addDefaultSensors();t._hasSensors=!0}if(1!=this._hasOverlap[t._uid]&&(this._removeContactsWith(t),this._hasOverlap[t._uid]=!0),1!=t._hasOverlap[this._uid]&&(t._removeContactsWith(this),t._hasOverlap[this._uid]=!0,t instanceof this.p.Group))for(let e of t)e._hasOverlap[this._uid]=!0}overlap(t,e){return this.overlaps(t,e)}overlaps(t,e){return this._ensureOverlap(t,e),this._overlaps[t._uid]=e||!0,1==this._overlappers[t._uid]}overlapping(t,e){this._ensureOverlap(t,e),this._overlapping[t._uid]=e||!0;let i=this._overlappers[t._uid];return i>0?i:0}overlapped(t,e){return this._ensureOverlap(t,e),this._overlapped[t._uid]=e||!0,-1==this._overlappers[t._uid]}addDefaultSensors(){let t;if(this.body)for(let e=this.fixtureList;e;e=e.getNext())e.m_isSensor||(t=e.m_shape,this.body.createFixture({shape:t,isSensor:!0}));else this.addSensor();this._hasSensors=!0}},this.Sprite.propTypes={x:"Float64",y:"Float64",vel:"Vec2",rotation:"number",rotationSpeed:"number",ani:"string",autoDraw:"boolean",allowSleeping:"boolean",autoUpdate:"boolean",bounciness:"number",collider:"Uint8",color:"color",debug:"boolean",density:"number",direction:"number",drag:"number",friction:"number",h:"number",isSuperFast:"boolean",layer:"number",life:"Int32",mass:"number",mirror:"Vec2_boolean",offset:"Vec2",pixelPerfect:"boolean",removed:"boolean",rotationDrag:"number",rotationLock:"boolean",scale:"Vec2",shape:"Uint8",sleeping:"boolean",stroke:"color",strokeWeight:"number",text:"string",textColor:"color",tile:"string",tileSize:"number",visible:"boolean",w:"number"},this.Sprite.props=Object.keys(this.Sprite.propTypes),this.Sprite.propsAll=this.Sprite.props.concat(["d","diameter","dynamic","fill","height","heading","kinematic","resetAnimationsOnChange","speed","static","width"]),this.Sprite.colliderTypes=["d","s","k","n"],this.Sprite.shapeTypes=["box","circle","chain","polygon"],this.Turtle=function(e){if(t.allSprites.tileSize>1)throw new Error("Turtle can't be used when allSprites.tileSize is greater than 1.");e??=25;let i=new t.Sprite(e,e,[[e,.4*e],[-e,.4*e],[0,.8*-e]]);i.color="green",i._isTurtleSprite=!0,i._prevPos={x:i.x,y:i.y};let s=i.move;return i.move=async function(){this._prevPos.x=this.x,this._prevPos.y=this.y,await s.call(this,...arguments)},i},this.SpriteAnimation=class extends Array{constructor(){super(),this.p=t;let e,i=[...arguments];if(this.name="default",(i[0]instanceof this.p.Sprite||i[0]instanceof this.p.Group)&&(e=i[0],i=i.slice(1)),e??=this.p.allSprites,"string"!=typeof i[0]||1!=i[0].length&&i[0].includes(".")||(this.name=i[0],i=i.slice(1)),this.frame=0,this._cycles=0,this.targetFrame=-1,this.offset={x:e.anis.offset.x||0,y:e.anis.offset.y||0},this._frameDelay=e.anis.frameDelay||4,this.demoMode=e.anis.demoMode||!1,this.playing=!0,this.visible=!0,this.looping=e.anis.looping,this.looping??=!0,this.endOnFirstFrame=!1,this.frameChanged=!1,this.onComplete=this.onChange=null,this._onComplete=this._onChange=null,this.rotation=e.anis.rotation||0,this._scale=new l,0!=i.length&&"number"!=typeof i[0])if(e.animations[this.name]=this,e._ani=this,Array.isArray(i[0])&&"string"==typeof i[0][0]&&(i=[...i[0]]),2!=i.length||"string"!=typeof i[0]||"string"!=typeof i[1]&&"number"!=typeof i[1])if("string"==typeof i[i.length-1]||i[i.length-1]instanceof p5.Image)for(let s=0;s=3)throw new x("SpriteAnimation",1);o=i[0],r=i[1]}else r=i[0];let h=this;if(o instanceof p5.Image&&1!=o.width&&1!=o.height)this.spriteSheet=o,n();else{let a;a="string"==typeof o?o:o.url,this.spriteSheet=this.p.loadImage(a,(()=>{n()}))}function n(){if(Array.isArray(r)||Array.isArray(r.frames)){if("number"!=typeof r[0]){let t=r;if(Array.isArray(r.frames)){t=r.frames,delete r.frames;for(let e=0;e=h.spriteSheet.width&&(u=0,c+=i,c>=h.spriteSheet.height&&(c=0))}}else{let p,d,u=i[0];if(isNaN(i[1])?p=i[1]:d=Number(i[1]),".png"!=u.slice(-4)||p&&".png"!=p.slice(-4))throw new x("SpriteAnimation",0,[u]);let c=0,f=0;for(let y=u.length-5;y>=0&&!isNaN(u.charAt(y));y--)c++;if(p)for(let m=p.length-5;m>=0&&!isNaN(p.charAt(m));m--)f++;let _,g=u.slice(0,-4-c);if(p&&(_=p.slice(0,-4-f)),p&&g!=_)this.push(this.p.loadImage(u)),this.push(this.p.loadImage(p));else{let w,v=parseInt(u.slice(-4-c,-4),10);if(d??=parseInt(p.slice(-4-f,-4),10),dthis.frame&&-1!==this.targetFrame?this.frame++:this.targetFrame=this.lastFrame?this.frame=0:this.frame++:this.frame{this._onComplete=()=>{this._onComplete=null,t()}}))}pause(t){this.playing=!1,t&&(this.frame=t)}stop(t){this.playing=!1,t&&(this.frame=t)}rewind(){return this.looping=!1,this.goToFrame(0)}loop(){this.looping=!0,this.playing=!0}noLoop(){this.looping=!1}nextFrame(){this.frame0?this.frame=this.frame-1:this.looping&&(this.frame=this.length-1),this.targetFrame=-1,this.playing=!1}goToFrame(t){if(!(t<0||t>=this.length))return this.targetFrame=t,this.targetFrame!==this.frame&&(this.playing=!0),new Promise((t=>{this._onComplete=()=>{this._onComplete=null,t()}}))}get lastFrame(){return this.length-1}get frameImage(){let t=this[this.frame];if(t instanceof p5.Image)return t;let{x:e,y:i,w:s,h:r}=t,o=createGraphics(s,r);return o.image(this.spriteSheet,this.offset.x,this.offset.y,s,r,e,i,s,r),o}get w(){return this.width}get width(){return this[this.frame]instanceof p5.Image?this[this.frame].width:this[this.frame]?this[this.frame].w:1}get h(){return this.height}get height(){return this[this.frame]instanceof p5.Image?this[this.frame].height:this[this.frame]?this[this.frame].h:1}get frames(){let t=[];for(let e=0;ee.#t[t],set(i){e.#t[t]=i;for(let s in e){let r=e[s];r instanceof SpriteAnimation&&(r[t]=i)}}});for(let t of s){this.#t[t]={_x:0,_y:0};for(let i of["x","y"])Object.defineProperty(this.#t[t],i,{get:()=>e.#t[t]["_"+i],set(s){e.#t[t]["_"+i]=s;for(let r in e){let o=e[r];o instanceof SpriteAnimation&&(o[t][i]=s)}}})}}},this.Group=class extends Array{constructor(...e){let i;if(e[0]instanceof t.Group&&(i=e[0],e=e.slice(1)),super(...e),this.p=t,"number"==typeof e[0])return;for(let t of this)if(!(t instanceof this.p.Sprite))throw new Error("A group can only contain sprites");if(this.idNum=this.p.p5play.groupsCreated,this._uid=this.idNum,this.p.p5play.groups[this._uid]=this,this.p.p5play.groupsCreated++,this.p.allSprites||(this._isAllSpritesGroup=!0),this.subgroups=[],i instanceof this.p.Group){i.subgroups.push(this);let t=i;do{t=this.p.p5play.groups[t.parent],t.subgroups.push(this)}while(!t._isAllSpritesGroup);this.parent=i._uid}else this._isAllSpritesGroup||(this.p.allSprites.subgroups.push(this),this.parent=0);this.animations=new this.p.SpriteAnimations,this._collides={},this._colliding={},this._collided={},this._hasOverlap={},this._overlaps={},this._overlapping={},this._overlapped={},this._collisions={},this._overlappers={};let s=this;this.Sprite=class extends this.p.Sprite{constructor(){super(s,...arguments)}},this.GroupSprite=this.Sprite,this.Group=class extends this.p.Group{constructor(){super(s,...arguments)}},this.Subgroup=this.Group,this.mouse={presses:null,pressing:null,pressed:null,holds:null,holding:null,held:null,released:null,hovers:null,hovering:null,hovered:null};for(let t in this.mouse)this.mouse[t]=function(e){for(let i of s)if(i.mouse[t](e))return!0;return!1};let r=[...this.p.Sprite.propsAll,"spriteSheet"];for(let t of r)"ani"!=t&&"velocity"!=t&&Object.defineProperty(this,t,{get(){let e=s["_"+t],i=s.length-1;if(void 0===e&&!s._isAllSpritesGroup){let r=this.p.p5play.groups[s.parent];r&&(e=r[t],i=r.length-1)}return e},set(e){s["_"+t]=e;for(let i=0;it&&(t=e._layer);return t}get ani(){return this._ani}set ani(t){this.addAni(t);for(let e of this)e.changeAni(t)}get animation(){return this._ani}set animation(t){this.ani=t}get anis(){return this.animations}get img(){return this._ani.frameImage}set img(t){this.ani=t}get image(){return this._ani.frameImage}set image(t){this.ani=t}set amount(t){let e=t-this.length,i=e>0;e=Math.abs(e);for(let t=0;t0?i:0}collided(t,e){return this._ensureCollide(t,e),this._collided[t._uid]=e||!0,-1==this._collisions[t._uid]}_removeContactsWith(t){for(let e of this)e._removeContactsWith(t)}_ensureOverlap(t,e){if(!t)throw new x("Group.overlap",2);if(!(t instanceof this.p.Sprite||t instanceof this.p.Group))throw new x("Group.overlap",0,[t]);if(e&&"function"!=typeof e)throw new x("Group.overlap",1,[e]);if(!this._hasSensors){for(let t of this)t._hasSensors||t.addDefaultSensors();this._hasSensors=!0}if(!t._hasSensors)if(t instanceof this.p.Sprite)t.addDefaultSensors();else{for(let e of t)e._hasSensors||e.addDefaultSensors();t._hasSensors=!0}if(1!=this._hasOverlap[t._uid]){this._removeContactsWith(t),this._hasOverlap[t._uid]=!0;for(let e of this)e._hasOverlap[t._uid]=!0}if(1!=t._hasOverlap[this._uid]&&(t._removeContactsWith(this),t._hasOverlap[this._uid]=!0,t instanceof this.p.Group))for(let e of t)e._hasOverlap[this._uid]=!0}overlap(t,e){return this.overlaps(t,e)}overlaps(t,e){return this._ensureOverlap(t,e),this._overlaps[t._uid]=e||!0,1==this._overlappers[t._uid]}overlapping(t,e){this._ensureOverlap(t,e),this._overlapping[t._uid]=e||!0;let i=this._overlappers[t._uid];return i>0?i:0}overlapped(t,e){return this._ensureOverlap(t,e),this._overlapped[t._uid]=e||!0,-1==this._overlappers[t._uid]}applyForce(t,e,i,s){for(let r of this)r.applyForce(t,e,i,s)}move(t,e,i){let s=[];for(let r of this)s.push(r.move(t,e,i));return Promise.all(s)}moveTo(t,e,i){if("number"!=typeof t){let s=t;if(s==this.p.mouse&&!this.p.mouse.active)return;i=e,e=s.y,t=s.x}let s=this._resetCentroid(),r=[];for(let o of this){let h={x:o.x-s.x+t,y:o.y-s.y+e};r.push(o.moveTo(h.x,h.y,i))}return Promise.all(r)}moveTowards(t,e,i){if("number"!=typeof t){let s=t;if(s==this.p.mouse&&!this.p.mouse.active)return;i=e,e=s.y,t=s.x}if(void 0!==t||void 0!==e){this._resetCentroid();for(let s of this){void 0===s.distCentroid&&this._resetDistancesFromCentroid();let r={x:s.distCentroid.x+t,y:s.distCentroid.y+e};s.moveTowards(r.x,r.y,i)}}}moveAway(t,e,i){if("number"!=typeof t){let s=t;if(s==this.p.mouse&&!this.p.mouse.active)return;i=e,e=s.y,t=s.x}if(void 0!==t||void 0!==e){this._resetCentroid();for(let s of this){void 0===s.distCentroid&&this._resetDistancesFromCentroid();let r={x:s.distCentroid.x+t,y:s.distCentroid.y+e};s.moveAway(r.x,r.y,i)}}}get(t){return console.warn("Deprecated: use group[i] instead of group.get(i)"),this[t]}push(...t){for(let e of t){if(!(e instanceof this.p.Sprite))throw new Error("you can only add sprites to a group, no "+typeof e+"s");super.push(e),this.parent&&this.p.p5play.groups[this.parent].push(e),e.groups.push(this)}return this.length}size(){return this.length}toString(){return"g"+this.idNum}cull(t,e,i,s,r){if(void 0===i){r=e,t=e=i=s=t}if(isNaN(t)||isNaN(e)||isNaN(i)||isNaN(s))throw new TypeError("The culling boundary must be defined with numbers");if(r&&"function"!=typeof r)throw new TypeError("The callback to group.cull must be a function");let o=this.p.camera.x-this.p.world.hw/this.p.camera.zoom,h=this.p.camera.y-this.p.world.hh/this.p.camera.zoom,n=-i+o,a=-t+h,l=this.p.width+s+o,p=this.p.height+e+h,d=0;for(let t=0;tl||e.y>p)&&(d++,r?r(e,d):e.remove(),e.removed&&t--))}return d}remove(t){if(void 0===t){for(;this.length>0;)this[0].remove();return}let e;if(e="number"==typeof t?t>=0?t:this.length+t:this.indexOf(t),-1!=e){let t=this[e];if(!t.removed){let e=t.groups.findIndex((t=>t._uid==this._uid));t.groups.splice(e,1)}return this.splice(e,1),t}throw new Error("Sprite not found in group")}removeAll(){this.remove()}draw(){let t=[...this];t.sort(((t,e)=>t._layer-e._layer));for(let e=0;e(t.getShape().testPoint(t.getBody().getTransform(),h)&&a.push(t),!0))),r??=this.p.allSprites;let l=[];if(a.length>0)for(let t of r)t.body&&a.includes(t.body.m_fixtureList)&&t._cameraActiveWhenDrawn==o&&l.push(t);return l}getSpriteAt(t,e,i){let s=this.getSpritesAt(t,e,i);return s.sort(((t,e)=>-1*(t._layer-e._layer))),s[0]}_beginContact(t){let e=t.m_fixtureA,i=t.m_fixtureB,s="_collisions";e.m_isSensor&&(s="_overlappers"),e=e.m_body.sprite,i=i.m_body.sprite,e[s][i._uid]=0,i[s][e._uid]=0;for(let t of i.groups)(!e[s][t._uid]||e[s][t._uid]<0)&&(t[s][e._uid]=0,e[s][t._uid]=0);for(let t of e.groups){(!i[s][t._uid]||i[s][t._uid]<0)&&(t[s][i._uid]=0,i[s][t._uid]=0);for(let e of i.groups)(!t[s][e._uid]||t[s][e._uid]<0)&&(t[s][e._uid]=0,e[s][t._uid]=0)}}_endContact(t){let e=t.m_fixtureA,i=t.m_fixtureB,s="_collisions";e.m_isSensor&&(s="_overlappers"),e=e.m_body.sprite,i=i.m_body.sprite,e[s][i._uid]=-2,i[s][e._uid]=-2;for(let t of i.groups){let i=!1;for(let r of t)if(r[s][e._uid]>=0){i=!0;break}i||(t[s][e._uid]=-2,e[s][t._uid]=-2)}for(let t of e.groups){let e=!1;for(let r of t)if(r[s][i._uid]>=0){e=!0;break}if(!e){t[s][i._uid]=-2,i[s][t._uid]=-2;for(let e of i.groups)t[s][e._uid]=-2,e[s][t._uid]=-2}}}_findContactCB(t,e,i){let s=e[t][i._uid];if(s)return s;let r=i instanceof this.p.Sprite;if(r)for(let r of i.groups)if(s=e[t][r._uid],s)return s;if(e instanceof this.p.Sprite)for(let o of e.groups){if(s=o[t][i._uid],s)return s;if(r)for(let e of i.groups)if(s=o[t][e._uid],s)return s}return!1}get allowSleeping(){return this.getAllowSleeping()}set allowSleeping(t){this.setAllowSleeping(t)}},this.Camera=class{constructor(e,i,s){this.p=t;this._pos={x:0,y:0},this.__pos={x:0,y:0},this.mouse={x:this.p.mouseX,y:this.p.mouseY},this.active=!1,this.bound={min:{x:0,y:0},max:{x:0,y:0}},this._zoomIdx=-1,this._zoom=s||1,this.x=e||0,this.y=i||0}get pos(){return this._pos}set pos(t){this.x=t.x,this.y=t.y}get position(){return this._pos}set position(t){this.x=t.x,this.y=t.y}get x(){return this._pos.x}set x(t){this._pos.x=t;let e=-t+this.p.world.hw/this._zoom;this.p.allSprites.pixelPerfect&&(e=Math.round(e)),this.__pos.x=e,this.bound.min.x=t-this.p.world.hw/this._zoom-100,this.bound.max.x=t+this.p.world.hw/this._zoom+100}get y(){return this._pos.y}set y(t){this._pos.y=t;let e=-t+this.p.world.hh/this._zoom;this.p.allSprites.pixelPerfect&&(e=Math.round(e)),this.__pos.y=e,this.bound.min.y=t-this.p.world.hh/this._zoom-100,this.bound.max.y=t+this.p.world.hh/this._zoom+100}get zoom(){return this._zoom}set zoom(t){this._zoom=t;let e=-this._pos.x+this.p.world.hw/t,i=-this._pos.y+this.p.world.hh/t;this.p.allSprites.pixelPerfect&&(e=Math.round(e),i=Math.round(i)),this.__pos.x=e,this.__pos.y=i}zoomTo(t,e){if(t==this._zoom)return Promise.resolve(!0);e??=.1;let i=Math.abs(t-this._zoom),s=Math.round(i/e);t{for(let t=0;t0&&t<=.1?t=this.p.map(t,0,.1,30,4):t<=.5?t=this.p.map(t,.1,.5,4,2.5):t<=.8?t=this.p.map(t,.5,.8,2.5,1):t<=.9?t=this.p.map(t,.8,.9,1,.5):t<=1&&(t=this.p.map(t,.9,1,.5,.2)),this._springiness=t,"wheel"==this.type?this._j.setSpringFrequencyHz(t):this._j.setFrequency(t)}get damping(){return"wheel"!=this.type?this._j.getDampingRatio():this._j.getSpringDampingRatio()}set damping(t){"wheel"==this.type?this._j.setSpringDampingRatio(t):this._j.setDampingRatio(t)}get speed(){return this._j.getJointSpeed()}set speed(t){this._j.isMotorEnabled()||this._j.enableMotor(!0),this._j.setMotorSpeed(t)}get motorSpeed(){return this._j.getMotorSpeed()}get enableMotor(){return this._j.isMotorEnabled()}set enableMotor(t){this._j.enableMotor(t)}get maxPower(){return this._j.getMaxMotorTorque()}set maxPower(t){!this._j.isMotorEnabled()&&t&&this._j.enableMotor(!0),this._j.setMaxMotorTorque(t),t||this._j.enableMotor(!1)}get power(){return this._j.getMotorTorque()}remove(){this._removed||(this.spriteA.joints.splice(this.spriteA.joints.indexOf(this),1),this.spriteB.joints.splice(this.spriteB.joints.indexOf(this),1),this.p.world.destroyJoint(this._j),this._removed=!0)}},this.GlueJoint=class extends this.Joint{constructor(t,e){super(...arguments,"glue")}},this.DistanceJoint=class extends this.Joint{constructor(t,e){super(...arguments,"distance");let s=i.DistanceJoint({},t.body,e.body,t.body.getWorldCenter(),e.body.getWorldCenter());this._createJoint(s)}_display(){this._draw(this.spriteA.x+this.offsetA.x,this.spriteA.y+this.offsetA.y,this.spriteB.x+this.offsetB.x,this.spriteB.y+this.offsetB.y),this.visible=null}},this.WheelJoint=class extends this.Joint{constructor(t,e){super(...arguments,"wheel");let s=i.WheelJoint({maxMotorTorque:1e3,frequencyHz:4,dampingRatio:.7},t.body,e.body,e.body.getWorldCenter(),new i.Vec2(0,1));this._createJoint(s),this._angle="degrees"==this.p._angleMode?90:1.5707963267948966}_display(){let t=this.spriteA.x,e=this.spriteA.y,i=this.spriteB.x+this.offsetB.x,s=this.spriteB.y+this.offsetB.y,r=this.p.tan(this.spriteA.rotation),o=this.p.tan(this._angle+this.spriteA.rotation),h=(s-e+r*t-o*i)/(r-o),n=r*(h-t)+e;this._draw(h,n,i,s),this.visible=null}get angle(){return this._angle}set angle(t){t!=this._angle&&(this._angle=t,this._j.m_localXAxisA=new i.Vec2(this.p.cos(t),this.p.sin(t)),this._j.m_localXAxisA.normalize(),this._j.m_localYAxisA=i.Vec2.crossNumVec2(1,this._j.m_localXAxisA))}},this.HingeJoint=class extends this.Joint{constructor(t,e){super(...arguments,"hinge");let s=i.RevoluteJoint({},t.body,e.body,t.body.getWorldCenter());this._createJoint(s)}_display(){this._draw(this.spriteA.x+this.offsetA.x,this.spriteA.y+this.offsetA.y),this.visible=null}get range(){return this.upperLimit-this.lowerLimit}set range(t){t/=2,this.upperLimit=t,this.lowerLimit=-t}get lowerLimit(){let t=this._j.getLowerLimit();return"radians"==this.p._angleMode?t:this.p.degrees(t)}set lowerLimit(t){this._j.isLimitEnabled()||this._j.enableLimit(!0),this.spriteA.body.setAwake(!0),this.spriteB.body.setAwake(!0),"degrees"==this.p._angleMode&&(t=this.p.radians(t)),this._j.m_lowerAngle=t}get upperLimit(){let t=this._j.getUpperLimit();return"radians"==this.p._angleMode?t:this.p.degrees(t)}set upperLimit(t){this._j.isLimitEnabled()||this._j.enableLimit(!0),this.spriteA.body.setAwake(!0),this.spriteB.body.setAwake(!0),"degrees"==this.p._angleMode&&(t=this.p.radians(t)),this._j.m_upperAngle=t}get angle(){let e=this._j.getJointAngle();return"radians"==this.p._angleMode?e:t.radians(e)}},this.RevoluteJoint=this.HingeJoint,this.SliderJoint=class extends this.Joint{constructor(t,e){super(...arguments,"slider");let s=i.PrismaticJoint({lowerTranslation:-1,upperTranslation:1,enableLimit:!0,maxMotorForce:50,motorSpeed:0,enableMotor:!0},t.body,e.body,t.body.getWorldCenter(),new i.Vec2(1,0));this._createJoint(s),this._angle=0}get angle(){return this._angle}set angle(t){t!=this._angle&&(this._angle=t,this._j.m_localXAxisA=new i.Vec2(this.p.cos(t),this.p.sin(t)),this._j.m_localXAxisA.normalize(),this._j.m_localYAxisA=i.Vec2.crossNumVec2(1,this._j.m_localXAxisA))}get range(){return this.upperLimit-this.lowerLimit}set range(t){t/=2,this.upperLimit=t,this.lowerLimit=-t}get lowerLimit(){return this._j.getLowerLimit()/this.spriteA.tileSize*s}set lowerLimit(t){this._j.isLimitEnabled()||this._j.enableLimit(!0),t=t*this.spriteA.tileSize/s,this._j.setLimits(t,this._j.getUpperLimit())}get upperLimit(){return this._j.getUpperLimit()/this.spriteA.tileSize*s}set upperLimit(t){this._j.isLimitEnabled()||this._j.enableLimit(!0),t=t*this.spriteA.tileSize/s,this._j.setLimits(this._j.getLowerLimit(),t)}},this.PrismaticJoint=this.SliderJoint,this.RopeJoint=class extends this.Joint{constructor(t,e){super(...arguments,"rope");let s=i.RopeJoint({maxLength:1},t.body,e.body,t.body.getWorldCenter(),e.body.getWorldCenter());this._createJoint(s)}get maxLength(){return this._j.getMaxLength()}set maxLength(t){this._j.setMaxLength(t)}};class l{constructor(){let t=this;Object.defineProperties(this,{x:{get:()=>t._x,set(e){e!=t._x&&(t._x=e,t._avg=.5*(t._x+t._y))},configurable:!0,enumerable:!0},y:{get:()=>t._y,set(e){e!=t._y&&(t._y=e,t._avg=.5*(t._x+t._y))},configurable:!0,enumerable:!0},_x:{value:1,enumerable:!1,writable:!0},_y:{value:1,enumerable:!1,writable:!0},_avg:{value:1,enumerable:!1,writable:!0}})}valueOf(){return this._avg}}const p=function(){let t=new Float32Array(1),e=new Int32Array(t.buffer);return function(i){t[0]=i;let s=e[0],r=s>>16&32768,o=s>>12&2047,h=s>>23&255;return h<103?r:h>142?(r|=31744,r|=(255==h?0:1)&&8388607&s,r):h<113?(o|=2048,r|=(o>>114-h)+(o>>113-h&1),r):(r|=h-112<<10|o>>1,r+=1&o,r)}}();function d(t){return!/^(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*\s*(?:(?:(?:async\s(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*\s*)?function|class)(?:\s|(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*)|(?:[_$\w][\w0-9_$]*\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*\()|(?:\[\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*(?:(?:['][^']+['])|(?:["][^"]+["]))\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*\]\())/.test(t.toString())}function u(t,e){return"triangle"==e?t=[t,-120,3]:"square"==e?t=[t,-90,4]:"pentagon"==e?t=[t,-72,5]:"hexagon"==e?t=[t,-60,6]:"septagon"==e?t=[t,-51.4285714286,7]:"octagon"==e?t=[t,-45,8]:"enneagon"==e?t=[t,-40,9]:"decagon"==e?t=[t,-36,10]:"hendecagon"==e?t=[t,-32.7272727273,11]:"dodecagon"==e&&(t=[t,-30,12]),t}this.Netcode=class{constructor(){this.typeSizes={boolean:1,Uint8:1,Vec2_boolean:1,Float16:2,number:2,color:4,Float32:4,Int32:4,Vec2:4,Float64:8},this.player=0}connect(){}disconnect(){}spriteToBinary(e){const i=t.Sprite.props;let s=3;for(let r=0;ro.setUint16(t,p(e)),o.setUint16(0,e._uid);let h=2;for(let s=0;sfunction(t){let e=(31744&t)>>10,i=1023&t;return(t>>15?-1:1)*(e?31===e?i?NaN:1/0:Math.pow(2,e-15)*(1+i/1024):i/1024*6103515625e-14)}(s.getUint16(t));let r=i||0,o=s.getUint16(r);r+=2;let h=t.p5play.sprites[o]||new t.Sprite;for(;r!==s.byteLength;){const e=s.getUint8(r);if(255===e)break;r+=1;const i=t.Sprite.props[e],o=t.Sprite.propTypes[i];if("boolean"===o)h[i]=0!==s.getUint8(r);else if("number"==o||"Float16"===o)h[i]=s.getFloat16(r);else if("Float32"===o)h[i]=s.getFloat32(r);else if("Float64"===o)h[i]=s.getFloat64(r);else{if("string"===o){const t=s.getUint16(r);r+=2;const e=new Uint8Array(s.buffer,r,t);h[i]=(new TextDecoder).decode(e),r+=t;continue}if("color"===o){const t=s.getUint8(r),e=s.getUint8(r+1),o=s.getUint8(r+2),n=s.getUint8(r+3);h[i]=color(t,e,o,n)}else if("Vec2"===o){const t=s.getFloat16(r),e=s.getFloat16(r+2);h[i]={x:t,y:e}}else if("Vec2_boolean"===o){const t=s.getUint8(r);h[i]={x:1==(1&t),y:2==(2&t)}}else if("Uint8"===o){let e=s.getUint8(r);"collider"===i?h.collider=t.Sprite.colliderTypes[e]:"shape"===i?h.shape=t.Sprite.shapeTypes[e]:h[i]=e}else"Int32"===o&&(h[i]=s.getInt32(r))}r+=this.typeSizes[o]}return s.offset=r,h}inputToJSON(){}},this.netcode=new this.Netcode,this.updateSprites=function(){1==this.frameCount&&console.warn("updateSprites() is deprecated, use world.step() instead."),this.world.step(...arguments),this.allSprites.update()},this.p5play.palettes??=[{a:"aqua",b:"black",c:"crimson",d:"dark blue",f:"fuchsia",g:"green",h:"hot pink",i:"blue",k:"black",l:"lavender",m:"magenta",n:"brown",o:"orange",p:"pink",r:"red",s:"sky blue",t:"turquoise",u:"blue",v:"violet",w:"white",y:"yellow"}],this.colorPal=(e,i)=>{if(e instanceof p5.Color)return e;let s;return"number"==typeof i&&(i=t.p5play.palettes[i]),i??=t.p5play.palettes[0],i&&(s=i[e]),""===s||"."===e||" "===e?t.color(0,0,0,0):t.color(s||e)},this.spriteArt=(e,i,s)=>{i??=1,"number"==typeof s&&(s=t.p5play.palettes[s]),s??=t.p5play.palettes[0];let r=e;"string"==typeof e&&(r=(e=(e=(e=e.trim()).replace(/\r*\n\t+/g,"\n")).replace(/\s+$/g,"")).split("\n"));let o=0;for(let t of r)t.length>o&&(o=t.length);let h=r.length,n=t.createImage(o*i,h*i);n.loadPixels();for(let t=0;tnew Promise(t?e=>{setTimeout(e,t)}:requestAnimationFrame),this.sleep=t=>this.delay(t),this.play=t=>{if(!t.play)throw new Error("Tried to play a sound but the sound is not a sound object: "+t);return new Promise(((e,i)=>{t.play(),t.onended((()=>e()))}))},this.p5play.playIntro=async function(){if(document.getElementById("p5play-intro"))return;t._incrementPreload();let e=document.createElement("div");e.id="p5play-intro",e.style="position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 1000; background-color: black;";let i=document.createElement("img");i.src="https://p5play.org/v3/made_with_p5play.png",i.style="position: absolute; top: 50%; left: 50%; width: 40vh; height: 20vh; margin-left: -20vh; margin-top: -10vh; z-index: 1000; opacity: 0; transition: opacity 0.1s ease-in-out;",document.body.append(e),e.append(i),await t.delay(100),i.style.opacity="1",i.style.transition="scale 2s, opacity 0.4s ease-in-out",i.style.scale="1.1",await t.delay(1200),i.style.opacity="0",await t.delay(400),e.style.display="none",e.remove(),document.getElementById("p5play-intro")?.remove(),t._decrementPreload()};{let t=location.hostname;switch(t){case"":case"127.0.0.1":case"localhost":case"p5play.org":case"openprocessing.org":case"preview.openprocessing.org":case"editor.p5js.org":case"codepen.io":case"cdpn.io":case"glitch.com":case"replit.com":case"stackblitz.com":case"jsfiddle.net":break;default:if(t.endsWith("stackblitz.io")||t.endsWith("glitch.me")||t.endsWith("repl.co")||location.origin.endsWith("preview.p5js.org"))break;this.p5play.playIntro()}}let c=p5.disableFriendlyErrors;p5.disableFriendlyErrors=!0,this.canvas=this.canvas;const f=this.createCanvas;this.createCanvas=function(){let e,i,s,r,o=[...arguments],h=!1,n=!1;if("string"==typeof o[0]&&(o[0].includes(":")?s=o[0].split(":"):(o[2]=o[0],o[0]=void 0),"fullscreen"==o[1]&&(h=!0)),o[0]?"number"==typeof o[0]&&"number"!=typeof o[1]&&(o[2]=o[1],o[1]=o[0]):(o[0]=window.innerWidth,o[1]=window.innerHeight,h=!0),"string"==typeof o[2]&&(o[2]=o[2].toLowerCase(),"p2d"!=o[2]&&"webgl"!=o[2]&&(o[2]=o[2].split(" ")),"pixelated"==o[2][0]&&(n=!0,o[2][1]?r=Number(o[2][1].slice(1)):h=!0,s=[o[0],o[1]]),"fullscreen"==o[2][0]&&(h=!0)),s){let t=Number(s[0]),h=Number(s[1]);r?(e=t*r,i=h*r):(e=window.innerWidth,i=window.innerWidth*(h/t),i>window.innerHeight&&(e=window.innerHeight*(t/h),i=window.innerHeight)),e=Math.round(e),i=Math.round(i),n||(o[0]=e,o[1]=i)}o.length<3&&(o[2]="p2d");let a=f.call(t,...o);this.canvas.tabIndex=0,this.canvas.w=o[0],this.canvas.h=o[1],this.canvas.addEventListener("keydown",(function(t){" "!=t.key&&"/"!=t.key&&"ArrowUp"!=t.key&&"ArrowDown"!=t.key&&"ArrowLeft"!=t.key&&"ArrowRight"!=t.key||t.preventDefault()})),this.canvas.addEventListener("mouseover",(()=>{this.mouse.isOnCanvas=!0,this.mouse.active=!0})),this.canvas.addEventListener("mouseleave",(()=>{this.mouse.isOnCanvas=!1})),this.canvas.addEventListener("touchstart",(t=>{t.preventDefault()})),this.world.resize(),c||(p5.disableFriendlyErrors=!1);let l="\ncanvas { \n\toutline: none;\n\t-webkit-touch-callout: none;\n\t-webkit-text-size-adjust: none;\n\t-webkit-user-select: none;\n\toverscroll-behavior: none;\n}\nmain{\n\toverscroll-behavior: none;\n}";h&&(l="html,\nbody,\n"+l,l+="\nhtml, body {\n\tmargin: 0;\n\tpadding: 0;\n\toverflow: hidden;\n\theight: 100%;\n}\nmain {\n\tmargin: auto;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-content: center;\n\tjustify-content: center;\n\theight: 100%;\n}"),n&&(l+=`\ncanvas {\n\timage-rendering: pixelated;\n\twidth: ${e}px!important;\n\theight: ${i}px!important;\n}`);let p=document.createElement("style");p.innerHTML=l,document.head.appendChild(p),n&&(t.pixelDensity(1),t.noSmooth());let d=navigator.userAgent.indexOf("iPhone OS");if(d>-1){let e=navigator.userAgent.substring(d+10,d+12);this.p5play.version=e,e<16&&t.pixelDensity(1),this.p5play.os.platform="iOS",this.p5play.os.version=e}else void 0!==navigator.userAgentData&&(this.p5play.os.platform=navigator.userAgentData.platform);return a},this.Canvas=function(){return t.createCanvas(...arguments)};const _=this.background;this.background=function(){let t,e=arguments;1==e.length&&("string"==typeof e[0]||e[0]instanceof p5.Color)&&(t=this.colorPal(e[0])),void 0!==t?_.call(this,t):_.call(this,...e)};const g=this.fill;this.fill=function(){let t,e=arguments;1==e.length&&(t=this.colorPal(e[0])),void 0!==t?g.call(this,t):g.call(this,...e)};const y=this.stroke;this.stroke=function(){let t,e=arguments;1==e.length&&(t=this.colorPal(e[0])),void 0!==t?y.call(this,t):y.call(this,...e)},this.p5play.images={onLoad:t=>{}},this.p5play.disableImages=!1;const m=this.loadImage;this.loadImg=this.loadImage=function(){if(this.p5play.disableImages)return;let e,i=arguments,s=i[0],r=t.p5play.images[s];if("function"==typeof i[i.length-1]&&(e=i[i.length-1]),r)return 1==r.width&&1==r.height||!r.pixels.length?e?(r.cbs.push(e),r.calls++):t._decrementPreload():(e&&e(),t._decrementPreload()),r;return r=m.call(t,s,(e=>{e.w=e.width,e.h=e.height;for(let t of e.cbs)t(e);for(let i=1;ii[e])),o+=h,p5._friendlyError(o,t)}}this.allSprites=new this.Group,this.world=new this.World,this.camera=new this.Camera,this.InputDevice=class{constructor(){this.holdThreshold=12}init(t){for(let e of t)this[e]=0}ac(t){return t}presses(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),1==this[t]||-2==this[t]}pressing(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),-2==this[t]?1:this[t]>0?this[t]:0}pressed(t){return this.released(t)}holds(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),this[t]==this.holdThreshold}holding(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),this[t]>=this.holdThreshold?this[t]:0}held(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),-3==this[t]}released(t){return t??=this.default,void 0===this[t]&&(t=this.ac(t)),this[t]<=-1}releases(t){return this.released(t)}},this._Mouse=class extends this.InputDevice{constructor(){super();let t=this;this._position={get x(){return t.x},set x(e){t.x=e},get y(){return t.y},set y(e){t.y=e}};this.init(["x","y","left","center","right"]),this.default="left",this.drag={left:0,center:0,right:0},this.isOnCanvas=!1,this.active=!1,this.x,this.y}get pos(){return this._position}get position(){return this._position}ac(t){return t=t.slice(0,4)?"left":"right"==t.slice(0,5)?"right":"middle"==t.slice(0,6)?"center":t.toLowerCase()}drags(t){return t??=this.default,1==this.drag[t]}dragging(t){return t??=this.default,this.drag[t]>0?this.drag[t]:0}dragged(t){return t??=this.default,-1==this.drag[t]}},this.mouse=new this._Mouse,this._SpriteMouse=class extends this._Mouse{constructor(){super(),this.hover=0}hovers(){return 1==this.hover}hovering(){return this.hover>0?this.hover:0}hovered(){return-1==this.hover}};const v=function(t){if(this.mouse[t]++,this.mouse.active=!0,this.world.mouseSprites.length){let e=this.world.mouseSprite;e&&(e.mouse[t]=0,e.mouse.drag[t]=0),e=this.world.mouseSprites[0],e.mouse[t]=1,this.world.mouseSprite=e}},b=this._onmousedown;this._onmousedown=function(t){let e="left";1===t.button?e="center":2===t.button&&(e="right"),v.call(this,e),b.call(this,t)};const S=this._ontouchstart;this._ontouchstart=function(t){v.call(this,"left"),S.call(this,t)};const A=function(t){let e=this.mouse;if(e[t]>0&&e.drag[t]<=0){e.drag[t]=1,e._isDragging=!0;let i=this.world.mouseSprite?.mouse;i&&(i.drag[t]=1,i._isDragging=!0)}},C=this._onmousemove;this._onmousemove=function(t){let e="left";1===t.button?e="center":2===t.button&&(e="right"),A.call(this,e),C.call(this,t)};const k=function(t){let e=this.mouse;e[t]>=e.holdThreshold?e[t]=-3:e[t]>1?e[t]=-1:e[t]=-2;let i=this.world.mouseSprite?.mouse;i&&(i.hover>1?(i[t]>=this.mouse.holdThreshold?i[t]=-3:i[t]>1?i[t]=-1:i[t]=-2,i.drag[t]>0&&(i.drag[t]=i[t])):(i[t]=0,i.drag[t]=0))},z=this._onmouseup;this._onmouseup=function(t){let e="left";1===t.button?e="center":2===t.button&&(e="right"),k.call(this,e),z.call(this,t)};const M=this._ontouchend;if(this._ontouchend=function(t){k.call(this,"left"),M.call(this,t)},this._KeyBoard=class extends this.InputDevice{constructor(){super(),this.default=" "}ac(t){if(1==t.length)return t.toLowerCase();if(!isNaN(t)){if(38==t)return"ArrowUp";if(40==t)return"ArrowDown";if(37==t)return"ArrowLeft";if(39==t)return"ArrowRight";if(t<10)return t+"";throw new Error('Use key names with the keyboard input functions, not key codes! If you are trying to detect if the user pressed a number key make it a string. For example: "5"')}return"space"==t||"spacebar"==t?" ":t[0].toUpperCase()+t.slice(1).toLowerCase()}get space(){return this[" "]}get spacebar(){return this[" "]}},this.kb=new this._KeyBoard,delete this._KeyBoard,this.keyboard=this.kb,navigator.keyboard){const t=navigator.keyboard;window==window.top?t.getLayoutMap().then((t=>{"w"!=t.get("KeyW")&&(this.p5play.standardizeKeyboard=!0)})):this.p5play.standardizeKeyboard=!0}else this.p5play.standardizeKeyboard=!0;function T(t){let e=t.code;return 4==e.length&&"Key"==e.slice(0,3)?e[3].toLowerCase():t.key}this.keyIsDown=function(t){throw new Error("The p5.js keyIsDown function is outdated and can't be used in p5play. Trust me, you'll see that the p5play kb.pressing function is much better. It uses key name strings that are easier to write and easier to read! https://p5play.org/learn/input_devices.html The p5.js keyIsDown function relies on key codes and custom constants for key codes, which are not only hard to remember but were also deprecated in the JavaScript language standards over six years ago and shouldn't be used in new projects. More info: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode")};let j={w:"up",s:"down",a:"left",d:"right",ArrowUp:"up",ArrowDown:"down",ArrowLeft:"left",ArrowRight:"right",i:"up2",k:"down2",j:"left2",l:"right2"};const F=this._onkeydown;this._onkeydown=function(t){let e=t.key;this.p5play.standardizeKeyboard&&(e=T(t));let i=[e],s=j[e];s&&i.push(s);for(let t of i)(!this.kb[t]||this.kb[t]<0)&&(this.kb[t]=1);F.call(this,t)};const D=this._onkeyup;this._onkeyup=function(t){let e=t.key;this.p5play.standardizeKeyboard&&(e=T(t));let i=[e],s=j[e];s&&i.push(s);for(let t of i)this.kb[t]>=this.kb.holdThreshold?this.kb[t]=-3:this.kb[t]>1?this.kb[t]=-1:this.kb[t]=-2;D.call(this,t)},this._Contro=class extends this.InputDevice{constructor(t){super();this.init(["a","b","x","y","l","r","lt","rt","select","start","up","down","left","right","leftTrigger","rightTrigger"]),this.leftStick={x:0,y:0,btn:0},this.rightStick={x:0,y:0,btn:0},this._btns={a:0,b:1,x:2,y:3,l:4,r:5,lt:6,rt:7,select:8,start:9,leftStickButton:10,rightStickButton:11,up:12,down:13,left:14,right:15},this._axes={leftStick:{x:0,y:1},rightStick:{x:2,y:3},leftTrigger:4,rightTrigger:5},t.id.includes("GuliKit")&&(this._btns.a=1,this._btns.b=0,this._btns.x=3,this._btns.y=2),e(t),this.gamepad=t,this.id=t.id}ac(t){return t.toLowerCase()}_update(){if(this.gamepad=navigator.getGamepads()[this.gamepad.index],!this.gamepad)return;let t=this.gamepad;for(let e in this._btns){let i=this._btns[e];t.buttons[i].pressed?this[e]++:this[e]=0}return this.leftStick.x=t.axes[this._axes.leftStick.x],this.leftStick.y=t.axes[this._axes.leftStick.y],this.rightStick.x=t.axes[this._axes.rightStick.x],this.rightStick.y=t.axes[this._axes.rightStick.y],void 0!==t.axes[this._axes.leftTrigger]?(this.leftTrigger=t.axes[this._axes.leftTrigger],this.rightTrigger=t.axes[this._axes.rightTrigger]):(this.leftTrigger=t.buttons[this._btns.lt].value,this.rightTrigger=t.buttons[this._btns.rt].value),!0}},this._Contros=class extends Array{constructor(){super();let t=this;window.addEventListener("gamepadconnected",(e=>{t._addContro(e.gamepad)})),window.addEventListener("gamepaddisconnected",(e=>{t._removeContro(e.gamepad)})),this.default="a";let e=["presses","pressing","pressed","holds","holding","held","released"];for(let t of e)this[t]=e=>{if(this[0])return this[0][t](e)};let i=["a","b","x","y","l","r","lt","rt","select","start","leftStickButton","rightStickButton","up","down","left","right"];for(let e of i)Object.defineProperty(this,e,{get:()=>t[0]?t[0][e]:0});let s=["leftStick","rightStick"];for(let e of s){this[e]={};for(let i of["x","y"])Object.defineProperty(this[e],i,{get:()=>t[0]?t[0][e][i]:0})}if(!navigator?.getGamepads)return;let r=navigator.getGamepads();for(let t of r)t&&this._addContro(t)}_addContro(i){i&&(e("controller "+this.length+" connected: "+i.id),this.push(new t._Contro(i)))}_removeContro(t){if(t){e("controller "+this.length+" disconnected: "+t.id);for(let e=0;ethis.p5play._fps,this.loadAds=t=>{t??={},void 0!==window.webkit&&webkit.messageHandlers.loadAds.postMessage(JSON.stringify(t))},this.showAd=t=>{t&&(t=t.toLowerCase()),t??="interstitial",void 0!==window.webkit&&confirm("p5play:"+t)}})),p5.prototype.registerMethod("pre",(function(){this.p5play._fps&&(this.p5play._preDrawFrameTime=performance.now()),1==this.frameCount&&(this.camera.x||(this.camera.x=this.world.hw),this.camera.y||(this.camera.y=this.world.hh),this.camera.init=!0,this.canvas.addEventListener("contextmenu",(t=>t.preventDefault()))),this.mouse.x=(this.mouseX-this.world.hw)/this.camera.zoom+this.camera.x,this.mouse.y=(this.mouseY-this.world.hh)/this.camera.zoom+this.camera.y,this.camera.mouse.x=this.mouseX,this.camera.mouse.y=this.mouseY,this.contro._update()})),p5.prototype.registerMethod("post",(function(){this.p5play._inPostDraw=!0,this.allSprites.autoCull&&this.allSprites.cull(1e4),this.allSprites._autoDraw&&(this.camera.on(),this.allSprites.draw(),this.camera.off()),this.allSprites._autoDraw??=!0,this.world.autoStep&&this.world.step(),this.world.autoStep??=!0,this.allSprites._autoUpdate&&this.allSprites.update(),this.allSprites._autoUpdate??=!0;for(let t of this.allSprites)t.autoDraw??=!0,t.autoUpdate??=!0;for(let t in this.kb)"holdThreshold"!=t&&(this.kb[t]<0?this.kb[t]=0:this.kb[t]>0&&this.kb[t]++);let t=this.mouse,e=this.world.mouseSprite?.mouse;for(let i of["left","center","right"])t[i]<0?t[i]=0:t[i]>0&&t[i]++,e&&(e[i]=t[i]);if(this.world.mouseTracking){let i=this.world.getSpritesAt(t.x,t.y);i.sort(((t,e)=>-1*(t._layer-e._layer)));let s=this.world.getSpritesAt(this.camera.mouse.x,this.camera.mouse.y,this.allSprites,!1);s.sort(((t,e)=>-1*(t._layer-e._layer))),i=i.concat(s);for(let t=0;t0?e.mouse.hover=-1:e.mouse.hover<0&&(e.mouse.hover=0):e.mouse.hover++}let r=this.world.mouseSprite;if(t.left<=0&&t.center<=0&&t.right<=0)r=null,this.world.mouseSprite=null;else for(let i of["left","center","right"])t.drag[i]<0?t.drag[i]=0:t.drag[i]>0&&t.drag[i]++,e&&(e.drag[i]=t.drag[i],e.x=r.x-t.x,e.y=r.y-t.y);for(let t of this.world.mouseSprites)if(!(e?._isDragging&&t==r||i.includes(t))){let e=t.mouse;e.hover=-1,e.left=e.center=e.right=0}this.world.mouseSprites=i}this.camera.off(),this.p5play._fps&&(this.p5play._postDrawFrameTime=performance.now(),this.p5play._fps=Math.round(1e3/(this.p5play._postDrawFrameTime-this.p5play._preDrawFrameTime))||1),this.p5play._inPostDraw=!1}));