text: (function(window){'use strict';var $e=new function(){const vbn=1000000;const vln=1/vbn;var constants={g:0.01};var internal={debug:true,catchup:false,started:false,canvas:"",ctx:"",textcolor:'black',size:0,time:{FPS:1,FPScount:0,FPSsum:0,lossedFrames:0,maxFPS:60,minFPS:20,deltaTime:1,startTime:0,behindTime:0,elapsedTime:0,miliseconds:0,speed:1,catchUpTime:1/8,intervalClear:10000,elapsedLastClear:0,intervalRestartDelay:40},controlVars:{update:{finish:false,exceeded:0,alert:50,alerted:false},start:false},debugVars:[],console:{history:[],border:false,font:'7pt Calibri',color:'black'},world:{gravity:10,drag:1},globals:{maxForce:150,opacity:0.9,background:"#FFF"},mouse:{over:undefined,selected:[],obj:undefined,click:{left:false,middle:false,right:false}},camera:{zoom:1},inputs:{},layers:[],phycs:[],user:{}};this.init=function(canvas,start,update){if(!internal.started){if(canvas!=undefined&&typeof canvas=="object"){if(typeof start=="function"&&typeof update=="function"){try{internal.canvas=canvas;internal.ctx=canvas.getContext("2d");internal.size=new this.Vector2(0,0);internal.size.x=canvas.width;internal.size.y=canvas.height;internal.user.start=start;internal.user.udpate=update;Start();internal.started=true}catch(e){$d.LogError("The element is not a canvas")}}else{$d.LogError("Missing Start/Update functions")}}else{$d.LogError("Invalid element")}}else{$d.LogWarning("The engine is already running!")}};this.setTextColor=function(value){if($d.ValidateInput(arguments,["string"])){internal.textcolor=value}};this.setZoom=function(value){if($d.ValidateInput(arguments,["number"])){if(value>0){internal.camera.zoom=value}else{$d.LogError("The camera Zoom need to be less than 0")}}};this.setMaxFPS=function(value){if($d.ValidateInput(arguments,["number"])){internal.time.maxFPS=value}};this.setDebug=function(value){if($d.ValidateInput(arguments,["boolean"])){internal.debug=value}};this.setSpeed=function(value){if($d.ValidateInput(arguments,["number"])){internal.time.speed=value}};this.setGravity=function(value){if($d.ValidateInput(arguments,["number"])){internal.world.gravity=value}};this.setCatchUp=function(value){if($d.ValidateInput(arguments,["boolean"])){internal.catchUp=value}};this.setBackground=function(value){if($d.ValidateInput(arguments,["string"])){internal.globals.background=value}};this.stats=function(){$d.Log("STATS");$d.Log("FPS: "+internal.time.FPS);$d.Log("Current state: "+((internal.started)?"Running":"Stopped"));$d.Log("Frame loss count: "+internal.time.lossedFrames);$d.Log("Elapsed Time: "+$d.FormatMiliseconds(internal.time.elapsedTime));$d.Stats()};this.add2DObject=function(obj,layer){if($d.ValidateInput(arguments,["object","number"])){if(internal.layers[layer+50]==undefined){internal.layers[layer+50]=[]}obj.id=internal.layers[layer+50].push(obj);obj.layer=layer}};this.addDebugObject=function(name,obj,vars,duration){if($d.ValidateInput(arguments,["string","object","array[string]"],["number"])){internal.debugVars.push({name:name,obj:obj,vars:vars,duration:duration})}};this.writeDebugConsole=function(string,type){internal.console.history.push({name:string,type:type})};this.getKey=function(keyCode){if(internal.inputs[keyCode]!=undefined){return internal.inputs[keyCode]}return false};function Start(){internal.controlVars.update.finish=true;var sd=new Date().getTime();internal.time.miliseconds=sd;internal.console.size=new $e.Vector2(50,50);internal.console.position=new $e.Vector2(internal.size.x-internal.console.size.x,0);internal.mouse.obj=new $e.Object2D("Mouse",new $e.Vector2(0,0),1,1,1);internal.mouse.obj.setCollider(new $e.BoxCollider(0.1,0.1),true);internal.camera.obj=new $e.BaseObject2D("MainCamera",new $e.Vector2(0,0));internal.canvas.addEventListener('mousemove',function(evt){UpdateMousePos(internal.canvas,evt)},false);internal.canvas.addEventListener("mousedown",function(evt){UpdateMouseAction(evt,true)});internal.canvas.addEventListener("mouseup",function(evt){UpdateMouseAction(evt,false)});window.addEventListener("keydown",function(evt){UpdateInputs(evt,true)});window.addEventListener("keyup",function(evt){UpdateInputs(evt,false)});window.addEventListener("mousewheel",function(evt){UpdateInputs({code:"mousewheel"},evt.wheelDeltaY);evt.preventDefault()});internal.time.interval=StartInterval();try{internal.user.start({FPS:internal.time.FPS,deltaTime:internal.time.deltaTime,totalTime:internal.time.elapsedTime,selected:internal.mouse.selected,over:internal.mouse.over,screenSize:internal.size,mouse:{pos:internal.mouse.obj.getPos()},camera:internal.camera.obj,zoom:internal.camera.zoom,objects:internal.layers})}catch(e){$d.LogError("Error in User Start function",e)}}function StartInterval(){return setInterval(function(){if(internal.controlVars.update.finish){internal.controlVars.update.finish=false;internal.controlVars.update.alerted=false;internal.controlVars.update.exceeded=0;var d=new Date().getTime();var t=d-internal.time.miliseconds;internal.time.elapsedTime+=t;internal.time.elapsedLastClear+=t;internal.time.deltaTime=(t/1000)*internal.time.speed;internal.time.miliseconds=d;internal.time.FPS=1/(internal.time.deltaTime/internal.time.speed);internal.time.FPSsum+=internal.time.FPS;internal.time.FPScount+=1;if(internal.time.FPS>0&&internal.time.FPS<internal.time.minFPS){if(internal.catchUp){$d.LogWarning("Running behind the main timeline ("+(internal.time.FPS+internal.time.behindTime)+" seconds) trying to catch up at "+internal.time.catchUpTime+" seconds per frame.")}internal.time.behindTime+=internal.time.deltaTime;internal.time.deltaTime=1/internal.time.minFPS}else{if(internal.time.behindTime>0){if(internal.catchUp){if(internal.time.behindTime<internal.time.catchUpTime){internal.time.deltaTime+=internal.time.behindTime*internal.time.speed;internal.time.behindTime=0;$d.LogWarning("Main timeline reached.")}else{internal.time.deltaTime+=internal.time.catchUpTime*internal.time.speed;internal.time.behindTime-=internal.time.catchUpTime*internal.time.speed}}}}if(internal.time.elapsedLastClear>=internal.time.intervalClear){internal.time.elapsedLastClear=0;clearInterval(internal.time.interval);ReStartInterval()}else{Update()}}else{internal.controlVars.update.exceeded+=1;internal.time.lossedFrames+=1;if(internal.controlVars.update.exceeded>=internal.controlVars.update.alert){$d.LogWarning("Loosing frames, consider using a lower maxFPS("+internal.time.FPS+") value or reivew your code.");internal.controlVars.update.alerted=true}}},1000/internal.time.maxFPS)}function ReStartInterval(){setTimeout(function(){internal.controlVars.update.finish=true;internal.time.interval=StartInterval()},internal.time.intervalRestartDelay)}function Update(){try{internal.user.udpate({FPS:internal.time.FPS,deltaTime:internal.time.deltaTime,totalTime:internal.time.elapsedTime,selected:internal.mouse.selected,over:internal.mouse.over,screenSize:internal.size,mouse:{pos:internal.mouse.obj.getPos()},camera:internal.camera.obj,zoom:internal.camera.zoom,objects:internal.layers});internal.inputs["mousewheel"]=0}catch(e){$d.LogError("Error in User Update function",e)}UpdatePhysics();DrawObjects();DrawMousePosition();DrawDebug();DrawConsole();internal.controlVars.update.finish=true}function DrawFPS(){internal.ctx.font="12px Arial";internal.ctx.fillStyle="#000";internal.ctx.fillText("FPS: "+Math.round(internal.time.FPS),10,10)}function DrawMousePosition(){var msg='Mouse position: '+internal.mouse.obj.getPos().toString(0);internal.ctx.font='8pt Calibri';internal.ctx.fillStyle=internal.textcolor;internal.ctx.fillText(msg,10,25)}function DrawConsole(){}function DrawDebug(){var offset=0;for(var i=internal.debugVars.length-1;i>=0;i-=1){if(internal.debugVars[i].duration==undefined||internal.debugVars[i].duration>0){var finalObj=internal.debugVars[i].obj;for(var x=0;x<internal.debugVars[i].vars.length;x+=1){finalObj=finalObj[internal.debugVars[i].vars[x]]}var msg="";if(finalObj.x!=undefined){msg=internal.debugVars[i].name+":\t"+finalObj.toString(2)}else{msg=internal.debugVars[i].name+":\t"+finalObj}internal.ctx.font='7pt Calibri';internal.ctx.fillStyle='black';internal.ctx.fillText(msg,10,internal.size.y-10*(internal.debugVars.length-i-offset));if(internal.debugVars[i].duration!=undefined){internal.debugVars[i].duration-=1}}else{offset+=1}}}function UpdateMousePos(canvas,evt){var rect=canvas.getBoundingClientRect();internal.mouse.obj.setPos(new $e.Vector2((evt.clientX-rect.left+internal.camera.obj.getPos().x)*(1/internal.camera.zoom),(internal.size.y-evt.clientY+rect.top-internal.camera.obj.getPos().y)*(1/internal.camera.zoom)));internal.mouse.over=CheckCollision(internal.mouse.obj,true)}function UpdateMouseAction(evt,active){switch(evt.button){case 0:internal.mouse.click.left=active;internal.inputs.ClickLeft=active;if(active){if(internal.mouse.over!=undefined){if(internal.mouse.over.collider.selectable){if(evt.shiftKey){var ind=internal.mouse.selected.indexOf(internal.mouse.over);if(ind!=-1){var last=internal.mouse.selected.slice(ind+1);internal.mouse.selected.splice(0,ind);for(var i=0;i<last.length;i+=1){internal.mouse.selected.push(last[i])}}else{internal.mouse.selected.push(internal.mouse.over)}}else{internal.mouse.selected=[internal.mouse.over]}}}else{internal.mouse.selected=[]}}break;case 1:internal.mouse.click.middle=active;internal.inputs.ClickMiddle=active;break;case 2:internal.mouse.click.right=active;internal.inputs.ClickRight=active;break;default:break}}function UpdateInputs(evt,press){if(evt.code=="mousewheel"){internal.inputs[evt.code]+=press}else{internal.inputs[evt.code]=press}if(evt.code!="F11"){if(evt.preventDefault!=undefined){evt.preventDefault()}}}function UpdatePhysics(){var objA;for(var i=0;i<internal.phycs.length;i+=1){objA=internal.phycs[i];if(objA.lookAtTarget!=undefined){objA.angularVelocity=0;objA.lookAt(objA.lookAtTarget)}if(!objA.kinematic){CheckCollision(objA,false);objA.collider.checked=internal.time.elapsedTime;objA.rotation+=objA.angularVelocity*internal.time.deltaTime;objA.rotation=objA.rotation%360;objA.angularVelocity*=objA.angularDrag;objA.velocity.x+=objA.force.x/objA.mass;objA.velocity.y-=internal.world.gravity;objA.velocity.y+=objA.force.y/objA.mass;objA.setPos(objA.getPos().sum(objA.velocity.multiply(internal.time.deltaTime)));if(objA.newtonian){for(var j=0;j<internal.phycs.length;j+=1){var objB=internal.phycs[j];if(objB!=objA){if(objB.newtonian){var dist=objB.getPos().substract(objA.getPos());var dir=dist.normalized();dist=dist.magnitude();var f=constants.g*((objA.mass*objB.mass)/dist);dir.scale(f);objA.addForce(dir)}}}}}}}function CheckCollision(obj,retObj){var objA=obj;var objB;var v3=new $e.Vector2(0,0);objA.collisions=0;for(var i=0;i<internal.phycs.length;i+=1){objB=internal.phycs[i];if(true){if(objB!=objA&&(!objA.kinematic||!objB.kinematic)){v3.copy(objB.getPos().substract(objA.getPos()));var dist=v3.magnitude();dist=dist-objA.collider.maxRadius-objB.collider.maxRadius;if((dist)<0){var Na,Nb,sep;var contactPA,contactPB;var trueCollide=false;var circlepolygon=false;if(objA.collider.type==1&&objB.collider.type==1){if(retObj){return objB}trueCollide=true;var dir=objB.getPos().substract(objA.getPos()).normalized();sep=dir.multiply(objA.getPos().substract(objB.getPos()).magnitude()-objA.collider.maxRadius-objB.collider.maxRadius);Na=objA.getPos().substract(objB.getPos()).normalized();Nb=objB.getPos().substract(objA.getPos()).normalized();contactPA=dir.multiply(objA.collider.radius);contactPB=dir.multiply(-objB.collider.radius)}else if(objA.collider.type==1&&(objB.collider.type==0||objB.collider.type==2)){circlepolygon=true;var closest={vertex:-1,distance:vbn};if(closest.vertex==-1){for(var j=0;j<objB.collider.vertexs.length;j+=1){var aV=objB.collider.vertexs[j].rrotate(objB.rotation).sum(objB.getPos());var bV;var p=objA.getPos();if(j==objB.collider.vertexs.length-1){bV=objB.collider.vertexs[0].rrotate(objB.rotation).sum(objB.getPos())}else{bV=objB.collider.vertexs[j+1].rrotate(objB.rotation).sum(objB.getPos())}var resp=pnt2line(p,aV,bV);if(resp.dist<objA.collider.radius){if(closest.distance>resp.dist){closest.distance=resp.dist;closest.vertex=j;closest.dir=resp.nearest.substract(p).normalized();contactPB=resp.nearest.substract(objB.getPos());contactPA=closest.dir.multiply(objA.collider.radius)}}}}if(closest.vertex!=-1){if(retObj){return objB}trueCollide=true;sep=closest.dir.multiply(closest.distance-objA.collider.maxRadius);Na=objB.collider.normals[closest.vertex].clone();Na.rotate(objB.rotation);MTDb=new $e.Vector2(0,0);Nb=objA.getPos().substract(objB.getPos()).normalized()}}else if(objB.collider.type==1&&(objA.collider.type==0||objA.collider.type==2)){circlepolygon=true;var closest={vertex:-1,distance:vbn};if(closest.vertex==-1){for(var j=0;j<objA.collider.vertexs.length;j+=1){var aV=objA.collider.vertexs[j].rrotate(objA.rotation).sum(objA.getPos());var bV;var p=objB.getPos();if(j==objA.collider.vertexs.length-1){bV=objA.collider.vertexs[0].rrotate(objA.rotation).sum(objA.getPos())}else{bV=objA.collider.vertexs[j+1].rrotate(objA.rotation).sum(objA.getPos())}var resp=pnt2line(p,aV,bV);if(resp.dist<objB.collider.radius){if(closest.distance>resp.dist){closest.distance=resp.dist;closest.vertex=j;closest.dir=resp.nearest.substract(p).normalized();contactPA=resp.nearest.substract(objA.getPos());contactPB=closest.dir.multiply(objB.collider.radius)}}}}if(closest.vertex!=-1){if(retObj){return objB}trueCollide=true;sep=closest.dir.multiply(closest.distance-objB.collider.maxRadius);Na=objA.collider.normals[closest.vertex].clone();Na.rotate(objA.rotation);MTDb=new $e.Vector2(0,0);Nb=objB.getPos().substract(objA.getPos()).normalized()}}else{var MTD2=Intersect(obj,objB);if(MTD2.intersect){if(retObj){return objB}trueCollide=true;var b=FindAxisLeastPenetration(objB,obj);MTDa=new $e.Vector2(0,0);Na=objB.collider.normals[b.vertexIndex].clone();Na.rotate(objB.rotation);contactPB=objB.collider.vertexs[b.vertexIndex];var a=FindAxisLeastPenetration(obj,objB);MTDb=new $e.Vector2(0,0);Nb=objA.collider.normals[a.vertexIndex].clone();Nb.rotate(objA.rotation);contactPA=objA.collider.vertexs[a.vertexIndex];sep=MTD2.mtd}}if(trueCollide){objA.collisions+=1;var rf=(objA.bounce+objB.bounce)/2;var ja,jb;if(circlepolygon){jb=rf*((objA.velocity.multiply(objA.mass-objB.mass).sum(objB.velocity.multiply(objB.mass*2)).magnitude())/(objA.mass+objB.mass));ja=rf*((objB.velocity.multiply(objB.mass-objA.mass).sum(objA.velocity.multiply(objA.mass*2)).magnitude())/(objB.mass+objA.mass))}else{ja=rf*((objA.velocity.multiply(objA.mass-objB.mass).sum(objB.velocity.multiply(objB.mass*2)).magnitude())/(objA.mass+objB.mass));jb=rf*((objB.velocity.multiply(objB.mass-objA.mass).sum(objA.velocity.multiply(objA.mass*2)).magnitude())/(objB.mass+objA.mass))}var Vea=objA.velocity.clone();var dota=Vea.dot(Na);dota=-2*dota;Na.scale(dota);var MTDa=Vea.sum(Na);objA.applyImpulse(MTDa.normalized().multiply(ja),contactPA);var Veb=objB.velocity.clone();var dotb=Veb.dot(Nb);dotb=-2*dotb;Nb.scale(dotb);var MTDb=Veb.sum(Nb);objB.applyImpulse(MTDb.normalized().multiply(jb),contactPB);if(objA.kinematic){objB.setPos(objB.getPos().substract(sep))}else if(objB.kinematic){objA.setPos(objA.getPos().sum(sep))}else{objA.setPos(objA.getPos().sum(sep.multiply(objB.mass/(objB.mass+objA.mass))));objB.setPos(objB.getPos().substract(sep.multiply(objA.mass/(objB.mass+objA.mass))))}}}}}}}function pnt2line(pnt,start,end){var line_vec=end.substract(start);var pnt_vec=pnt.substract(start);var line_len=line_vec.magnitude();var line_unitvec=line_vec.normalized();var pnt_vec_scaled=pnt_vec.multiply(1.0/line_len);var t=line_unitvec.dot(pnt_vec_scaled);if(t<0){t=0}else if(t>1){t=1}var nearest=line_vec.multiply(t);var dist=nearest.substract(pnt_vec).magnitude();nearest=nearest.sum(start);return{dist:dist,nearest:nearest}}function GetSupport(obj,dir){var bestProjection= -vbn;var bestVertex=new $e.Vector2(0,0);for(var i=0;i<obj.collider.vertexs.length;i+=1){var vr=obj.collider.vertexs[i].clone();vr.rotate(obj.rotation);var v=obj.getPos().sum(vr);var projection=dir.dot(v);if(projection>bestProjection){bestVertex=v;bestProjection=projection}}return bestVertex}function FindAxisLeastPenetration(A,B){var bestDistance= -vbn;var bestIndex;for(var i=0;i<A.collider.vertexs.length;i+=1){var n=A.collider.normals[i].clone();n.rotate(A.rotation);var s=GetSupport(B,n.multiply(-1));var vr=new $e.Vector2(A.collider.vertexs[i].x,A.collider.vertexs[i].y);vr.rotate(A.rotation);var v=new $e.Vector2(vr.x+A.getPos().x,vr.y+A.getPos().y);var sv=new $e.Vector2(s.x-v.x,s.y-v.y);var d=n.dot(sv);if(d>bestDistance){bestDistance=d;bestIndex=i}}return{bestDistance:bestDistance,vertexIndex:bestIndex}}function Intersect(A,B){var Axis=[];var iNumAxis=0;var J=A.collider.vertexs.length-1;for(var I=0;I<A.collider.vertexs.length;I+=1){var E=(A.collider.vertexs[I].rrotate(A.rotation).sum(A.getPos())).substract(A.collider.vertexs[J].rrotate(A.rotation).sum(A.getPos()));var N=Axis[iNumAxis++]=new $e.Vector2(-E.y,E.x);if(AxisSeparatePolygons(N,A,B)){return false}J=I}J=B.collider.vertexs.length-1;for(var I=0;I<B.collider.vertexs.length;I+=1){var E=(B.collider.vertexs[I].sum(B.getPos()).rrotate(B.rotation)).substract(B.collider.vertexs[J].rrotate(B.rotation).sum(B.getPos()));var N=Axis[iNumAxis++]=new $e.Vector2(-E.y,E.x);if(AxisSeparatePolygons(N,A,B)){return false}J=I}var MTD=FindMTD(Axis,iNumAxis);var D=A.getPos().substract(B.getPos());if(D.dot(MTD)<0.0){MTD.scale(-1)}return{intersect:true,mtd:MTD}}function CalculateInterval(Axis,P){var min,max;var d=Axis.dot(P.collider.vertexs[0].rrotate(P.rotation).sum(P.getPos()));min=max=d;for(var I=0;I<P.collider.vertexs.length;I+=1){var d=(P.collider.vertexs[I].rrotate(P.rotation).sum(P.getPos())).dot(Axis);if(d<min){min=d}else if(d>max){max=d}}return{min:min,max:max}}function AxisSeparatePolygons(Axis,A,B){var a=CalculateInterval(Axis,A);var b=CalculateInterval(Axis,B);if(a.min>b.max||b.min>a.max){return true}var d0=a.max-b.min;var d1=b.max-a.min;var depth=(d0<d1)?d0:d1;var axis_length_squared=Axis.dot(Axis);Axis.scale(depth/axis_length_squared);return false}function FindMTD(PushVectors,iNumVectors){var MTD=PushVectors[0].clone();var mind2=MTD.dot(MTD);for(var I=1;I<iNumVectors;I+=1){var d2=PushVectors[I].dot(PushVectors[I]);if(d2<mind2){mind2=d2;MTD=PushVectors[I].clone()}}return MTD}function DrawObjects(){internal.size.x=internal.ctx.canvas.width=internal.canvas.clientWidth;internal.size.y=internal.ctx.canvas.height=internal.canvas.clientHeight;internal.ctx.globalAlpha=internal.globals.opacity;internal.ctx.fillStyle=internal.globals.background;internal.ctx.fillRect(0,0,internal.size.x,internal.size.y);internal.ctx.globalAlpha=1;for(var i=0;i<internal.layers.length;i+=1){for(var f=0;f<internal.layers[i].length;f+=1){Draw(internal.layers[i][f])}}}function Draw(obj){if(internal.debug){internal.ctx.fillStyle=obj.color;var tv=new $e.Vector2((obj.getPos().x-internal.camera.obj.getPos().x)*internal.camera.zoom+(internal.size.x*internal.camera.zoom/2),(internal.size.y-obj.getPos().y+internal.camera.obj.getPos().y)*internal.camera.zoom+(internal.size.y*internal.camera.zoom/2));tv.toFixed(0);internal.ctx.setTransform(internal.camera.zoom,0,0,internal.camera.zoom,tv.x,tv.y);var rot=obj.rotation*Math.PI/180;internal.ctx.rotate(-rot);if(internal.mouse.over==obj){internal.ctx.shadowBlur=2;internal.ctx.shadowColor="#3c84c1"}if(obj.texture!=undefined){internal.ctx.drawImage(obj.texture.getTexture(),-obj.texture.size.x/2,-obj.texture.size.y/2,obj.texture.size.x,obj.texture.size.y)}else{if(obj.collider.type==1){internal.ctx.fillRect(-10/2,-10/2,10,10)}else{internal.ctx.fillRect(-10/2,-10/2,10,10)}}if(internal.debug){internal.ctx.globalAlpha=0.1;internal.ctx.fillStyle="#F22";internal.ctx.beginPath();internal.ctx.arc(obj.pivot.x,-obj.pivot.y,5,0,2*Math.PI);internal.ctx.fill();internal.ctx.globalAlpha=internal.globals.opacity;if(obj.collider!=undefined){internal.ctx.beginPath();if(obj.collider.type==1){internal.ctx.arc(0,0,obj.collider.radius,0,2*Math.PI)}else{internal.ctx.moveTo(obj.collider.vertexs[obj.collider.vertexs.length-1].x,obj.collider.vertexs[obj.collider.vertexs.length-1].y);for(var i=0;i<obj.collider.vertexs.length;i+=1){internal.ctx.lineTo(obj.collider.vertexs[i].x,obj.collider.vertexs[i].y)}}internal.ctx.strokeStyle='#F00';internal.ctx.stroke();internal.ctx.fillStyle="#FA0";if(obj.collider.contactPoint!=undefined){internal.ctx.fillRect(obj.collider.vertexs[obj.collider.contactPoint].x-2,(obj.collider.vertexs[obj.collider.contactPoint].y)-2,4,4)}}}internal.ctx.rotate(rot);internal.ctx.font='6pt Calibri';internal.ctx.fillStyle=internal.textcolor;internal.ctx.fillText(obj.name,0,0);internal.ctx.setTransform(1,0,0,1,0,0);internal.ctx.shadowBlur=0;}}this.Vector2=function(x,y){this.x=x;this.y=y};this.Texture=function(name,srcs,size,time,loop){this.name=name;this.loop=loop;this.time=time;this.size=size;this.img=[];for(var i=0;i<srcs.length;i+=1){var tempImg=new Image();tempImg.src=srcs[i];this.img.push(tempImg)}this.counter=0;this.frameTime=time/this.img.length};this.Texture.prototype.getTexture=function(){if(this.img.length==1){return this.img[0]}this.counter+=internal.time.deltaTime*1000;if(this.counter>this.time){this.counter=0}var ret=this.img[Math.floor(this.counter/this.frameTime)];return ret};this.BaseObject2D=function(name,pos){this.id=-1;this.name=name;this.posOrigin=pos.clone();this.scale=new $e.Vector2(1,1);this.rotation=0;this.pivot=new $e.Vector2(0,0);this.lookAtTarget=undefined;this.lookAtOffset=0;this.color="#DDD";this.layer=-99;this.parent=null;this.childs=[]};class Object2D extends this.BaseObject2D{constructor(name,pos,mass,drag,angularDrag,bounce,newtonian){super(name,pos);this.kinematic=(mass==0);this.mass=((mass==0)?1:mass);this.newtonian=(newtonian==undefined)?false:newtonian;this.drag=drag;this.angularDrag=angularDrag;this.bounce=bounce;this.setInertia(1);this.angularVelocity=0;this.velocity=new $e.Vector2(0,0);this.force=new $e.Vector2(0,0);this.collisions=0}}this.BaseObject2D.prototype.getPos=function(){if(this.parent!=null){return this.posOrigin.sum(this.parent.getPos())}else{return this.posOrigin}};this.BaseObject2D.prototype.setPos=function(v2){var f;if(arguments.length==1){f=v2}else if(arguments.length==2&&!isNaN(parseFloat(arguments[0]))&&!isNaN(parseFloat(arguments[1]))){f=new $e.Vector2(arguments[0],arguments[1])}else{$d.LogError("Invalid value, expected Vector2");return}if(this.parent!=null){this.posOrigin.copy(f.substract(this.parent.getPos()))}else{this.posOrigin.copy(f)}};this.BaseObject2D.prototype.setParent=function(parent){if(this.parent!=null){this.parent.childs.splice(this.parent.childs.indexOf(this),1)}this.parent=parent;this.parent.childs.push(this);this.offSetPos=this.getPos()};Object2D.prototype.setInertia=function(value){this.inertia=value;this.inverseInertia=(value!=0)?1/value:0};this.BaseObject2D.prototype.setPivot=function(position){this.setPos(this.posOrigin);this.pivot=position;this.setPos(this.getPos().sum(this.pivot.rrotate(this.rotation)))};Object2D.prototype.addForce=function(force,forceType){if(!this.kinematic){if(forceType==undefined||forceType==0){this.velocity.x+=force.x/this.mass;this.velocity.y+=force.y/this.mass}else{this.force.x+=force.x;this.force.y+=force.y}}};Object2D.prototype.applyImpulse=function(impulse,contactVector){if(!this.kinematic){this.velocity=impulse.clone();var rot= -this.inverseInertia*contactVector.normalized().cross(impulse);this.angularVelocity+=rot}};Object2D.prototype.setCollider=function(collider,noadd){if(noadd==undefined||!noadd){if(this.collider==undefined){internal.phycs.push(this)}}this.collider=collider};this.BaseObject2D.prototype.lookAt=function(Obj2){this.setPos(this.posOrigin);var target=Obj2.getPos().substract(this.getPos());this.rotation=(target.angle()*(180/Math.PI)-180)+this.lookAtOffset;this.setPos(this.getPos().sum(this.pivot.rrotate(this.rotation)))};this.Object2D=Object2D;this.BoxCollider=function(width,height){$e.BaseCollider.call(this,0);this.vertexs=[new $e.Vector2(-width/2,height/2),new $e.Vector2(width/2,height/2),new $e.Vector2(width/2,-height/2),new $e.Vector2(-width/2,-height/2)];this.calculateNormals()};this.CircleCollider=function(radius){$e.BaseCollider.call(this,1);this.radius=radius;this.maxRadius=radius};this.PolygonCollider=function(vertexs){if(typeof vertexs=="object"){if(vertexs.length>=3){$e.BaseCollider.call(this,2);this.vertexs=vertexs;this.calculateNormals()}else{$d.LogError("The polygon collider needs at least 3 points")}}else{$d.LogError("Invalid value, expected Array")}};this.BaseCollider=function(type){this.selectable=true;this.type=type;this.contactPoint;this.vertexs=[];this.normals=[];this.checked=false;this.maxRadius= -vbn;this.checked=0};this.PolygonCollider.prototype.calculateNormals=this.BoxCollider.prototype.calculateNormals=function(){for(var i=0;i<this.vertexs.length;i+=1){var next=i+1;if(next==this.vertexs.length){next=0}this.normals.push(this.vertexs[i].normal(this.vertexs[next]).normalized());var dist=this.vertexs[i].magnitude();if(this.maxRadius<dist){this.maxRadius=dist}}};this.Vector2.prototype.sum=function(v2){return new $e.Vector2(this.x+v2.x,this.y+v2.y)};this.Vector2.prototype.substract=function(v2){return new $e.Vector2(this.x-v2.x,this.y-v2.y)};this.Vector2.prototype.multiply=function(mul){return new $e.Vector2(this.x*mul,this.y*mul)};this.Vector2.prototype.scale=function(mul){this.x=this.x*mul;this.y=this.y*mul};this.Vector2.prototype.normalize=function(){if(this.x!=0&&this.y!=0){var l=this.magnitude();this.x=this.x/l;this.y=this.y/l}};this.Vector2.prototype.normalized=function(){if(this.x==0&&this.y==0){return this}var l=this.magnitude();return new $e.Vector2(this.x/l,this.y/l)};this.Vector2.prototype.magnitude=function(){return Math.sqrt((this.x*this.x)+(this.y*this.y))};this.Vector2.prototype.dot=function(v2){return((this.x*v2.x)+(this.y*v2.y))};this.Vector2.prototype.cross=function(v2){return((this.x*v2.y)-(v2.x*this.y))};this.Vector2.prototype.angle=function(v2){if(v2==undefined){return Math.atan2(this.y,this.x)}else{return Math.atan2(v2.y-this.y,v2.x-this.x)}};this.Vector2.prototype.normal=function(v2){return new $e.Vector2(-(v2.y-this.y),v2.x-this.x)};this.Vector2.prototype.rotate=function(angle){var radians=angle*(Math.PI/180);var cosa=Math.cos(radians);var sina=Math.sin(radians);var tempX=this.x*cosa-this.y*sina;var tempY=this.x*sina+this.y*cosa;if(Math.abs(tempX)<vln){tempX=0}if(Math.abs(tempY)<vln){tempY=0}this.x=tempX;this.y=tempY};this.Vector2.prototype.rrotate=function(angle){var v2=new $e.Vector2(this.x,this.y);v2.rotate(angle);return v2};this.Vector2.prototype.swap=function(){var tX=this.x;this.x=this.y;this.y=tX};this.Vector2.prototype.toFixed=function(fix){this.x=this.x.toFixed(fix);this.y=this.y.toFixed(fix)};this.Vector2.prototype.clone=function(){return new $e.Vector2(this.x,this.y)};this.Vector2.prototype.copy=function(v2){this.x=v2.x;this.y=v2.y};this.Vector2.prototype.toString=function(fixed){if(fixed!=undefined){return "("+this.x.toFixed(fixed)+","+this.y.toFixed(fixed)+")"}else{return "("+this.x+","+this.y+")"}};}window.$e=$e})(window);