-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
1 lines (1 loc) · 9.64 KB
/
index.js
1
export function startGame(p={}){const le=/Chrome/.test(navigator.userAgent)&&/Google Inc/.test(navigator.vendor),a=p.width||640,r=p.height||640,oe="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAEACAYAAAADRnAGAAACGUlEQVR42u3aSQ7CMBAEQIsn8P+/hiviAAK8zFIt5QbELiTHmfEYE3L9mZE9AAAAqAVwBQ8AAAD6THY5CgAAAKbfbPX3AQAAYBEEAADAuZrC6UUyfMEEAIBiAN8OePXnAQAAsLcmmKFPAQAAgHMbm+gbr3Sdo/LtcAAAANR6GywPAgBAM4D2JXAAABoBzBjA7AmlOx8AAEAzAOcDAADovTc4vQim6wUCABAYQG8QAADd4dPd2fRVYQAAANQG0B4HAABAawDnAwAA6AXgfAAAALpA2uMAAABwPgAAgPoAM9Ci/R4AAAD2dmqcEQIAIC/AiQGuAAYAAECcRS/a/cJXkUf2AAAAoBaA3iAAALrD+gIAAADY9baX/nwAAADNADwFAADo9YK0e5FMX/UFACA5QPSNEAAAAHKtCekmDAAAAADvBljtfgAAAGgMMGOrunvCy2uCAAAACFU6BwAAwF6AGQPa/XsAAADYB+B8AAAAtU+ItD4OAwAAAFVhAACaA0T7B44/BQAAANALwGMQAAAAADYO8If2+P31AgAAQN0SWbhFDwCAZlXgaO1xAAAA1FngnA8AACAeQPSNEAAAAM4CnC64AAAA4GzN4N9NSfgKEAAAAACszO26X8/X6BYAAAD0Anid8KcLAAAAAAAAAJBnwNEvAAAA9Jns1ygAAAAAAAAAAAAAAAAAAABAQ4COCENERERERERERBrnAa1sJuUVr3rsAAAAAElFTkSuQmCC",w=37,x=39,ae=32,re=500,ce={x:0,y:204,w:62,h:32},ue=[{x:0,y:0,w:51,h:34},{x:0,y:102,w:51,h:34}],he=[{x:0,y:137,w:50,h:33},{x:0,y:170,w:50,h:34}],Ae=[{x:0,y:68,w:50,h:32},{x:0,y:34,w:50,h:32}],I=40,me=11*I;function de(i,e){return Math.random()*(e-i)+i}function pe(i,e,t){return Math.min(Math.max(i,e),t)}function E(i,e,t){return i<=t&&i>=e}function Q(i,e){const t=E(i.x,e.x,e.x+e.w)||E(e.x,i.x,i.x+i.w),n=E(i.y,e.y,e.y+e.h)||E(e.y,i.y,i.y+i.h);return t&&n}class O{x;y;constructor(e,t){this.x=typeof e>"u"?0:e,this.y=typeof t>"u"?0:t}set(e,t){this.x=e,this.y=t}}class be{x;y;w;h;constructor(e,t,n,s){this.x=typeof e>"u"?0:e,this.y=typeof t>"u"?0:t,this.w=typeof n>"u"?0:n,this.h=typeof s>"u"?0:s}set(e,t,n,s){this.x=e,this.y=t,this.w=n,this.h=s}}let A,l,f,S,u=[],M=[],N=0,o,h=[],v,R=!1,g=-1,P=0,y=0,H=1,m=!1;class G{img;position;scale;bounds;doLogic;constructor(e,t,n){this.img=e,this.position=new O(t,n),this.scale=new O(1,1),this.bounds=new be(t,n,this.img.width,this.img.height),this.doLogic=!0}update(e){}_updateBounds(){this.bounds.set(this.position.x,this.position.y,~~(.5+this.img.width*this.scale.x),~~(.5+this.img.height*this.scale.y))}_drawImage(){l.drawImage(this.img,this.position.x,this.position.y)}draw(e){this._updateBounds(),this._drawImage()}}class Y extends G{clipRect;constructor(e,t,n,s){super(e,n,s),this.clipRect=t,this.bounds.set(n,s,this.clipRect.w,this.clipRect.h)}update(e){}_updateBounds(){const e=~~(.5+this.clipRect.w*this.scale.x),t=~~(.5+this.clipRect.h*this.scale.y);this.bounds.set(this.position.x-e/2,this.position.y-t/2,e,t)}_drawImage(){l.save(),l.transform(this.scale.x,0,0,this.scale.y,this.position.x,this.position.y),l.drawImage(this.img,this.clipRect.x,this.clipRect.y,this.clipRect.w,this.clipRect.h,~~(.5+-this.clipRect.w*.5),~~(.5+-this.clipRect.h*.5),this.clipRect.w,this.clipRect.h),l.restore()}draw(e){super.draw(e)}}class fe extends Y{lives;xVel;bullets;bulletDelayAccumulator;score;constructor(){super(f,ce,a/2,r-70),this.scale.set(.85,.85),this.lives=3,this.xVel=0,this.bullets=[],this.bulletDelayAccumulator=0,this.score=0}reset(){this.lives=3,this.score=0,this.position.set(a/2,r-70)}shoot(){const e=new K(this.position.x,this.position.y-this.bounds.h/2,1,1e3);this.bullets.push(e),C("shoot")}handleInput(){X(w)?this.xVel=-175:X(x)?this.xVel=175:this.xVel=0,U(ae)&&this.bulletDelayAccumulator>.5&&(this.shoot(),this.bulletDelayAccumulator=0)}updateBullets(e){for(let t=this.bullets.length-1;t>=0;t--){let n=this.bullets[t];n.alive?n.update(e):(this.bullets.splice(t,1),n=void 0)}}update(e){this.bulletDelayAccumulator+=e,this.position.x+=this.xVel*e,this.position.x=pe(this.position.x,this.bounds.w/2,a-this.bounds.w/2),this.updateBullets(e)}draw(e){super.draw(e);for(let t=0,n=this.bullets.length;t<n;t++){const s=this.bullets[t];s.alive&&s.draw(e)}}}class K extends G{direction;speed;alive;constructor(e,t,n,s){super(S,e,t),this.direction=n,this.speed=s,this.alive=!0}update(e){this.position.y-=this.speed*this.direction*e,this.position.y<0&&(this.alive=!1)}draw(e){super.draw(e)}}class ge extends Y{clipRects;onFirstState;stepDelay;stepAccumulator;doShoot;bullet;alive;constructor(e,t,n){super(f,e[0],t,n),this.clipRects=e,this.scale.set(.5,.5),this.alive=!0,this.onFirstState=!0,this.stepDelay=1,this.stepAccumulator=0,this.doShoot=!1,this.bullet=void 0}toggleFrame(){this.onFirstState=!this.onFirstState,this.clipRect=this.onFirstState?this.clipRects[0]:this.clipRects[1]}shoot(){this.bullet=new K(this.position.x,this.position.y+this.bounds.w/2,-1,500)}update(e){if(this.stepAccumulator+=e,this.stepAccumulator>=this.stepDelay){this.position.x<this.bounds.w/2+20&&g<0&&(R=!0),g===1&&this.position.x>a-this.bounds.w/2-20&&(R=!0),this.position.y>a-50&&Ee();const t=Math.floor(Math.random()*(this.stepDelay+1));de(0,1e3)<=5*(this.stepDelay+1)&&(this.doShoot=!0),this.position.x+=10*g,this.toggleFrame(),this.stepAccumulator=0}this.position.y+=P,this.bullet&&this.bullet.alive?this.bullet.update(e):this.bullet=void 0}draw(e){super.draw(e),this.bullet!==void 0&&this.bullet.alive&&this.bullet.draw(e)}}class ye{particlePool;particles;constructor(){this.particlePool=[],this.particles=[]}draw(){for(let e=this.particles.length-1;e>=0;e--){const t=this.particles[e];t.moves++,t.x+=t.xunits,t.y+=t.yunits+t.gravity*t.moves,t.life--,t.life<=0?this.particlePool.length<100?this.particlePool.push(this.particles.splice(e,1)):this.particles.splice(e,1):(l.globalAlpha=t.life/t.maxLife,l.fillStyle=t.color,l.fillRect(t.x,t.y,t.width,t.height),l.globalAlpha=1)}}createExplosion(e,t,n,s,d,b,j,Z,$){for(let ee=0;ee<s;ee++){const _e=Math.floor(Math.random()*360),te=Math.floor(Math.random()*j/2)+j,D=Math.floor(Math.random()*$)+$/2,ie=_e*Math.PI/180,ne=Math.cos(ie)*te,se=Math.sin(ie)*te;if(this.particlePool.length>0){const c=this.particlePool.pop();c.x=e,c.y=t,c.xunits=ne,c.yunits=se,c.life=D,c.color=n,c.width=d,c.height=b,c.gravity=Z,c.moves=0,c.alpha=1,c.maxLife=D,this.particles.push(c)}else this.particles.push({x:e,y:t,xunits:ne,yunits:se,life:D,color:n,width:d,height:b,gravity:Z,moves:0,alpha:1,maxLife:D})}}}function we(){if(p.canvas)A=p.canvas;else{const i=p.selector||"#invaders",e=document.querySelector(i)||document.body;A=document.createElement("canvas"),e.appendChild(A)}A.width=a,A.height=r,l=A.getContext("2d"),k(!1),f=new Image,f.src=oe,xe(),window.addEventListener("resize",J),document.addEventListener("keydown",Fe),document.addEventListener("keyup",Be)}function xe(){const i=Me(2,8,e=>{e.fillStyle="white",e.fillRect(0,0,e.canvas.width,e.canvas.height)});S=new Image,S.src=i.toDataURL()}function k(i){l.imageSmoothingEnabled=i,l.mozImageSmoothingEnabled=i,l.oImageSmoothingEnabled=i,l.webkitImageSmoothingEnabled=i,l.msImageSmoothingEnabled=i}function L(){h=[],o=new fe,v=new ye,T(),W()}function T(){y=0;for(let i=0,e=5*11;i<e;i++){const t=i%11,n=Math.floor(i/11);let s=[];switch(n){case 0:case 1:s=ue;break;case 2:case 3:s=he;break;case 4:s=Ae;break}h.push(new ge(s,a/2-me/2+I/2+t*I,r/3.25-n*40)),y++}}function Ee(){h=[],T(),o.reset()}function ve(){we(),u=[],M=[],J()}function X(i){return u[i]}function U(i){return!M[i]&&u[i]}function Re(i){R&&(R=!1,g=-g,P=25);for(let e=h.length-1;e>=0;e--){let t=h[e];if(!t.alive){h.splice(e,1),t=void 0,y--,y<1&&(H++,T());return}if(t.stepDelay=(y*20-H*10)/1e3,t.stepDelay<=.05&&(t.stepDelay=.05),t.update(i),t.doShoot){t.doShoot=!1,t.shoot();const n=String(Math.round(Math.random()*3+1));C(`fastinvader${n}`)}}P=0}function Ce(){const i=o.bullets;for(let e=0,t=i.length;e<t;e++){const n=i[e];for(let s=0,d=h.length;s<d;s++){const b=h[s];Q(n.bounds,b.bounds)&&(b.alive=n.alive=!1,C("invaderkilled"),v.createExplosion(b.position.x,b.position.y,"white",70,5,5,3,.15,50),o.score+=25)}}}function De(){for(let i=0,e=h.length;i<e;i++){const t=h[i];if(t.bullet&&Q(t.bullet.bounds,o.bounds))if(o.lives===0)m=!1;else{C("explosion"),t.bullet.alive=!1,v.createExplosion(o.position.x,o.position.y,"green",100,8,8,6,.001,40),o.position.set(a/2,r-70),o.lives--;break}}}function Ie(){Ce(),De()}function Se(i){o.handleInput(),M=u.slice(),o.update(i),Re(i),Ie()}function Me(i,e,t){const n=document.createElement("canvas");n.width=i,n.height=e;const s=n.getContext("2d");return t(s),n}function F(i,e,t,n,s){typeof n<"u"&&(l.fillStyle=n),typeof s<"u"&&(l.font=s+"px Play"),l.fillText(i,e,t)}function B(i,e,t,n,s){const d=l.measureText(i);F(i,e-d.width/2,t,n,s)}function V(i,e,t,n,s,d){~~(.5+Date.now()/n)%2&&B(i,e,t,s,d)}function W(){l.fillStyle="#02ff12",l.fillRect(0,r-30,a,2),F(o.lives+" x ",10,r-7.5,"white",20),l.drawImage(f,o.clipRect.x,o.clipRect.y,o.clipRect.w,o.clipRect.h,45,r-23,o.clipRect.w*.5,o.clipRect.h*.5),F("CREDIT: ",a-115,r-7.5),B("SCORE: "+o.score,a/2,20),V("00",a-25,r-7.5,re)}function Pe(i){for(let e=0;e<h.length;e++)h[e].draw(i)}function Le(i){o.draw(i),Pe(i),v.draw(),W()}function Te(){B(p.title||"Space Invaders",a/2,r/2.75,"#FFFFFF",36),V("Press enter to play!",a/2,r/2,500,"#FFFFFF",36)}function z(){const i=window.performance.now();let e=i-N;e>100&&(e=100),U(13)&&!m&&(L(),m=!0),m&&Se(e/1e3),l.fillStyle="black",l.fillRect(0,0,a,r),m?Le(!1):Te(),N=i,requestAnimationFrame(z)}function J(){const i=window.innerWidth,e=window.innerHeight,t=Math.min(i/a,e/r);le?(A.width=a*t,A.height=r*t,k(!1),l.transform(t,0,0,t,0,0)):(A.style.width=a*t+"px",A.style.height=r*t+"px")}function Fe(i){i.preventDefault(),u[i.keyCode]=!0}function Be(i){i.preventDefault(),u[i.keyCode]=!1}let q;document.addEventListener("touchstart",i=>{q={x:i.touches[0].clientX,y:i.touches[0].clientY},m?o.shoot():(L(),m=!0)}),document.addEventListener("touchmove",i=>{const t={x:i.touches[0].clientX,y:i.touches[0].clientY}.x-q.x;t>0?(u[x]=!0,u[w]=!1):t<0&&(u[w]=!0,u[x]=!1)}),document.addEventListener("touchend",i=>{u[w]=!1,u[x]=!1});const _=document.createElement("link");_.rel="stylesheet",_.href="https://fonts.googleapis.com/css?family=Play:400,700",document.head.appendChild(_),ve(),z(),p.autoPlay&&(L(),m=!0);async function C(i){}}