forked from sent/waves
93 lines
59 KiB
HTML
93 lines
59 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en-US">
|
|
<head>
|
|
|
|
<script src="/js/all.min.min.js"></script>
|
|
|
|
|
|
<style>canvas{padding-left:0;padding-right:0;border:1px solid grey}body{background-color:#141414;margin:0}a{color:#fff}a:hover{color:#ff0}.subheader{color:#fff;user-select:none;font-family:Arial}.column-left{float:left;width:33.333%;text-align:left}.column-center{display:inline-block;width:33.333%;text-align:center}.column-right{float:right;width:33.333%;text-align:right}.title{text-align:center;font-family:Arial;color:#fff;user-select:none}.wrapper{font-size:0;padding-top:10px;margin:0 auto;box-shadow:rgba(0,0,0,.16) 0 2px 4px 0,rgba(0,0,0,.12) 0 2px 10px 0}#titleWrapper{font-size:initial;padding-bottom:12px}#menuWrapper{border-left:1px solid grey;border-right:1px solid grey;border-bottom:1px solid grey;padding-bottom:3px;margin-bottom:15px;background-color:#3c3c3c;overflow:auto;font-family:Arial;font-size:14px;user-select:none;position:relative;color:#ff0;width:inherit}#elementTable{border-collapse:collapse;float:left}.elementMenuButton{background:0 0;border:none;text-align:left;user-select:none;width:100%;height:100%}.elementMenuButton:hover{background-color:#0a0a0a;color:#fff!important}.elementMenuButton:active{background-color:#646464;color:#fff!important}.selectedElementMenuButton{outline:1px solid white}.optionsCol{float:left}.spigotType{width:75px}#speedSliderDiv{margin-top:4px;margin-bottom:8px}#speedSlider{width:60px;height:10px;border-radius:5px;background-image:linear-gradient(to right,rgba(255,0,0,.8),rgba(0,128,0,.8));outline:0;-webkit-appearance:none}#optionsCol2{padding-left:4px}#fps-counter{position:absolute;bottom:1px;right:1px}.optionButton{font-size:inherit;font-family:inherit;user-select:none;border:none;outline:0}.optionButtonContainer{margin-top:4px}#clearButton:hover{background-color:red}#clearButton:active{background-color:#7b0000}#saveButton:hover{background-color:#0f0}#saveButton:active{background-color:#007b00}#loadButton:hover{background-color:#ff0}#loadButton:active{background-color:#7b7b00}#penSizeDiv{margin-bottom:2px}
|
|
</style>
|
|
<title>Sand Game</title>
|
|
</head>
|
|
<body>
|
|
<div class="wrapper" id="gameWrapper">
|
|
<div id="titleWrapper">
|
|
<h1 class="title">Sand Game v1.2</h1>
|
|
<div class="subheader">
|
|
<div class="column-left">
|
|
<a href="https://github.com/3kh0/" target="_blank">Source Code</a>
|
|
</div>
|
|
<div class="column-center">
|
|
By: 3kh0 and retronbv
|
|
</div>
|
|
<div class="column-right">
|
|
<a href="/">Website</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<br />
|
|
<canvas id="mainCanvas">Your browser doesn't support HTML5 canvas. :(</canvas>
|
|
<div id="menuWrapper">
|
|
<table id="elementTable"></table>
|
|
<div id="optionsCol1" class="optionsCol">
|
|
<div id="penSizeDiv">
|
|
<label for="pensize">Pen Size</label>
|
|
<select id="pensize"></select>
|
|
</div>
|
|
<div>
|
|
<select id="spigot1Type" class="spigotType"></select>
|
|
<select id="spigot1Size"></select>
|
|
</div>
|
|
<div>
|
|
<select id="spigot2Type" class="spigotType"></select>
|
|
<select id="spigot2Size"></select>
|
|
</div>
|
|
<div>
|
|
<select id="spigot3Type" class="spigotType"></select>
|
|
<select id="spigot3Size"></select>
|
|
</div>
|
|
<div>
|
|
<select id="spigot4Type" class="spigotType"></select>
|
|
<select id="spigot4Size"></select>
|
|
</div>
|
|
</div>
|
|
<div id="optionsCol2" class="optionsCol">
|
|
<div>
|
|
<label for="overwriteCheckbox">Overwrite</label>
|
|
<input type="checkbox" id="overwriteCheckbox" />
|
|
</div>
|
|
<div id="speedSliderDiv">
|
|
<label for="speedSlider">Speed</label>
|
|
<input type="range" id="speedSlider" />
|
|
</div>
|
|
<div class="optionButtonContainer">
|
|
<input id="saveButton" class="optionButton" type="button" value="Save" />
|
|
<input id="loadButton" class="optionButton" type="button" value="Load" />
|
|
</div>
|
|
<div id="clearButtonDiv" class="optionButtonContainer">
|
|
<input id="clearButton" class="optionButton" type="button" value="Clear" />
|
|
</div>
|
|
</div>
|
|
<div id="fps-counter"></div>
|
|
</div>
|
|
</div>
|
|
<br />
|
|
<script type="text/javascript">const TWO_PI=2*Math.PI,HALF_PI=Math.PI/2,QUARTER_PI=Math.PI/4,EIGHTH_PI=Math.PI/8,SIXTEENTH_PI=Math.PI/16,EIGHTEENTH_PI=Math.PI/18,__num_rand_ints=8192,__rand_ints=new Uint8Array(8192);for(var __next_rand=0,i=0;i<8192;i++)__rand_ints[i]=Math.floor(100*Math.random());function random(){const t=__rand_ints[__next_rand];return 8192===++__next_rand&&(__next_rand=0),t}function executeAndTime(t){const n=performance.now();t();return performance.now()-n}function displayPerformance(t,n){const r=executeAndTime(t);console.log(n,": ",r,"ms")}function docOffsetLeft(t){var n=0;do{isNaN(t.offsetLeft)||(n+=t.offsetLeft)}while(t=t.offsetParent);return n}function docOffsetTop(t){var n=0;do{isNaN(t.offsetTop)||(n+=t.offsetTop)}while(t=t.offsetParent);return n}function distance(t,n,r,e){const o=t-r,i=n-e;return Math.sqrt(o*o+i*i)}function fastItoXYBorderingAdjacent(t,n,r,e){const o=r+width;if(o===e)return[t,n+1];if(o-1===e)return[t-1,n+1];if(o+1===e)return[t+1,n+1];if(r-1===e)return[t-1,n];if(r+1===e)return[t+1,n];const i=r-width;if(i===e)return[t,n-1];if(i-1===e)return[t-1,n-1];if(i+1===e)return[t+1,n-1];throw"Not passed a bordering coordinate"}function fastItoXYBordering(t,n,r,e){if(r+width===e)return[t,n+1];if(r-1===e)return[t-1,n];if(r+1===e)return[t+1,n];if(r-width===e)return[t,n-1];throw"Not passed a bordering coordinate"}
|
|
</script>
|
|
<script type="text/javascript">const __max_width=560,__max_height=480,width=Math.min(560,Math.max(screen.width-6,1)),height=Math.min(480,Math.max(screen.height-200,100)),MAX_FPS=120,DEFAULT_FPS=60,MAX_NUM_PARTICLES=1e3;
|
|
</script>
|
|
<script type="text/javascript">var PENSIZE,SELECTED_ELEM,OVERWRITE_ENABLED;const userstrokeCanvas=document.createElement("canvas");userstrokeCanvas.width=width,userstrokeCanvas.height=height;const userstrokeCtx=userstrokeCanvas.getContext("2d",{alpha:!1}),CURSORS=[];class Cursor{constructor(t){this.x=0,this.y=0,this.prevX=0,this.prevY=0,this.documentX=0,this.documentY=0,this.isDown=!1,this.inCanvas=!1,this.canvas=t}canvasCursorDown(t,s){this.isDown=!0,this.inCanvas=!0,this.prevX=t,this.prevY=s,this.x=t,this.y=s}canvasCursorMove(t){if(!this.isDown)return;const s=t();this.x=s[0],this.y=s[1]}canvasCursorEnter(t,s){if(this.inCanvas=!0,!this.isDown)return;const e=t(this),i=s(this);Cursor.interpolateCursorBorderPosition(e,i),this.prevX=i[0],this.prevY=i[1],this.x=e[0],this.y=e[1]}canvasCursorLeave(t){if(this.inCanvas=!1,!this.isDown)return;const s=t(this);Cursor.interpolateCursorBorderPosition([this.prevX,this.prevY],s),this.x=s[0],this.y=s[1]}documentCursorMove(t){if(!this.isDown)return;if(this.inCanvas)return;const s=t();this.documentX=s[0],this.documentY=s[1]}documentCursorUp(){this.isDown=!1}documentCursorDown(t,s){if(t.target==onscreenCanvas)return;if(this.isDown)return;this.isDown=!0,this.inCanvas=!1,this.prevX=this.x,this.prevY=this.y;const e=s(this);this.documentX=e[0],this.documentY=e[1]}documentVisibilityChange(t){}static interpolateCursorBorderPosition(t,s){var e=t[1]-s[1],i=t[0]-s[0];0===e&&(e=.001),0===i&&(i=.001);const n=e/i,o=t[1]-n*t[0];return s[0]<0?(s[0]=0,s[1]=o):s[0]>MAX_X_IDX&&(s[0]=MAX_X_IDX,s[1]=n*MAX_X_IDX+o),s[1]<0?(s[1]=0,s[0]=(0-o)/n):s[1]>MAX_Y_IDX&&(s[1]=MAX_Y_IDX,s[0]=(MAX_Y_IDX-o)/n),s[0]=Math.floor(s[0]),s[1]=Math.floor(s[1]),s[0]=Math.max(Math.min(s[0],MAX_X_IDX),0),s[1]=Math.max(Math.min(s[1],MAX_Y_IDX),0),s}drawStroke(){if(!this.isDown)return;if(!this.inCanvas&&this.prevX===this.x&&this.prevY===this.y)return;const t=SELECTED_ELEM,s=OVERWRITE_ENABLED||t===BACKGROUND,e=4278190080!==t?"rgba("+(255&t)+","+((65280&t)>>>8)+","+((16711680&t)>>>16)+", 1)":"rgba(1, 0, 0, 1)",i=Math.min(this.prevX,this.x),n=Math.max(this.prevX,this.x),o=this.prevX<=this.x?this.prevY:this.y,r=this.prevX<=this.x?this.y:this.prevY;this.prevX=this.x,this.prevY=this.y;const h=Math.ceil(PENSIZE/2),u=i-h,a=Math.min(o,r)-h,c=i-u,v=o-a,f=n-u,C=r-a,d=f+PENSIZE+2,M=Math.max(v,C)+PENSIZE+2;userstrokeCanvas.width<d&&(userstrokeCanvas.width=d),userstrokeCanvas.height<M&&(userstrokeCanvas.height=M),userstrokeCtx.beginPath(),userstrokeCtx.rect(0,0,d,M),userstrokeCtx.fillStyle="rgba(0, 0, 0, 1)",userstrokeCtx.fill(),c===f&&v===C?(userstrokeCtx.beginPath(),userstrokeCtx.lineWidth=0,userstrokeCtx.fillStyle=e,userstrokeCtx.arc(c,v,PENSIZE/2,0,TWO_PI),userstrokeCtx.fill()):(userstrokeCtx.lineWidth=PENSIZE,userstrokeCtx.strokeStyle=e,userstrokeCtx.lineCap="round",userstrokeCtx.beginPath(),userstrokeCtx.moveTo(c,v),userstrokeCtx.lineTo(f,C),userstrokeCtx.stroke());const D=userstrokeCtx.getImageData(0,0,d,M),p=new Uint32Array(D.data.buffer);var m,l;const E=Math.max(0,-1*u),X=Math.max(0,-1*a),S=Math.min(d,width-u),I=Math.min(M,height-a);if(E>S||X>I)console.log("Bug in userstroke drawing");else for(l=X;l!==I;l++){const e=(l+a)*width,i=l*d;for(m=E;m!==S;m++){const n=m+u;if(4278190080!==p[m+i]){const i=n+e;(s||gameImagedata32[i]===BACKGROUND)&&(gameImagedata32[i]=t)}}}}}class Mouse extends Cursor{constructor(t){super(t),this.shiftStartX=0,this.shiftStartY=0,this.shiftPressed=!1,this.lineDirection=Mouse.NO_DIRECTION}canvasMouseDown(t){const s=Mouse.getMousePos(t,!0,this.canvas);this.shiftPressed&&!t.shiftKey&&(this.shiftPressed=!1),this.shiftPressed&&(this.shiftStartX=s[0],this.shiftStartY=s[1],this.lineDirection=Mouse.NO_DIRECTION),super.canvasCursorDown(s[0],s[1])}canvasMouseMove(t){const s=this.canvas;super.canvasCursorMove((function(){return Mouse.getMousePos(t,!0,s)}))}canvasMouseEnter(t){const s=this.canvas;super.canvasCursorEnter((function(e){return Mouse.getMousePos(t,!0,s)}),(function(t){return[t.documentX,t.documentY]})),this.isDown&&this.shiftPressed&&this.lineDirection===Mouse.NO_DIRECTION&&(this.shiftStartX=this.prevX,this.shiftStartY=this.prevY)}canvasMouseLeave(t){const s=this.canvas;super.canvasCursorLeave((function(e){return Mouse.getMousePos(t,!1,s)}))}documentMouseMove(t){if(t.target==onscreenCanvas)return;const s=this.canvas;super.documentCursorMove((function(){return Mouse.getMousePos(t,!1,s)}))}documentMouseUp(t){this.lineDirection=Mouse.NO_DIRECTION,super.documentCursorUp()}documentMouseDown(t){if(t.target==onscreenCanvas)return;const s=this.canvas;this.shiftPressed&&!t.shiftKey&&(this.shiftPressed=!1),this.shiftPressed&&(this.lineDirection=Mouse.NO_DIRECTION),super.documentCursorDown(t,(function(){return Mouse.getMousePos(t,!1,s)}))}static getMousePos(t,s,e){var i,n;return s?(i=t.offsetX,n=t.offsetY,i<0?i=0:i>=width&&(i=MAX_X_IDX),n<0?n=0:n>=height&&(n=MAX_Y_IDX)):(i=t.pageX-docOffsetLeft(e),n=t.pageY-docOffsetTop(e)),[Math.round(i),Math.round(n)]}documentKeyDown(t){t.shiftKey&&(this.shiftPressed||(this.shiftPressed=!0,this.lineDirection=Mouse.NO_DIRECTION,this.isDown&&this.inCanvas&&(this.shiftStartX=this.x,this.shiftStartY=this.y)))}documentKeyUp(t){!t.shiftKey&&this.shiftPressed&&(this.shiftPressed=!1)}documentVisibilityChange(t){"hidden"==document.visibilityState&&(this.documentMouseUp(null),this.shiftPressed=!1),super.documentVisibilityChange(t)}handleShift(){if(!this.isDown)return!1;if(!this.shiftPressed)return!1;if(!this.inCanvas&&this.prevX===this.x&&this.prevY===this.y)return;if(this.lineDirection===Mouse.NO_DIRECTION){if(!this.inCanvas)return!1;const t=this.x-this.shiftStartX,s=this.y-this.shiftStartY,e=Math.abs(t),i=Math.abs(s);if(Math.max(e,i)<8)return!0;Math.abs(e-i)<5?this.lineDirection=s*t<0?Mouse.DIAGONAL_DOWN:Mouse.DIAGONAL_UP:this.lineDirection=e>i?Mouse.HORIZONTAL:Mouse.VERTICAL}const t=this.lineDirection;if(t===Mouse.HORIZONTAL)this.prevY=this.shiftStartY,this.y=this.shiftStartY;else if(t===Mouse.VERTICAL)this.prevX=this.shiftStartX,this.x=this.shiftStartX;else if(t===Mouse.DIAGONAL_DOWN||t===Mouse.DIAGONAL_UP){this.prevX=this.shiftStartX,this.prevY=this.shiftStartY;const s=t===Mouse.DIAGONAL_DOWN?-1:1,e=this.shiftStartY-s*this.shiftStartX,i=s*this.x+e,n=(this.y-e)/s;distance(n,this.y,this.shiftStartX,this.shiftStartY)>distance(this.x,i,this.shiftStartX,this.shiftStartY)?this.x=n:this.y=i}return!1}drawStroke(){this.handleShift()||super.drawStroke()}}class TouchCursor extends Cursor{constructor(t){super(t)}canvasTouchStart(t){const s=TouchCursor.getTouchPos(t);if(s)return super.canvasCursorDown(s[0],s[1]),t.preventDefault(),!1}canvasTouchEnd(t){return super.documentCursorUp(),t.preventDefault(),!1}canvasTouchMove(t){const s=TouchCursor.getTouchPos(t);if(!s)return;return super.canvasCursorMove((function(){return s})),t.preventDefault(),!1}static getTouchPos(t){if(!t.touches)return null;const s=t.touches[0];if(!s)return null;const e=t.target.getBoundingClientRect();var i=Math.round(s.pageX-e.left-window.scrollX),n=Math.round(s.pageY-e.top-window.scrollY);return i<0?i=0:i>=width&&(i=MAX_X_IDX),n<0?n=0:n>=height&&(n=MAX_Y_IDX),[i,n]}}function initCursors(){PENSIZE=PEN_SIZES[DEFAULT_PEN_IDX],SELECTED_ELEM=WALL,OVERWRITE_ENABLED=!0,Mouse.NO_DIRECTION=0,Mouse.HORIZONTAL=1,Mouse.VERTICAL=2,Mouse.DIAGONAL_UP=3,Mouse.DIAGONAL_DOWN=4;const t=new Mouse(onscreenCanvas);onscreenCanvas.onmousedown=function(s){t.canvasMouseDown(s)},onscreenCanvas.onmousemove=function(s){t.canvasMouseMove(s)},onscreenCanvas.onmouseleave=function(s){t.canvasMouseLeave(s)},onscreenCanvas.onmouseenter=function(s){t.canvasMouseEnter(s)},document.onmouseup=function(s){t.documentMouseUp(s)},document.onmousedown=function(s){t.documentMouseDown(s)},document.onmousemove=function(s){t.documentMouseMove(s)},document.onkeydown=function(s){t.documentKeyDown(s)},document.onkeyup=function(s){t.documentKeyUp(s)},document.onvisibilitychange=function(s){t.documentVisibilityChange(s)};const s=new TouchCursor(onscreenCanvas);onscreenCanvas.addEventListener("touchstart",(function(t){s.canvasTouchStart(t)})),onscreenCanvas.addEventListener("touchend",(function(t){s.canvasTouchEnd(t)})),onscreenCanvas.addEventListener("touchmove",(function(t){s.canvasTouchMove(t)})),CURSORS.push(t),CURSORS.push(s),Object.freeze(CURSORS)}function updateUserStroke(){const t=CURSORS.length;for(var s=0;s!==t;s++)CURSORS[s].drawStroke()}
|
|
</script>
|
|
<script type="text/javascript">const offscreenParticleCanvas=document.createElement("canvas"),offscreenParticleCtx=offscreenParticleCanvas.getContext("2d",{alpha:!1}),UNKNOWN_PARTICLE=0,NITRO_PARTICLE=1,NAPALM_PARTICLE=2,C4_PARTICLE=3,LAVA_PARTICLE=4,MAGIC1_PARTICLE=5,MAGIC2_PARTICLE=6,METHANE_PARTICLE=7,TREE_PARTICLE=8,CHARGED_NITRO_PARTICLE=9,NUKE_PARTICLE=10,__particleInit=[UNKNOWN_PARTICLE_INIT,NITRO_PARTICLE_INIT,NAPALM_PARTICLE_INIT,C4_PARTICLE_INIT,LAVA_PARTICLE_INIT,MAGIC1_PARTICLE_INIT,MAGIC2_PARTICLE_INIT,METHANE_PARTICLE_INIT,TREE_PARTICLE_INIT,CHARGED_NITRO_PARTICLE_INIT,NUKE_PARTICLE_INIT];Object.freeze(__particleInit);const __particleActions=[UNKNOWN_PARTICLE_ACTION,NITRO_PARTICLE_ACTION,NAPALM_PARTICLE_ACTION,C4_PARTICLE_ACTION,LAVA_PARTICLE_ACTION,MAGIC1_PARTICLE_ACTION,MAGIC2_PARTICLE_ACTION,METHANE_PARTICLE_ACTION,TREE_PARTICLE_ACTION,CHARGED_NITRO_PARTICLE_ACTION,NUKE_PARTICLE_ACTION];function UNKNOWN_PARTICLE_INIT(t){}function UNKNOWN_PARTICLE_ACTION(t){throw"Unknown particle"}function NITRO_PARTICLE_INIT(t){t.setColor(FIRE);const e=5+10*Math.random(),i=Math.random()*TWO_PI;t.setVelocity(e,i),t.size=2+7*Math.random()}function NITRO_PARTICLE_ACTION(t){offscreenParticleCtx.beginPath(),offscreenParticleCtx.lineWidth=t.size,offscreenParticleCtx.strokeStyle=t.rgbaColor,offscreenParticleCtx.lineCap="round",offscreenParticleCtx.moveTo(t.x,t.y),t.x+=t.xVelocity,t.y+=t.yVelocity,offscreenParticleCtx.lineTo(t.x,t.y),offscreenParticleCtx.stroke();const e=t.actionIterations;e%5==0&&(t.size/=1.3),e%15==0&&(t.yVelocity+=e/5*10),(t.size<1.75||t.offCanvas())&&particles.makeParticleInactive(t)}function NAPALM_PARTICLE_INIT(t){t.setColor(FIRE),t.size=8*Math.random()+6,t.xVelocity=8*Math.random()-4,t.yVelocity=-1*(4*Math.random()+4),t.maxIterations=Math.floor(10*Math.random())+5}function NAPALM_PARTICLE_ACTION(t){t.drawCircle(t.size),t.x+=t.xVelocity,t.y+=t.yVelocity,t.size*=1+.1*Math.random(),t.actionIterations>t.maxIterations&&particles.makeParticleInactive(t)}function C4_PARTICLE_INIT(t){t.setColor(FIRE);const e=1e4*Math.random();t.size=e<9e3?10*Math.random()+3:e<9500?32*Math.random()+3:e<9800?64*Math.random()+3:128*Math.random()+3}function C4_PARTICLE_ACTION(t){t.drawCircle(t.size),t.actionIterations%3==0&&(t.size/=3,t.size<=1&&particles.makeParticleInactive(t))}function LAVA_PARTICLE_INIT(t){t.setColor(FIRE);var e=QUARTER_PI+Math.random()*HALF_PI;random()<75&&Math.abs(HALF_PI-e)<EIGHTEENTH_PI&&(e+=EIGHTEENTH_PI*(e>HALF_PI?1:-1)),t.xVelocity=(1+3*Math.random())*Math.cos(e),t.yVelocity=(-4*Math.random()-3)*Math.sin(e),t.initYVelocity=t.yVelocity,t.yAcceleration=.06,t.size=4+3*Math.random(),t.y-=t.size}function LAVA_PARTICLE_ACTION(t){offscreenParticleCtx.beginPath(),offscreenParticleCtx.lineWidth=t.size,offscreenParticleCtx.strokeStyle=t.rgbaColor,offscreenParticleCtx.lineCap="round",offscreenParticleCtx.moveTo(t.x,t.y);const e=t.actionIterations;if(t.x+=t.xVelocity,t.y=t.initY+t.initYVelocity*e+t.yAcceleration*e*e/2,offscreenParticleCtx.lineTo(t.x,t.y),offscreenParticleCtx.stroke(),t.x<0||t.x>MAX_X_IDX||t.y>MAX_Y_IDX)particles.makeParticleInactive(t);else if(random()<25){t.yVelocity=t.initYVelocity+t.yAcceleration*e;const a=t.aboutToHit();var i=-1;if(a===WATER||a===SALT_WATER?random()<58&&(i=ROCK):a===LAVA||a===ROCK?random()<75&&(i=LAVA):a===ICE||a===CHILLED_ICE||a===CRYO?random()<70&&(i=ROCK):a===WALL&&random()<25&&(i=LAVA),-1!==i)return t.setColor(i),t.drawCircle(t.size/2),void particles.makeParticleInactive(t)}}function MAGIC1_PARTICLE_INIT(t){t.reinitialized||t.setRandomColor(MAGIC_COLORS);var e=5+Math.round(13*Math.random());const i=[t];var a;for(a=1;a!==e;a++){const e=particles.addActiveParticle(0,t.x,t.y,t.i);if(!e)break;particles.particleCounts[e.type]--,particles.particleCounts[5]++,e.type=5,e.setColor(t.color),i.push(e)}e=i.length;const n=TWO_PI/e,r=7+3*Math.random(),c=4+4*Math.random();var o=0;for(a=0;a!==e;a++){const t=i[a];t.setVelocity(r,o),t.size=c,o+=n}}function MAGIC1_PARTICLE_ACTION(t){offscreenParticleCtx.beginPath(),offscreenParticleCtx.lineWidth=t.size,offscreenParticleCtx.strokeStyle=t.rgbaColor,offscreenParticleCtx.lineCap="square",offscreenParticleCtx.moveTo(t.x,t.y),t.x+=t.xVelocity,t.y+=t.yVelocity,offscreenParticleCtx.lineTo(t.x,t.y),offscreenParticleCtx.stroke(),t.offCanvas()&&particles.makeParticleInactive(t)}function MAGIC2_PARTICLE_INIT(t){t.setRandomColor(MAGIC_COLORS),t.size=4+8*Math.random(),t.x=Math.floor(width/2),t.y=Math.floor(height/2),t.initX=t.x,t.initY=t.y,t.magic_2_max_radius=Math.sqrt(width*width+height*height)/2+t.size,t.magic_2_theta=0,t.magic_2_speed=20,t.magic_2_radius_spacing=25+55*Math.random(),t.magic_2_radius=t.magic_2_radius_spacing}function MAGIC2_PARTICLE_ACTION(t){offscreenParticleCtx.beginPath(),offscreenParticleCtx.lineWidth=t.size,offscreenParticleCtx.strokeStyle=t.rgbaColor,offscreenParticleCtx.lineCap="round",offscreenParticleCtx.moveTo(t.x,t.y);const e=t.magic_2_theta+t.magic_2_speed/t.magic_2_radius;t.magic_2_theta=e;const i=t.magic_2_theta/TWO_PI*t.magic_2_radius_spacing;t.magic_2_radius=i,t.x=i*Math.cos(e)+t.initX,t.y=i*Math.sin(e)+t.initY,offscreenParticleCtx.lineTo(t.x,t.y),offscreenParticleCtx.stroke(),i>t.magic_2_max_radius&&particles.makeParticleInactive(t)}function METHANE_PARTICLE_INIT(t){t.setColor(FIRE),t.size=10+10*Math.random()}function METHANE_PARTICLE_ACTION(t){const e=t.actionIterations;t.drawCircle(t.size),e>2&&particles.makeParticleInactive(t)}Object.freeze(__particleActions);class TreeType{constructor(){throw"Should never actually instantiate this."}static initTreeParticle(t,e){}static branchAngles(t){throw"Branch angles not implemented."}static branchSpacingFactor(t){throw"Branch spacing factor not implemented."}}class Tree0 extends TreeType{static branchAngles(t){const e=EIGHTH_PI+Math.random()*QUARTER_PI;return[t.angle+e,t.angle-e]}static branchSpacingFactor(t){return.9}}class Tree1 extends TreeType{static initTreeParticle(t,e){const i=e?e.branchDirection:random()<50?1:-1;t.branchDirection=i}static branchAngles(t){const e=(EIGHTH_PI+Math.random()*EIGHTH_PI)*t.branchDirection;return[t.angle+e,t.angle]}static branchSpacingFactor(t){return.7}}class Tree2 extends TreeType{static branchAngles(t){const e=Math.random()*SIXTEENTH_PI+EIGHTH_PI;return[t.angle,t.angle+e,t.angle-e]}static branchSpacingFactor(t){return.6}}const TREE_TYPES=[Tree0,Tree2],NUM_TREE_TYPES=TREE_TYPES.length;function TREE_PARTICLE_INIT(t){t.setColor(BRANCH),t.size=random()<50?3:4;const e=1+.5*Math.random(),i=-1*(HALF_PI+EIGHTH_PI-Math.random()*QUARTER_PI);t.setVelocity(e,i),t.generation=1,t.branchSpacing=15+Math.round(45*Math.random()),t.maxBranches=1+Math.round(2*Math.random()),t.nextBranch=t.branchSpacing,t.branches=0,random()<62?t.treeType=0:t.treeType=1+Math.floor(Math.random()*NUM_TREE_TYPES-1),TREE_TYPES[t.treeType].initTreeParticle(t,null)}function TREE_PARTICLE_ACTION(t){if(offscreenParticleCtx.beginPath(),offscreenParticleCtx.lineWidth=t.size,offscreenParticleCtx.strokeStyle=t.rgbaColor,offscreenParticleCtx.lineCap="round",offscreenParticleCtx.moveTo(t.x,t.y),t.x+=t.xVelocity,t.y+=t.yVelocity,offscreenParticleCtx.lineTo(t.x,t.y),offscreenParticleCtx.stroke(),t.aboutToHit()===WALL)return void particles.makeParticleInactive(t);const e=t.actionIterations;if(e>=t.nextBranch){if(t.branches++,0===t.maxBranches)return void particles.makeParticleInactive(t);const a=t.color===LEAF||t.branches===t.maxBranches,n=TREE_TYPES[t.treeType],r=n.branchAngles(t),c=r.length;for(var i=0;i<c;i++){const e=particles.addActiveParticle(8,t.x,t.y,t.i);if(!e)break;e.generation=t.generation+1,e.maxBranches=Math.max(0,t.maxBranches-1),e.branchSpacing=t.branchSpacing*n.branchSpacingFactor(t),e.nextBranch=e.branchSpacing,e.angle=r[i],e.setVelocity(t.velocity,e.angle),e.size=Math.max(t.size-1,2),e.treeType=t.treeType,n.initTreeParticle(e,t),a&&e.setColor(LEAF)}if(t.branches>=t.maxBranches)return void particles.makeParticleInactive(t);t.branchSpacing>45&&(t.branchSpacing*=.8),t.nextBranch=e+t.branchSpacing*(.35*Math.random()+.65)}}function CHARGED_NITRO_PARTICLE_INIT(t){t.setColor(FIRE),t.size=4,t.xVelocity=0,t.yVelocity=-100,t.minY=-1;const e=(3+Math.round(2*Math.random()))*width;for(var i=t.i;i>-1;i-=e)if(gameImagedata32[i]===WALL){t.minY=i/width;break}}function CHARGED_NITRO_PARTICLE_ACTION(t){offscreenParticleCtx.beginPath(),offscreenParticleCtx.lineWidth=t.size,offscreenParticleCtx.strokeStyle=t.rgbaColor,offscreenParticleCtx.lineCap="square",offscreenParticleCtx.moveTo(t.initX,t.initY),t.x+=t.xVelocity,t.y=Math.max(t.minY,t.y+t.yVelocity),offscreenParticleCtx.lineTo(t.x,t.y),offscreenParticleCtx.stroke(),(t.y<=t.minY||t.offCanvas())&&particles.makeParticleInactive(t)}function NUKE_PARTICLE_INIT(t){t.setColor(FIRE);const e=Math.max(width,height);t.size=e/4+Math.random()*e/8}function NUKE_PARTICLE_ACTION(t){t.drawCircle(t.size),t.actionIterations>4&&particles.makeParticleInactive(t)}class Particle{constructor(){this.type=0,this.initX=-1,this.initY=-1,this.x=-1,this.y=-1,this.i=-1,this.color=0,this.rgbaColor="rgba(0, 0, 0, 1)",this.velocity=0,this.angle=0,this.xVelocity=0,this.yVelocity=0,this.size=0,this.actionIterations=0,this.active=!1,this.next=null,this.prev=null,this.reinitialized=!1}setColor(t){Particle.warned_unpaintable_color||t in PAINTABLE_PARTICLE_COLORS||(console.log("Unpaintable particle color: "+t),Particle.warned_unpaintable_color=!0),this.color=t;const e=255&t,i=(65280&t)>>>8,a=(16711680&t)>>>16;this.rgbaColor="rgba("+e+","+i+","+a+", 1)"}setRandomColor(t){const e=Math.floor(Math.random()*t.length);this.setColor(t[e])}offCanvas(){const t=this.x,e=this.y;return t<0||t>MAX_X_IDX||e<0||e>MAX_Y_IDX}setVelocity(t,e){this.velocity=t,this.angle=e,this.xVelocity=t*Math.cos(e),this.yVelocity=t*Math.sin(e)}aboutToHit(){const t=this.size/2,e=Math.atan2(this.yVelocity,this.xVelocity),i=this.x+Math.cos(e)*t,a=this.y+Math.sin(e)*t,n=Math.round(i)+Math.round(a)*width;return n<0||n>MAX_IDX?BACKGROUND:gameImagedata32[n]}drawCircle(t){offscreenParticleCtx.beginPath(),offscreenParticleCtx.lineWidth=0,offscreenParticleCtx.fillStyle=this.rgbaColor,offscreenParticleCtx.arc(this.x,this.y,t,0,TWO_PI),offscreenParticleCtx.fill()}}Particle.warned_unpaintable_color=!1;class ParticleList{constructor(){this.activeHead=null,this.activeSize=0,this.inactiveHead=null,this.inactiveSize=0,this.particleCounts=new Uint32Array(__particleInit.length);for(var t=0;t<this.particleCounts.length;t++)this.particleCounts[t]=0}addActiveParticle(t,e,i,a){if(0===this.inactiveSize)return null;const n=this.inactiveHead;return this.inactiveHead=this.inactiveHead.next,this.inactiveHead&&(this.inactiveHead.prev=null),this.inactiveSize--,this.activeHead?(this.activeHead.prev=n,n.next=this.activeHead,n.prev=null,this.activeHead=n):(n.next=null,n.prev=null,this.activeHead=n),this.activeSize++,n.active=!0,n.reinitialized=!1,n.actionIterations=0,n.type=t,n.initX=e,n.initY=i,n.x=e,n.y=i,n.i=a,this.particleCounts[t]++,__particleInit[t](n),n}makeParticleInactive(t){t.active=!1,this.particleCounts[t.type]--,t.type=0,t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.activeHead&&(this.activeHead=t.next),this.activeSize--,this.inactiveHead?(this.inactiveHead.prev=t,t.next=this.inactiveHead,t.prev=null,this.inactiveHead=t):(t.next=null,t.prev=null,this.inactiveHead=t),this.inactiveSize++}inactivateAll(){for(var t=this.activeHead;t;){const e=t.next;this.makeParticleInactive(t),t=e}}reinitializeParticle(t,e){if(!t.active)throw"Can only be used with active particles";this.particleCounts[t.type]--,this.particleCounts[e]++,t.type=e,t.reinitialized=!0,__particleInit[e](t)}particleActive(t){return this.particleCounts[t]>0}}const particles=new ParticleList,PAINTABLE_PARTICLE_COLORS={},MAGIC_COLORS=[];function initParticles(){if(__particleInit.length!==__particleActions.length)throw"Particle arrays must be same length";var t,e=MAX_NUM_PARTICLES;for(particles.inactiveHead=new Particle,particles.inactiveSize++,t=particles.inactiveHead,e--;e>0;){const i=new Particle;i.prev=t,t.next=i,particles.inactiveSize++,t=i,e--}offscreenParticleCanvas.width=width,offscreenParticleCanvas.height=height,PAINTABLE_PARTICLE_COLORS[FIRE]=null,PAINTABLE_PARTICLE_COLORS[WALL]=null,PAINTABLE_PARTICLE_COLORS[ROCK]=null,PAINTABLE_PARTICLE_COLORS[LAVA]=null,PAINTABLE_PARTICLE_COLORS[PLANT]=null,PAINTABLE_PARTICLE_COLORS[SPOUT]=null,PAINTABLE_PARTICLE_COLORS[WELL]=null,PAINTABLE_PARTICLE_COLORS[WAX]=null,PAINTABLE_PARTICLE_COLORS[ICE]=null,PAINTABLE_PARTICLE_COLORS[BRANCH]=null,PAINTABLE_PARTICLE_COLORS[LEAF]=null,Object.freeze(PAINTABLE_PARTICLE_COLORS),MAGIC_COLORS.push(WALL),MAGIC_COLORS.push(PLANT),MAGIC_COLORS.push(SPOUT),MAGIC_COLORS.push(WELL),MAGIC_COLORS.push(WAX),MAGIC_COLORS.push(ICE),Object.freeze(MAGIC_COLORS)}function updateParticles(){if(!particles.activeHead)return;const t=offscreenParticleCanvas.width,e=offscreenParticleCanvas.height;offscreenParticleCtx.beginPath(),offscreenParticleCtx.fillStyle="rgba(0, 0, 0, 1)",offscreenParticleCtx.rect(0,0,t,e),offscreenParticleCtx.fill();for(var i=particles.activeHead;i;){const t=i.next;i.actionIterations++,__particleActions[i.type](i),i=t}const a=offscreenParticleCtx.getImageData(0,0,t,e),n=new Uint32Array(a.data.buffer);var r,c,o=0;for(c=0;c!==e;c++){const e=o;for(r=0;r!==t;r++){const t=r+e,i=n[t];var s;if(4278190080!==i)if(i in PAINTABLE_PARTICLE_COLORS)gameImagedata32[t]=i;else(r-3>=0&&(s=n[t-3])in PAINTABLE_PARTICLE_COLORS||r+3<=MAX_X_IDX&&(s=n[t+3])in PAINTABLE_PARTICLE_COLORS||c-3>=0&&(s=n[t-3*width])in PAINTABLE_PARTICLE_COLORS||c+3<=MAX_Y_IDX&&(s=n[t+3*width])in PAINTABLE_PARTICLE_COLORS)&&(gameImagedata32[t]=s)}o+=t}}
|
|
</script>
|
|
<script type="text/javascript">var __next_elem_idx=0;function __inGameColor(a,e,n){a&=252,e&=252,n&=252;const t=3&__next_elem_idx,o=(12&__next_elem_idx)>>>2,d=(48&__next_elem_idx)>>>4;return __next_elem_idx++,4278190080+((n+=d)<<16)+((e+=o)<<8)+(a+=t)}const BACKGROUND=__inGameColor(0,0,0),WALL=__inGameColor(127,127,127),SAND=__inGameColor(223,193,99),WATER=__inGameColor(0,10,255),PLANT=__inGameColor(0,220,0),FIRE=__inGameColor(255,0,10),SALT=__inGameColor(253,253,253),SALT_WATER=__inGameColor(127,175,255),OIL=__inGameColor(150,60,0),SPOUT=__inGameColor(117,189,252),WELL=__inGameColor(131,11,28),TORCH=__inGameColor(200,5,0),GUNPOWDER=__inGameColor(170,170,140),WAX=__inGameColor(239,225,211),FALLING_WAX=__inGameColor(240,225,211),NITRO=__inGameColor(0,150,26),NAPALM=__inGameColor(220,128,70),C4=__inGameColor(240,230,150),CONCRETE=__inGameColor(180,180,180),FUSE=__inGameColor(219,175,199),ICE=__inGameColor(161,232,255),CHILLED_ICE=__inGameColor(20,153,220),LAVA=__inGameColor(245,110,40),ROCK=__inGameColor(68,40,8),STEAM=__inGameColor(195,214,235),CRYO=__inGameColor(0,213,255),MYSTERY=__inGameColor(162,232,196),METHANE=__inGameColor(140,140,140),SOIL=__inGameColor(120,75,33),WET_SOIL=__inGameColor(70,35,10),BRANCH=__inGameColor(166,128,100),LEAF=__inGameColor(82,107,45),POLLEN=__inGameColor(230,235,110),CHARGED_NITRO=__inGameColor(245,98,78),ACID=__inGameColor(157,240,40),THERMITE=__inGameColor(195,140,70),BURNING_THERMITE=__inGameColor(255,130,130),RETRON_MAT=__inGameColor(102,153,255),OBSIDIAN=__inGameColor(27,24,41),elements=new Uint32Array([BACKGROUND,WALL,SAND,WATER,PLANT,FIRE,SALT,SALT_WATER,OIL,SPOUT,WELL,TORCH,GUNPOWDER,WAX,FALLING_WAX,NITRO,NAPALM,C4,CONCRETE,FUSE,ICE,CHILLED_ICE,LAVA,ROCK,STEAM,CRYO,MYSTERY,METHANE,SOIL,WET_SOIL,BRANCH,LEAF,POLLEN,CHARGED_NITRO,ACID,THERMITE,BURNING_THERMITE,RETRON_MAT,OBSIDIAN]),elementActions=[BACKGROUND_ACTION,WALL_ACTION,SAND_ACTION,WATER_ACTION,PLANT_ACTION,FIRE_ACTION,SALT_ACTION,SALT_WATER_ACTION,OIL_ACTION,SPOUT_ACTION,WELL_ACTION,TORCH_ACTION,GUNPOWDER_ACTION,WAX_ACTION,FALLING_WAX_ACTION,NITRO_ACTION,NAPALM_ACTION,C4_ACTION,CONCRETE_ACTION,FUSE_ACTION,ICE_ACTION,CHILLED_ICE_ACTION,LAVA_ACTION,ROCK_ACTION,STEAM_ACTION,CRYO_ACTION,MYSTERY_ACTION,METHANE_ACTION,SOIL_ACTION,WET_SOIL_ACTION,BRANCH_ACTION,LEAF_ACTION,POLLEN_ACTION,CHARGED_NITRO_ACTION,ACID_ACTION,THERMITE_ACTION,BURNING_THERMITE_ACTION,RETRON_MAT_ACTION,OBSIDIAN_ACTION];Object.freeze(elementActions);const GAS_PERMEABLE={},NUM_ELEMENTS=elements.length;function initElements(){if(NUM_ELEMENTS>64)throw"too many elements (we only use 6 bits for element index)";if(NUM_ELEMENTS!==elementActions.length)throw"need 1 action per element";const a={};for(var e=0;e<elements.length;e++){const n=elements[e];if(((196608&n)>>>12)+((768&n)>>>6)+(3&n)!==e)throw"elements array order does not match element indices";if(n in a)throw"duplicate color";if(n>>>24!=255)throw console.log(n,e),"alpha must be set to 0xff";a[n]=null}GAS_PERMEABLE[SAND]=null,GAS_PERMEABLE[WATER]=null,GAS_PERMEABLE[SALT]=null,GAS_PERMEABLE[SALT_WATER]=null,GAS_PERMEABLE[OIL]=null,GAS_PERMEABLE[GUNPOWDER]=null,GAS_PERMEABLE[FALLING_WAX]=null,GAS_PERMEABLE[NITRO]=null,GAS_PERMEABLE[NAPALM]=null,GAS_PERMEABLE[CONCRETE]=null,GAS_PERMEABLE[ROCK]=null,GAS_PERMEABLE[CRYO]=null,GAS_PERMEABLE[MYSTERY]=null,GAS_PERMEABLE[SOIL]=null,GAS_PERMEABLE[WET_SOIL]=null,GAS_PERMEABLE[POLLEN]=null,GAS_PERMEABLE[CHARGED_NITRO]=null,GAS_PERMEABLE[ACID]=null,Object.freeze(GAS_PERMEABLE)}function WALL_ACTION(a,e,n){}function OBSIDIAN_ACTION(a,e,n){}function BACKGROUND_ACTION(a,e,n){throw"As an optimization, we should never be invoking the action for the background"}function SAND_ACTION(a,e,n){if(e!==MAX_Y_IDX&&uniformBelowAdjacent(a,e,n)!==SAND){if(doDensitySink(a,e,n,WATER,!0,25))return;if(doDensitySink(a,e,n,SALT_WATER,!0,25))return}doGravity(a,e,n,!0,95)}function WATER_ACTION(a,e,n){doGravity(a,e,n,!0,95)||doDensityLiquid(a,e,n,OIL,25,50)}function PLANT_ACTION(a,e,n){if(doGrow(a,e,n,WATER,50),random()<5){if(-1!==bordering(a,e,n,SALT))return void(gameImagedata32[n]=BACKGROUND)}}function FIRE_ACTION(a,e,n){if(random()<80){var t=bordering(a,e,n,WATER);if(-1===t&&(t=bordering(a,e,n,SALT_WATER)),-1!==t&&-1===bordering(a,e,n,BURNING_THERMITE))return gameImagedata32[t]=STEAM,void(gameImagedata32[n]=BACKGROUND)}if(random()<20){const t=borderingAdjacent(a,e,n,PLANT);if(-1!==t)return void(gameImagedata32[t]=FIRE)}if(random()<1){const t=bordering(a,e,n,WAX);if(-1!==t){const o=fastItoXYBordering(a,e,n,t);gameImagedata32[t]=FIRE;const d=below(Math.max(e,o[1]),Math.max(n,t),BACKGROUND);return void(-1!==d&&(gameImagedata32[d]=FALLING_WAX))}}if(random()<80){const t=borderingAdjacent(a,e,n,FUSE);if(-1!==t)return void(gameImagedata32[t]=FIRE)}if(random()<40){var o=!0;const t=Math.max(a-1,0),r=Math.max(e-1,0),m=Math.min(a+2,MAX_X_IDX+1),A=Math.min(e+2,MAX_Y_IDX+1);var d,i;for(i=r;i!==A;i++){const n=i*width;for(d=t;d!==m;d++){if(i===e&&d===a)continue;const t=gameImagedata32[n+d];if(t!==FIRE){if(t===PLANT||t===FUSE||t===BRANCH||t===LEAF){o=!1;break}if((d==a||i==e)&&t===WAX){o=!1;break}if(t===OIL&&random()<50){o=!1;break}}}if(!o)break}if(o)return void(gameImagedata32[n]=BACKGROUND)}if(random()<50){const a=above(e,n,BACKGROUND);if(-1!==a)return void(gameImagedata32[a]=FIRE)}}function SALT_ACTION(a,e,n){doGravity(a,e,n,!0,95)||doTransform(a,e,n,WATER,SALT_WATER,25,50)||doDensitySink(a,e,n,SALT_WATER,!0,25)}function SALT_WATER_ACTION(a,e,n){doGravity(a,e,n,!0,95)||doDensityLiquid(a,e,n,WATER,50,50)}function OIL_ACTION(a,e,n){random()<30&&-1!==bordering(a,e,n,FIRE)?__doBorderBurn(a,e,n):doGravity(a,e,n,!0,95)}function SPOUT_ACTION(a,e,n){doProducer(a,e,n,WATER,!1,5)}function WELL_ACTION(a,e,n){doProducer(a,e,n,OIL,!1,10)}function TORCH_ACTION(a,e,n){doProducer(a,e,n,FIRE,!0,25)}function GUNPOWDER_ACTION(a,e,n){if(random()<95&&-1!==bordering(a,e,n,FIRE))if(random()<1&&random()<25&&particles.particleCounts[MAGIC1_PARTICLE]<30){const t=particles.addActiveParticle(UNKNOWN_PARTICLE,a,e,n);t&&(t.setColor(FIRE),particles.reinitializeParticle(t,MAGIC1_PARTICLE))}else __doGunpowderExplosion(a,e,n);else doGravity(a,e,n,!0,95)}function WAX_ACTION(a,e,n){}function RETRON_MAT_ACTION(a,e,n){}function FALLING_WAX_ACTION(a,e,n){doGravity(a,e,n,!1,100)||(gameImagedata32[n]=WAX)}function NITRO_ACTION(a,e,n){if(!doGravity(a,e,n,!0,95)&&!surroundedByAdjacent(a,e,n,NITRO)){if(-1!==borderingAdjacent(a,e,n,FIRE)){if(random()<30){if(!particles.addActiveParticle(NITRO_PARTICLE,a,e,n))return;return void __doBorderBurn(a,e,n)}if(random()<20)return void(gameImagedata32[n]=FIRE)}if(e!==MAX_Y_IDX&&uniformBelowAdjacent(a,e,n)!==NITRO){if(doDensitySink(a,e,n,OIL,!0,25))return;if(doDensitySink(a,e,n,WATER,!0,25))return;if(doDensitySink(a,e,n,SALT_WATER,!0,25))return;if(doDensitySink(a,e,n,POLLEN,!0,25))return}}}function NAPALM_ACTION(a,e,n){random()<25&&-1!==bordering(a,e,n,FIRE)?particles.addActiveParticle(NAPALM_PARTICLE,a,e,n)||(gameImagedata32[n]=FIRE):doGravity(a,e,n,!0,95)}function C4_ACTION(a,e,n){random()<60&&-1!==bordering(a,e,n,FIRE)&&(particles.addActiveParticle(C4_PARTICLE,a,e,n)||(gameImagedata32[n]=FIRE))}function CONCRETE_ACTION(a,e,n){if(e!==MAX_Y_IDX&&uniformBelowAdjacent(a,e,n)!==CONCRETE){if(doDensitySink(a,e,n,WATER,!0,35))return;if(doDensitySink(a,e,n,SALT_WATER,!0,35))return}if(random()<10&&random()<10){if(-1!==borderingAdjacent(a,e,n,WALL))return void(gameImagedata32[n]=WALL)}doGravity(a,e,n,!0,95)||random()<10&&random()<10&&random()<5&&(gameImagedata32[n]=WALL)}function FUSE_ACTION(a,e,n){}function ICE_ACTION(a,e,n){if(!surroundedBy(a,e,n,ICE))if(random()<1&&-1!==bordering(a,e,n,WATER))gameImagedata32[n]=WATER;else{if(random()<70){const t=bordering(a,e,n,STEAM);if(-1!==t)return gameImagedata32[n]=WATER,void(random()<50&&(gameImagedata32[t]=WATER))}if(random()<10){var t=bordering(a,e,n,SALT);if(-1===t&&(t=bordering(a,e,n,SALT_WATER)),-1!==t)return void(gameImagedata32[n]=WATER)}(random()<50&&-1!==bordering(a,e,n,FIRE)||random()<50&&-1!==bordering(a,e,n,LAVA))&&(gameImagedata32[n]=WATER)}}function CHILLED_ICE_ACTION(a,e,n){random()<6?gameImagedata32[n]=ICE:-1===bordering(a,e,n,SALT)&&-1===bordering(a,e,n,SALT_WATER)&&-1===bordering(a,e,n,LAVA)&&-1===bordering(a,e,n,FIRE)&&-1===bordering(a,e,n,STEAM)?doGrow(a,e,n,WATER,50):gameImagedata32[n]=ICE}const __lava_immune=[LAVA,BACKGROUND,FIRE,WALL,ROCK,WATER,SALT_WATER,STEAM,OBSIDIAN];Object.freeze(__lava_immune);const __num_lava_immune=__lava_immune.length;function LAVA_ACTION(a,e,n){if(doTransform(a,e,n,WATER,OBSIDIAN,100,100))return;const t=0!==e?n-width:-1,o=e!==MAX_Y_IDX?n+width:-1,d=0!==a?n-1:-1,i=a!==MAX_X_IDX?n+1:-1;var r=!0;if((-1!==t&&gameImagedata32[t]!==LAVA||-1!==d&&gameImagedata32[d]!==LAVA&&gameImagedata32[d]!==BACKGROUND||-1!==i&&gameImagedata32[i]!==LAVA&&gameImagedata32[i]!==BACKGROUND||-1!==o&&gameImagedata32[o]!==LAVA&&gameImagedata32[o]!==BACKGROUND)&&(r=!1),!r){if(random()<4){const t=particles.particleCounts[LAVA_PARTICLE]<10?100:35;if(random()<t&&-1!==bordering(a,e,n,OIL))return particles.addActiveParticle(LAVA_PARTICLE,a,e,n),void(gameImagedata32[n]=BACKGROUND)}if(random()<25){const a=[t,o,d,i],e=a.length;var m,A;for(m=0;m!==e;m++){const e=a[m];if(-1===e)continue;const n=gameImagedata32[e];var I=!0;for(A=0;A!==__num_lava_immune;A++)if(n===__lava_immune[A]){I=!1;break}I&&(gameImagedata32[e]=FIRE)}}if(random()<6&&-1!==t&&gameImagedata32[t]===BACKGROUND&&(gameImagedata32[t]=FIRE),-1!==o){const a=gameImagedata32[o];if(a===FIRE)gameImagedata32[o]=BACKGROUND;else if(a===STEAM&&random()<95)return gameImagedata32[o]=LAVA,void(gameImagedata32[n]=STEAM)}random()<15&&(-1!==d&&gameImagedata32[d]===FIRE&&(gameImagedata32[d]=BACKGROUND),-1!==i&&gameImagedata32[i]===FIRE&&(gameImagedata32[i]=BACKGROUND))}doGravity(a,e,n,!0,100)}function ROCK_ACTION(a,e,n){if(e!==MAX_Y_IDX&&uniformBelowAdjacent(a,e,n)!==ROCK){if(doDensitySink(a,e,n,WATER,!1,95))return;if(doDensitySink(a,e,n,OIL,!1,95))return;if(doDensitySink(a,e,n,SALT_WATER,!1,95))return;if(doDensitySink(a,e,n,LAVA,!1,20))return}if(!doGravity(a,e,n,!1,99)&&random()<1&&random()<20&&-1!==above(e,n,OIL)){const a=above(e,n,OIL);if(-1!==a)return void(random()<50?gameImagedata32[a]=METHANE:gameImagedata32[n]=METHANE)}}function STEAM_ACTION(a,e,n){doDensityGas(a,e,n,70)||doRise(a,e,n,70,60)||(random()<5&&-1!==bordering(a,e,n,WATER)?gameImagedata32[n]=WATER:random()<5&&random()<40&&-1!==below(e,n,BACKGROUND)&&-1===above(e,n,BACKGROUND)?random()<30?gameImagedata32[n]=WATER:gameImagedata32[n]=BACKGROUND:random()<5&&-1!==bordering(a,e,n,SPOUT)?gameImagedata32[n]=WATER:random()<1&&random()<5&&-1===below(e,n,STEAM)&&(gameImagedata32[n]=BACKGROUND))}function CRYO_ACTION(a,e,n){const t=Math.max(a-1,0),o=Math.max(e-1,0),d=Math.min(a+2,MAX_X_IDX+1),i=Math.min(e+2,MAX_Y_IDX+1);var r,m;for(m=o;m!==i;m++){const o=m*width;for(r=t;r!==d;r++){if(m===e&&r===a)continue;const t=o+r,d=gameImagedata32[t];if(d!==CRYO){if(d===CHILLED_ICE&&random()<1&&random()<5)return void(gameImagedata32[n]=CHILLED_ICE);if(d===WALL||d===SPOUT||d===WAX||d===WELL||d===FUSE||d===PLANT||d===C4)return void(gameImagedata32[n]=CHILLED_ICE);if(d===WATER||d===ICE)return gameImagedata32[t]=CHILLED_ICE,void(gameImagedata32[n]=CHILLED_ICE);if(d===LAVA)return gameImagedata32[n]=BACKGROUND,void(gameImagedata32[t]=ROCK)}}}doGravity(a,e,n,!0,95)||random()<1&&random()<50&&-1===bordering(a,e,n,BACKGROUND)&&!surroundedBy(a,e,n,CRYO)&&(gameImagedata32[n]=CHILLED_ICE)}function MYSTERY_ACTION(a,e,n){if(particles.particleActive(MAGIC1_PARTICLE)||particles.particleActive(MAGIC2_PARTICLE))gameImagedata32[n]=BACKGROUND;else if(!(doGravity(a,e,n,!0,95)||random()<50)){if(-1!==borderingAdjacent(a,e,n,SAND))return particles.addActiveParticle(MAGIC1_PARTICLE,a,e,n),void(gameImagedata32[n]=BACKGROUND);if(-1!==borderingAdjacent(a,e,n,SALT))return particles.addActiveParticle(MAGIC2_PARTICLE,a,e,n),void(gameImagedata32[n]=BACKGROUND);if(-1!==bordering(a,e,n,FIRE))for(var t=MAX_IDX;0!==t;t--){const a=gameImagedata32[t];if(a===WALL)continue;if(a===FIRE){gameImagedata32[t]=BACKGROUND;continue}if(a===MYSTERY){gameImagedata32[t]=BACKGROUND;continue}const e=Math.floor(Math.random()*t),n=gameImagedata32[e];n!==WALL&&n!==FIRE&&n!==MYSTERY&&(gameImagedata32[t]=n,gameImagedata32[e]=a)}return-1!==bordering(a,e,n,POLLEN)?(particles.addActiveParticle(NUKE_PARTICLE,a,e,n),void(gameImagedata32[n]=BACKGROUND)):void 0}}function METHANE_ACTION(a,e,n){random()<25&&-1!==bordering(a,e,n,FIRE)?particles.addActiveParticle(METHANE_PARTICLE,a,e,n)||(gameImagedata32[n]=FIRE):doRise(a,e,n,25,65)||doDensityGas(a,e,n,70)}function SOIL_ACTION(a,e,n){if(!doGravity(a,e,n,!1,99)){if(e!==MAX_Y_IDX&&uniformBelowAdjacent(a,e,n)!==SOIL){if(doDensitySink(a,e,n,WATER,!0,50))return;if(doDensitySink(a,e,n,SALT_WATER,!0,50))return;if(doDensitySink(a,e,n,POLLEN,!0,50))return}if(!doTransform(a,e,n,NITRO,CHARGED_NITRO,25,100)&&random()<15){const t=aboveAdjacent(a,e,n,WATER);if(-1!==t)return gameImagedata32[t]=BACKGROUND,void(gameImagedata32[n]=WET_SOIL)}}}function WET_SOIL_ACTION(a,e,n){if(random()<15){const t=aboveAdjacent(a,e,n,WATER);-1!==t&&(gameImagedata32[t]=BACKGROUND)}if(!doGravity(a,e,n,!1,99)&&!doDensitySink(a,e,n,WATER,!0,50)&&!doDensitySink(a,e,n,SALT_WATER,!0,50)&&random()<5){if(random()<97)return void(-1===borderingAdjacent(a,e,n,WATER)&&(gameImagedata32[n]=SOIL));if(random()<35)return;-1===aboveAdjacent(a,e,n,BACKGROUND)||-1===belowAdjacent(a,e,n,SOIL)&&-1===belowAdjacent(a,e,n,WALL)||particles.addActiveParticle(TREE_PARTICLE,a,e,n)&&(gameImagedata32[n]=SOIL)}}function BRANCH_ACTION(a,e,n){random()<3&&-1!==borderingAdjacent(a,e,n,FIRE)&&(gameImagedata32[n]=FIRE)}function LEAF_ACTION(a,e,n){if(random()<5&&-1!==borderingAdjacent(a,e,n,FIRE)&&(gameImagedata32[n]=FIRE),random()<20){if(-1!==borderingAdjacent(a,e,n,SALT))return void(gameImagedata32[n]=BACKGROUND)}random()<1&&random()<9&&doProducer(a,e,n,POLLEN,!1,100)}function POLLEN_ACTION(a,e,n){doGravity(a,e,n,!0,95)}function CHARGED_NITRO_ACTION(a,e,n){if(!doGravity(a,e,n,!0,95)){if(e!==MAX_Y_IDX&&uniformBelowAdjacent(a,e,n)!==CHARGED_NITRO){if(doDensitySink(a,e,n,SOIL,!0,25))return;if(doDensitySink(a,e,n,WET_SOIL,!0,25))return;if(doDensitySink(a,e,n,NITRO,!0,25))return;if(doDensitySink(a,e,n,POLLEN,!0,25))return}return-1!==borderingAdjacent(a,e,n,FIRE)?(particles.addActiveParticle(CHARGED_NITRO_PARTICLE,a,e,n),void(gameImagedata32[n]=FIRE)):void 0}}function ACID_ACTION(a,e,n){if(random()<10){const d=e>0?e-1:-1,i=e<MAX_Y_IDX?e+1:-1,r=a>0?a-1:-1,m=a<MAX_X_IDX?a+1:-1,A=[r,m,a],I=[i,d,e];var t,o;for(random()<50&&(A[0]=m,A[1]=r),random()<50&&(I[0]=d,I[1]=i),o=0;3!==o;o++){const d=I[o];if(-1===d)continue;if(random()<25&&d!==i)continue;const r=d*width;for(t=0;3!==t;t++){const o=A[t];if(-1===o)continue;if(d===e&&o===a)continue;if(o!==a&&d!==e)continue;const i=r+o,m=gameImagedata32[i];if(m!==ACID&&m!==BACKGROUND&&m!==WATER&&m!==SALT_WATER&&m!==ICE&&m!==CHILLED_ICE&&m!==CRYO)return d!==e+1?void(gameImagedata32[i]=BACKGROUND):(gameImagedata32[n]=BACKGROUND,void((m!==WALL||random()<75)&&(gameImagedata32[i]=ACID)))}}}doDensityLiquid(a,e,n,WATER,25,30)||doDensityLiquid(a,e,n,SALT_WATER,25,30)||doGravity(a,e,n,!0,100)}function THERMITE_ACTION(a,e,n){surroundedByAdjacent(a,e,n,THERMITE)||(random()<50&&-1!==borderingAdjacent(a,e,n,FIRE)?gameImagedata32[n]=BURNING_THERMITE:doDensitySink(a,e,n,WATER,!1,95)||doDensitySink(a,e,n,SALT_WATER,!1,95)||doDensitySink(a,e,n,OIL,!1,95)||doGravity(a,e,n,!1,99))}function BURNING_THERMITE_ACTION(a,e,n){const t=[e>0?n-width:-1,a>0?n-1:-1,a<MAX_X_IDX?n+1:-1];var o;for(o=0;3!==o;o++){const a=t[o];if(-1===a)continue;const e=gameImagedata32[a];e!==THERMITE&&e!==BURNING_THERMITE&&e!==LAVA&&e!==WALL&&(gameImagedata32[a]=FIRE)}if(random()<2&&random()<7)return particles.addActiveParticle(CHARGED_NITRO_PARTICLE,a,e,n),void(gameImagedata32[n]=FIRE);if(random()<2)return void(gameImagedata32[n]=FIRE);if(random()<8){const t=adjacent(a,n,WALL);-1!==t&&(gameImagedata32[t]=BACKGROUND);const o=below(e,n,WALL);-1!==o&&(gameImagedata32[o]=BACKGROUND)}const d=below(e,n,FIRE);-1!==d&&(gameImagedata32[d]=BACKGROUND),doGravity(a,e,n,!1,99)||doDensitySink(a,e,n,WATER,!1,95)||doDensitySink(a,e,n,SALT_WATER,!1,95)||doDensitySink(a,e,n,OIL,!1,95)}function __pickRandValid(a,e){const n=-1!==a,t=-1!==e;return n&&t?random()<50?a:e:n?a:t?e:-1}function below(a,e,n){if(a===MAX_Y_IDX)return-1;const t=e+width;return gameImagedata32[t]===n?t:-1}function belowAdjacent(a,e,n,t){if(e===MAX_Y_IDX)return-1;const o=n+width;if(gameImagedata32[o]===t)return o;const d=o-1,i=o+1;return __pickRandValid(0!==a&&gameImagedata32[d]===t?d:-1,a!==MAX_X_IDX&&gameImagedata32[i]===t?i:-1)}function above(a,e,n){if(0===a)return-1;const t=e-width;return gameImagedata32[t]===n?t:-1}function aboveAdjacent(a,e,n,t){if(0===e)return-1;const o=n-width;if(gameImagedata32[o]===t)return o;const d=o-1,i=o+1;return __pickRandValid(0!==a&&gameImagedata32[d]===t?d:-1,a!==MAX_X_IDX&&gameImagedata32[i]===t?i:-1)}function adjacent(a,e,n){const t=e-1,o=e+1;return __pickRandValid(0!==a&&gameImagedata32[t]===n?t:-1,a!==MAX_X_IDX&&gameImagedata32[o]===n?o:-1)}function bordering(a,e,n,t){var o=-1;return e!==MAX_Y_IDX&&(o=below(e,n,t)),-1===o&&(o=adjacent(a,n,t)),-1===o&&0!==e&&(o=above(e,n,t)),o}function borderingAdjacent(a,e,n,t){var o=-1;return e!==MAX_Y_IDX&&(o=belowAdjacent(a,e,n,t)),-1===o&&(o=adjacent(a,n,t)),-1===o&&0!==e&&(o=aboveAdjacent(a,e,n,t)),o}function surroundedBy(a,e,n,t){return(e===MAX_Y_IDX||gameImagedata32[n+width]===t)&&((0===e||gameImagedata32[n-width]===t)&&((0===a||gameImagedata32[n-1]===t)&&(a===MAX_X_IDX||gameImagedata32[n+1]===t)))}function surroundedByAdjacent(a,e,n,t){const o=e===MAX_Y_IDX,d=0===e;if(!o&&gameImagedata32[n+width]!==t)return!1;if(!d&&gameImagedata32[n-width]!==t)return!1;if(0!==a){const a=n-1;if(gameImagedata32[a]!==t)return!1;if(!d&&gameImagedata32[a-width]!==t)return!1;if(!o&&gameImagedata32[a+width]!==t)return!1}if(a!==MAX_X_IDX){const a=n+1;if(gameImagedata32[a]!==t)return!1;if(!d&&gameImagedata32[a-width]!==t)return!1;if(!o&&gameImagedata32[a+width]!==t)return!1}return!0}function surroundedByCount(a,e,n,t){var o=0;return e!==MAX_Y_IDX&&gameImagedata32[n+width]===t&&o++,0!==e&&gameImagedata32[n-width]===t&&o++,0!==a&&gameImagedata32[n-1]===t&&o++,a!==MAX_X_IDX&&gameImagedata32[n+1]===t&&o++,o}function surroundedByAdjacentCount(a,e,n,t){const o=e===MAX_Y_IDX,d=0===e;var i=0;if(o||gameImagedata32[n+width]!==t||i++,d||gameImagedata32[n-width]!==t||i++,0!==a){const a=n-1;gameImagedata32[a]===t&&i++,d||gameImagedata32[a-width]!==t||i++,o||gameImagedata32[a+width]!==t||i++}if(a!==MAX_X_IDX){const a=n+1;gameImagedata32[a]===t&&i++,d||gameImagedata32[a-width]!==t||i++,o||gameImagedata32[a+width]!==t||i++}return i}function doGravity(a,e,n,t,o){return!(random()>=o)&&(e===MAX_Y_IDX?(gameImagedata32[n]=BACKGROUND,!0):(-1===(d=t?belowAdjacent(a,e,n,BACKGROUND):below(e,n,BACKGROUND))&&t&&(d=adjacent(a,n,BACKGROUND)),-1!==d&&(gameImagedata32[d]=gameImagedata32[n],gameImagedata32[n]=BACKGROUND,!0)));var d}function doRise(a,e,n,t,o){var d=-1;if(random()<t){if(0===e)return gameImagedata32[n]=BACKGROUND,!0;d=aboveAdjacent(a,e,n,BACKGROUND)}return-1===d&&random()<o&&(d=adjacent(a,n,BACKGROUND)),-1!==d&&(gameImagedata32[d]=gameImagedata32[n],gameImagedata32[n]=BACKGROUND,!0)}function doDensitySink(a,e,n,t,o,d){return!(random()>=d)&&(e!==MAX_Y_IDX&&(-1!==(i=o?belowAdjacent(a,e,n,t):below(e,n,t))&&(gameImagedata32[i]=gameImagedata32[n],gameImagedata32[n]=t,!0)));var i}function doDensityLiquid(a,e,n,t,o,d){var i=-1;return random()<o&&(i=belowAdjacent(a,e,n,t)),-1===i&&random()<d&&(i=adjacent(a,n,t)),-1!==i&&(gameImagedata32[i]=gameImagedata32[n],gameImagedata32[n]=t,!0)}function doGrow(a,e,n,t,o){if(random()>=o)return!1;const d=borderingAdjacent(a,e,n,t);return-1!==d&&(gameImagedata32[d]=gameImagedata32[n],!0)}function __doBorderBurn(a,e,n){0!==e&&(gameImagedata32[n-width]=FIRE),e!==MAX_Y_IDX&&(gameImagedata32[n+width]=FIRE),0!==a&&(gameImagedata32[n-1]=FIRE),a!==MAX_X_IDX&&(gameImagedata32[n+1]=FIRE),gameImagedata32[n]=FIRE}function __doGunpowderExplosion(a,e,n){const t=random()<60,o=t?FIRE:GUNPOWDER,d=0!==a,i=a!==MAX_X_IDX;if(gameImagedata32[n]=o,0!==e){const a=n-width;gameImagedata32[a]=o,d&&(gameImagedata32[a-1]=o),i&&(gameImagedata32[a+1]=o)}if(d&&(gameImagedata32[n-1]=o),i&&(gameImagedata32[n+1]=o),e!==MAX_Y_IDX){const a=n+width;gameImagedata32[a]=o,d&&(gameImagedata32[a-1]=o),i&&(gameImagedata32[a+1]=o)}if(t&&!(random()>=40)){if(e-2>=0){const a=n-2*width;(gameImagedata32[a]!==GUNPOWDER||random()<50)&&(gameImagedata32[a]=FIRE)}if(e+2>=0){const a=n+2*width;(gameImagedata32[a]!==GUNPOWDER||random()<50)&&(gameImagedata32[a]=FIRE)}if(a-2>=0){const a=n-2;(gameImagedata32[a]!==GUNPOWDER||random()<50)&&(gameImagedata32[a]=FIRE)}if(a+2>=0){const a=n+2;(gameImagedata32[a]!==GUNPOWDER||random()<50)&&(gameImagedata32[a]=FIRE)}}}function doTransform(a,e,n,t,o,d,i){const r=random();if(r>=d)return!1;const m=bordering(a,e,n,t);return-1!==m&&(gameImagedata32[n]=o,r<i&&(gameImagedata32[m]=o),!0)}function doProducer(a,e,n,t,o,d){if(random()>=d)return!1;const i=n-width,r=n+width,m=n-1,A=n+1;0===e||!o&&gameImagedata32[i]!==BACKGROUND||(gameImagedata32[i]=t),e===MAX_Y_IDX||!o&&gameImagedata32[r]!==BACKGROUND||(gameImagedata32[r]=t),0===a||!o&&gameImagedata32[m]!==BACKGROUND||(gameImagedata32[m]=t),a===MAX_X_IDX||!o&&gameImagedata32[A]!==BACKGROUND||(gameImagedata32[A]=t)}function uniformBelowAdjacent(a,e,n){if(e===MAX_Y_IDX)return-1;const t=n+width,o=gameImagedata32[t];return 0!==a&&gameImagedata32[t-1]!==o||a!==MAX_X_IDX&&gameImagedata32[t+1]!==o?-1:o}function gasPermeable(a){return a!==BACKGROUND&&a!==STEAM&&a!==METHANE&&a in GAS_PERMEABLE}function doDensityGas(a,e,n,t){if(random()>=t)return!1;if(0===e)return!1;const o=gameImagedata32[n];var d=-1;const i=n-width,r=gameImagedata32[i];if(gasPermeable(r))d=i;else{const e=i-1,n=i+1,t=0!==a?gameImagedata32[e]:-1,o=a!==MAX_X_IDX?gameImagedata32[n]:-1;var m=-1,A=-1;t!==r&&gasPermeable(t)&&(m=e),o!==r&&(-1!==m&&t===o||gasPermeable(o))&&(A=n),d=__pickRandValid(m,A)}if(-1===d&&0!==a&&a!==MAX_X_IDX&&e!==MAX_Y_IDX){if(gasPermeable(gameImagedata32[n-1])&&gameImagedata32[n-1+width]!==o)d=n-1;else{gasPermeable(gameImagedata32[n+1])&&gameImagedata32[n+1+width]!==o&&(d=n+1)}}return-1!==d&&(gameImagedata32[n]=gameImagedata32[d],gameImagedata32[d]=o,!0)}
|
|
</script>
|
|
<script type="text/javascript">const SPIGOT_ELEMENT_OPTIONS=[SAND,WATER,ACID,SALT,FIRE,SALT_WATER,OIL,TORCH,GUNPOWDER,FALLING_WAX,NITRO,NAPALM,LAVA,ROCK,STEAM,CRYO,MYSTERY,METHANE,SOIL,WET_SOIL,POLLEN,CHARGED_NITRO,FIRE,THERMITE,BURNING_THERMITE,RETRON_MAT],SPIGOT_SIZE_OPTIONS=[0,5,10,15,20,25,50,100],DEFAULT_SPIGOT_SIZE_IDX=1,SPIGOT_ELEMENTS=[SAND,WATER,SALT,OIL],SPIGOT_SIZES=[],SPIGOT_HEIGHT=10,MAX_SPIGOT_WIDTH=Math.max(...SPIGOT_SIZE_OPTIONS),NUM_SPIGOTS=SPIGOT_ELEMENTS.length,SPIGOT_SPACING=Math.round((width-MAX_SPIGOT_WIDTH*NUM_SPIGOTS)/(NUM_SPIGOTS+1)+MAX_SPIGOT_WIDTH),SPIGOTS_ENABLED=MAX_SPIGOT_WIDTH*NUM_SPIGOTS<=width&&10<=height;function initSpigots(){const S=SPIGOT_SIZE_OPTIONS[1];for(var I=0;I!==NUM_SPIGOTS;I++)SPIGOT_SIZES.push(S)}function updateSpigots(){var S,I,T;if(SPIGOTS_ENABLED)for(S=0;S!==NUM_SPIGOTS;S++){const _=SPIGOT_ELEMENTS[S],E=SPIGOT_SPACING*(S+1)-MAX_SPIGOT_WIDTH,P=E+SPIGOT_SIZES[S];if(!(E<0)){if(P>MAX_X_IDX)break;var O=0;for(T=0;10!==T;T++){for(I=E;I!==P;I++)random()<10&&(gameImagedata32[I+O]=_);O+=width}}}}
|
|
</script>
|
|
<script type="text/javascript" >const onscreenPixelRatio=window.devicePixelRatio,onscreenScaledWidth=onscreenPixelRatio*width,onscreenScaledHeight=onscreenPixelRatio*height,onscreenCanvas=document.getElementById("mainCanvas");onscreenCanvas.width=onscreenScaledWidth,onscreenCanvas.height=onscreenScaledHeight,onscreenCanvas.style.width=width+"px",onscreenCanvas.style.height=height+"px";const onscreenCtx=onscreenCanvas.getContext("2d",{alpha:!1}),gameCanvas=document.createElement("canvas");gameCanvas.width=width,gameCanvas.height=height;const gameCtx=gameCanvas.getContext("2d",{alpha:!1}),gameImagedata=gameCtx.createImageData(width,height),gameImagedata32=new Uint32Array(gameImagedata.data.buffer),saveGameImagedata32=new Uint32Array(gameImagedata32.length);var gamestateSaved=!1;const MAX_X_IDX=width-1,MAX_Y_IDX=height-1,MAX_IDX=width*height-1;var fpsSetting,msPerFrame,lastLoop=0,frameDebt=0,lastFPSLabelUpdate=0;const refreshTimes=[];function init(){var e=document.getElementById("gameWrapper");e.style.height=height+"px",e.style.width=width+"px",setFPS(DEFAULT_FPS),initCursors(),initElements(),initParticles(),initSpigots(),initMenu();const a=gameImagedata32.length;for(var t=0;t<a;t++)gameImagedata32[t]=BACKGROUND,saveGameImagedata32[t]=BACKGROUND;onscreenCtx.mozImageSmoothingEnabled=!1,onscreenCtx.imageSmoothingEnabled=!1,onscreenCtx.webkitImageSmoothingEnabled=!1,onscreenCtx.msImageSmoothingEnabled=!1,onscreenCtx.oImageSmoothingEnabled=!1}function setFPS(e){fpsSetting=e,e>0?msPerFrame=1e3/fpsSetting:drawFPSLabel(0)}function updateGame(){var e,a;updateSpigots(),updateParticles();var t=MAX_IDX;const n=1&MAX_Y_IDX;for(a=MAX_Y_IDX;-1!==a;a--){const s=a;if((1&s)===n){for(e=MAX_X_IDX;-1!==e;e--){const a=gameImagedata32[t];if(a===BACKGROUND){t--;continue}elementActions[((196608&a)>>>12)+((768&a)>>>6)+(3&a)](e,s,t),t--}t++}else{for(e=0;e!==width;e++){const a=gameImagedata32[t];if(a===BACKGROUND){t++;continue}elementActions[((196608&a)>>>12)+((768&a)>>>6)+(3&a)](e,s,t),t++}t--}t-=width}perfRecordFrame(),frameDebt--}function draw(){gameCtx.putImageData(gameImagedata,0,0),gameCtx.scale(onscreenPixelRatio,onscreenPixelRatio),onscreenCtx.drawImage(gameCanvas,0,0,onscreenScaledWidth,onscreenScaledHeight)}function setGameCanvas(e){const a=MAX_IDX+1;for(var t=0;t!==a;t++)gameImagedata32[t]=e}function clearGameCanvas(){particles.inactivateAll(),setGameCanvas(BACKGROUND)}function saveGameCanvas(){const e=MAX_IDX+1;for(var a=0;a!==e;a++)saveGameImagedata32[a]=gameImagedata32[a];gamestateSaved=!0}function loadGameCanvas(){if(!gamestateSaved)return;particles.inactivateAll();const e=MAX_IDX+1;for(var a=0;a!==e;a++)gameImagedata32[a]=saveGameImagedata32[a]}function perfRecordFrame(){const e=performance.now(),a=e-1e3;for(;refreshTimes.length>0&&refreshTimes[0]<=a;)refreshTimes.shift();refreshTimes.push(e),e-lastFPSLabelUpdate>200&&(drawFPSLabel(refreshTimes.length),lastFPSLabelUpdate=e)}function mainLoop(e){if(window.requestAnimationFrame(mainLoop),0===lastLoop)return void(lastLoop=e);const a=e-lastLoop;if(lastLoop=e,a<0)console.log("time has gone backwards");else{if(fpsSetting>0&&(frameDebt+=a/msPerFrame),frameDebt=Math.min(frameDebt,5),updateUserStroke(),frameDebt>=1)if(frameDebt<2)updateGame();else{const e=executeAndTime(updateGame);for(var t=a-3.5-e;t>e&&frameDebt>=1;)updateGame(),t-=e}draw()}}window.onload=function(){init(),mainLoop(0)};
|
|
</script>
|
|
|
|
<script>const ELEMENT_MENU_ELEMENTS_PER_ROW=4,PEN_SIZES=[2,4,8,16,32,64,128,256,512,1024],PEN_SIZE_LABELS=["1px","2px","4px","8px","16px","32px","64px","128px","256px","512px"],DEFAULT_PEN_IDX=1,elementMenuItems=[BACKGROUND,WALL,SAND,WATER,PLANT,FIRE,SALT,SALT_WATER,OIL,SPOUT,WELL,TORCH,GUNPOWDER,WAX,FALLING_WAX,NITRO,NAPALM,C4,CONCRETE,FUSE,ICE,CHILLED_ICE,LAVA,ROCK,STEAM,CRYO,MYSTERY,METHANE,SOIL,WET_SOIL,BRANCH,LEAF,POLLEN,CHARGED_NITRO,ACID,THERMITE,BURNING_THERMITE,RETRON_MAT,OBSIDIAN],menuNames={};menuNames[BACKGROUND]="ERASER",menuNames[WALL]="WALL",menuNames[SAND]="SAND",menuNames[WATER]="WATER",menuNames[PLANT]="PLANT",menuNames[FIRE]="FIRE",menuNames[SALT]="SALT",menuNames[SALT_WATER]="SALT WATER",menuNames[OIL]="OIL",menuNames[SPOUT]="SPOUT ",menuNames[WELL]="WELL",menuNames[TORCH]="TORCH",menuNames[GUNPOWDER]="GUNPOWDER",menuNames[WAX]="WAX ",menuNames[FALLING_WAX]="FALLING WAX",menuNames[NITRO]="NITRO ",menuNames[NAPALM]="NAPALM",menuNames[C4]="C-4 ",menuNames[CONCRETE]="CONCRETE ",menuNames[FUSE]="FUSE",menuNames[ICE]="ICE",menuNames[CHILLED_ICE]="CHILLED ICE",menuNames[LAVA]="LAVA",menuNames[ROCK]="ROCK",menuNames[STEAM]="STEAM",menuNames[CRYO]="CRYO",menuNames[MYSTERY]="???",menuNames[METHANE]="METHANE",menuNames[SOIL]="SOIL",menuNames[WET_SOIL]="WET SOIL",menuNames[BRANCH]="BRANCH",menuNames[LEAF]="LEAF",menuNames[POLLEN]="POLLEN",menuNames[CHARGED_NITRO]="CHARGED NITRO ",menuNames[ACID]="ACID",menuNames[THERMITE]="THERMITE",menuNames[BURNING_THERMITE]="BURNING THERMITE",menuNames[RETRON_MAT]="RETRON MAT",menuNames[OBSIDIAN]="OBSIDIAN";const menuAltColors={};function initMenu(){document.getElementById("menuWrapper");const e=document.getElementById("elementTable");e.style.width="50%";const n=Math.ceil(elementMenuItems.length/4);var t,E,m=0;for(t=0;t<n;t++){const n=e.insertRow(t);for(E=0;E<4&&!(m>=elementMenuItems.length);E++){const e=n.insertCell(E),t=document.createElement("input");e.appendChild(t),t.type="button",t.className="elementMenuButton";const a=elementMenuItems[m];if(!(a in menuNames))throw"element is missing a canonical name: "+a;t.value=menuNames[a];const u=a;var s;t.id=u,s=a in menuAltColors?menuAltColors[a]:"rgb("+(255&u)+", "+((65280&u)>>>8)+", "+((16711680&u)>>>16)+")",t.style.color=s,t.addEventListener("click",(function(){document.getElementById(SELECTED_ELEM.toString()).classList.remove("selectedElementMenuButton"),t.classList.add("selectedElementMenuButton"),SELECTED_ELEM=parseInt(t.id,10)})),m++}}document.getElementById(SELECTED_ELEM.toString()).click();const a=document.getElementById("pensize");for(t=0;t<PEN_SIZES.length;t++){const e=document.createElement("option");e.value=PEN_SIZES[t],e.text=PEN_SIZE_LABELS[t],1===t&&(e.selected="selected",PENSIZE=parseInt(e.value,10)),a.add(e)}a.addEventListener("change",(function(){PENSIZE=parseInt(a.value,10)}));const u=[document.getElementById("spigot1Type"),document.getElementById("spigot2Type"),document.getElementById("spigot3Type"),document.getElementById("spigot4Type")],I=[document.getElementById("spigot1Size"),document.getElementById("spigot2Size"),document.getElementById("spigot3Size"),document.getElementById("spigot4Size")];if(u.length!==I.length)throw"should be same length";for(t=0;t<u.length;t++){const e=u[t],n=I[t];for(E=0;E<SPIGOT_ELEMENT_OPTIONS.length;E++){const n=SPIGOT_ELEMENT_OPTIONS[E],m=document.createElement("option");m.value=n,m.text=menuNames[n],t===E&&(m.selected="selected",SPIGOT_ELEMENTS[t]=n),e.add(m)}for(E=0;E<SPIGOT_SIZE_OPTIONS.length;E++){const e=SPIGOT_SIZE_OPTIONS[E],m=document.createElement("option");m.value=e,m.text=E.toString(10),E===DEFAULT_SPIGOT_SIZE_IDX&&(m.selected="selected",SPIGOT_SIZES[t]=e),n.add(m)}}u[0].addEventListener("change",(function(){SPIGOT_ELEMENTS[0]=parseInt(u[0].value,10)})),u[1].addEventListener("change",(function(){SPIGOT_ELEMENTS[1]=parseInt(u[1].value,10)})),u[2].addEventListener("change",(function(){SPIGOT_ELEMENTS[2]=parseInt(u[2].value,10)})),u[3].addEventListener("change",(function(){SPIGOT_ELEMENTS[3]=parseInt(u[3].value,10)})),I[0].addEventListener("change",(function(){SPIGOT_SIZES[0]=parseInt(I[0].value,10)})),I[1].addEventListener("change",(function(){SPIGOT_SIZES[1]=parseInt(I[1].value,10)})),I[2].addEventListener("change",(function(){SPIGOT_SIZES[2]=parseInt(I[2].value,10)})),I[3].addEventListener("change",(function(){SPIGOT_SIZES[3]=parseInt(I[3].value,10)}));const o=document.getElementById("overwriteCheckbox");o.checked=OVERWRITE_ENABLED,o.addEventListener("click",(function(){OVERWRITE_ENABLED=o.checked}));const N=document.getElementById("speedSlider");N.min=0,N.max=MAX_FPS,N.value=DEFAULT_FPS,N.addEventListener("input",(function(){const e=parseInt(N.value,10);Math.abs(e-DEFAULT_FPS)<10&&(N.value=DEFAULT_FPS),setFPS(parseInt(N.value,10))}));document.getElementById("clearButton").onclick=clearGameCanvas;document.getElementById("saveButton").onclick=saveGameCanvas;document.getElementById("loadButton").onclick=loadGameCanvas}function drawFPSLabel(e){document.getElementById("fps-counter").innerText="FPS: "+e}menuAltColors[WATER]="rgb(0, 130, 255)",menuAltColors[WALL]="rgb(160, 160, 160)",menuAltColors[BACKGROUND]="rgb(200, 100, 200)",menuAltColors[WELL]="rgb(158, 13, 33)",menuAltColors[SOIL]="rgb(171, 110, 53)";
|
|
</script>
|
|
</body>
|
|
</html> |