Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!-- Main page for Stage One Maze by Sean McKean (check main.js for license) -->
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="X-UA-Compatible" content="chrome=1" />
- <title>stage one maze</title>
- <style>
- body {
- text-align: center;
- font: 100% monospace;
- background-color: #fff;
- }
- canvas {
- border: 1px solid black;
- }
- </style>
- </head>
- <body>
- <canvas id="mainCanvas" width="600" height="400">
- canvas tag not supported by this browser.
- </canvas>
- <p>
- <button id="edit">set up</button>
- <button id="makeMaze" disabled>create maze</button>
- show win display<input id="winCheck" type="checkbox" checked />
- predefined sizes:
- <select id="sizes" disabled>
- <option value="custom">custom</option>
- <option value="a" selected>5x5x5</option>
- <option value="b">7x7x7</option>
- <option value="c">9x9x9</option>
- <option value="d">11x11x11</option>
- <option value="e">13x13x13</option>
- <option value="f">25x25x1</option>
- </select>
- <br />
- <button id="instructions">instructions</button>
- canvas size: <select id="canvasSizes" disabled>
- <option value="a">small</option>
- <option value="b" selected>medium</option>
- <option value="c">large</option>
- <option value="d">x-large</option>
- </select>
- width: <input id="width" type="text" size="3" value="5" disabled></input>
- height: <input id="height" type="text" size="3" value="5" disabled></input>
- depth: <input id="depth" type="text" size="3" value="5" disabled></input>
- </p>
- <div id="fpsText">
- <p>Average FPS: <span id="fpsCount">0</span></p>
- </div>
- <br /><p><a href="http://systemsymmetry.com">Return to home page</a></p>
- <script type="text/javascript">/*
- * Stage One Maze
- * Copyright (c) 2012 Sean McKean (smckean AT systemsymmetry DOT com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
- var middleMouseTime;
- function time() {
- return new Date().getTime();
- }
- function disableEvent(evt) {
- evt.preventDefault();
- }
- function mouseButtonPrecedence(i, j) {
- return (mbstate[i] > 0 && (mbstate[i] < mbstate[j] || mbstate[j] == 0));
- }
- function onMouseMove(evt) {
- msx = evt.clientX;
- msy = evt.clientY;
- if(msx < 0)
- msx = 0;
- if(msx >= window.innerWidth)
- msx = window.innerWidth-1;
- if(msy < 0)
- msy = 0;
- if(msy >= window.innerHeight)
- msy = window.innerHeight-1;
- }
- function onMouseDown(evt) {
- if(evt.button > 0 || msx < window.innerWidth-24) {
- if(evt.button == 0) {
- if(mbstate[1] == 0 || mouseButtonPrecedence(2, 1)) {
- plrSpeed = MaxSpeed/2;
- } else {
- plrSpeed = 0.0;
- }
- }
- for(var i = 0; i < 3; i++)
- if(mbstate[i] > 0)
- mbstate[i]++;
- mbstate[evt.button] = 1;
- mbpos = { x: evt.clientX, y: evt.clientY };
- if(evt.button == 1)
- middleMouseTime = time();
- evt.preventDefault();
- }
- }
- function onMouseUp(evt) {
- if(evt.button == 0)
- plrSpeed = 0.0;
- if(evt.button == 1 && time()-middleMouseTime < 250)
- keys.tab = true;
- mbstate[evt.button] = 0;
- for(var i = 0; i < 3; i++)
- if(mbstate[i] > 1)
- mbstate[i]--;
- mbpos = { x: evt.clientX, y: evt.clientY };
- evt.preventDefault();
- }
- function onMouseScroll(evt) {
- if(evt.wheelDelta > 0)
- mapZoom = clip(mapZoom*MapZoomMult, 1.0, 16.0);
- if(evt.wheelDelta < 0)
- mapZoom = clip(mapZoom/MapZoomMult, 1.0, 16.0);
- if(msx < window.innerWidth-24)
- evt.preventDefault();
- }
- function setKey(evt, name, value) {
- keys[name] = value;
- evt.preventDefault();
- }
- function onKeyDown(evt) {
- if(evt.which) {
- key = evt.which;
- } else if(window.event) {
- key = evt.keyCode;
- }
- switch(key) {
- case 83: // Rotate down
- setKey(evt, 's', 1); break;
- case 87: // Rotate up
- setKey(evt, 'w', 1); break;
- case 65: // Rotate left
- setKey(evt, 'a', 1); break;
- case 68: // Rotate right
- setKey(evt, 'd', 1); break;
- case 81: // Roll left
- setKey(evt, 'q', 1); break;
- case 69: // Roll right
- setKey(evt, 'e', 1); break;
- case 82: // Move forward
- setKey(evt, 'r', 1); break;
- case 70: // Move backward
- setKey(evt, 'f', 1); break;
- case 88: // Strafe down
- setKey(evt, 'x', 1); break;
- case 67: // Strafe up
- setKey(evt, 'c', 1); break;
- case 90: // Strafe left
- setKey(evt, 'z', 1); break;
- case 86: // Strafe right
- setKey(evt, 'v', 1); break;
- case 9: // tab
- case 77: // 'm' -- toggle map
- setKey(evt, 'tab', true); break;
- case 32: // spacebar
- setKey(evt, 'spc', true); break;
- case 188: // ','
- case 189: // '-'
- setKey(evt, 'minus', true); break;
- case 190: // '.'
- case 187: // '='
- setKey(evt, 'plus', true); break;
- }
- //console.log(key);
- }
- function onKeyUp(evt) {
- if(evt.which) {
- key = evt.which;
- } else if(window.event) {
- key = evt.keyCode;
- }
- switch(key) {
- case 83:
- setKey(evt, 's', 0); break;
- case 87:
- setKey(evt, 'w', 0); break;
- case 65:
- setKey(evt, 'a', 0); break;
- case 68:
- setKey(evt, 'd', 0); break;
- case 81:
- setKey(evt, 'q', 0); break;
- case 69:
- setKey(evt, 'e', 0); break;
- case 82:
- setKey(evt, 'r', 0); break;
- case 70:
- setKey(evt, 'f', 0); break;
- case 88:
- setKey(evt, 'x', 0); break;
- case 67:
- setKey(evt, 'c', 0); break;
- case 90:
- setKey(evt, 'z', 0); break;
- case 86:
- setKey(evt, 'v', 0); break;
- }
- }
- function changeWindowListeners(add) {
- if(add) {
- window.addEventListener('mousemove', onMouseMove, false);
- window.addEventListener('mousedown', onMouseDown, false);
- window.addEventListener('mouseup', onMouseUp, false);
- window.addEventListener('mousewheel', onMouseScroll, false);
- window.addEventListener('keydown', onKeyDown, false);
- window.addEventListener('keyup', onKeyUp, false);
- } else {
- window.removeEventListener('mousemove', onMouseMove, false);
- window.removeEventListener('mousedown', onMouseDown, false);
- window.removeEventListener('mouseup', onMouseUp, false);
- window.removeEventListener('mousewheel', onMouseScroll, false);
- window.removeEventListener('keydown', onKeyDown, false);
- window.removeEventListener('keyup', onKeyUp, false);
- }
- }
- function onEditBtn(evt) {
- if(!editBtnPressed) {
- editBtnPressed = true;
- cancelFrame(frameID[0]);
- makeBtn.disabled = false;
- sizeSelect.disabled = false;
- canvasSelect.disabled = false;
- inTextW.disabled = false;
- inTextH.disabled = false;
- inTextD.disabled = false;
- changeWindowListeners(false);
- if(!winState) {
- mc.ct.clearRect(0, 0, mc.w, mc.h);
- renderPrompt('click here to resume');
- mc.cv.addEventListener('click', onCanvasClick, false);
- }
- }
- }
- function onMakeBtn(evt) {
- var w = inTextW.value, h = inTextH.value, d = inTextD.value;
- inW = int(w);
- if(!(inW >= 1)) {
- inW = 5;
- } else if(inW%2 == 0) {
- inW = inW+1;
- }
- inH = int(h);
- if(!(inH >= 1)) {
- inH = 5;
- } else if(inH%2 == 0) {
- inH = inH+1;
- }
- inD = int(d);
- if(!(inD >= 1)) {
- inD = 5;
- } else if(inD%2 == 0) {
- inD = inD+1;
- }
- inTextW.value = inW.toString();
- inTextH.value = inH.toString();
- inTextD.value = inD.toString();
- makeBtn.disabled = true;
- sizeSelect.disabled = true;
- canvasSelect.disabled = true;
- inTextW.disabled = true;
- inTextH.disabled = true;
- inTextD.disabled = true;
- editBtnPressed = false;
- changeWindowListeners(true);
- mc.cv.removeEventListener('click', onCanvasClick, false);
- cancelFrame(frameID[1]);
- init();
- }
- function onInstructBtn(evt) {
- var w = 800, h = 460;
- var left = Math.floor(window.screen.width/2-w/2);
- var top = 32;
- open('help.html', 'instruction-popup', 'width='+w+', height='+h+', menubar=no, status=no, scrollbars=yes, resizable=yes, toolbar=no, location=no, left='+left+', top='+top);
- }
- function onCanvasClick(evt) {
- makeBtn.disabled = true;
- sizeSelect.disabled = true;
- canvasSelect.disabled = true;
- inTextW.disabled = true;
- inTextH.disabled = true;
- inTextD.disabled = true;
- editBtnPressed = false;
- changeWindowListeners(true);
- mc.cv.removeEventListener('click', onCanvasClick, false);
- if(mcChange)
- mc.updateSize(mcW, mcH, AspectMult);
- if(!winState)
- frameID[0] = requestFrame(output);
- }
- function onSelectChange(evt) {
- var t = evt.target;
- switch(t.value) {
- case 'a':
- inTextW.value = inTextH.value = inTextD.value = '5';
- break;
- case 'b':
- inTextW.value = inTextH.value = inTextD.value = '7';
- break;
- case 'c':
- inTextW.value = inTextH.value = inTextD.value = '9';
- break;
- case 'd':
- inTextW.value = inTextH.value = inTextD.value = '11';
- break;
- case 'e':
- inTextW.value = inTextH.value = inTextD.value = '13';
- break;
- case 'f':
- inTextW.value = '25';
- inTextH.value = '25';
- inTextD.value = '1';
- break;
- }
- }
- function onCanvasChange(evt) {
- mcChange = true;
- var t = evt.target;
- switch(t.value) {
- case 'a':
- mcW = 300;
- mcH = 200;
- break;
- case 'b':
- mcW = 600;
- mcH = 400;
- break;
- case 'c':
- mcW = 800;
- mcH = 600;
- break;
- case 'd':
- mcW = 1000;
- mcH = 800;
- break;
- }
- }
- function onTextChange(evt) {
- sizeSelect.value = 'custom';
- }</script>
- <script type="text/javascript">/*
- * Stage One Maze
- * Copyright (c) 2012 Sean McKean (smckean AT systemsymmetry DOT com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
- function Map(w, h, d) {
- this.w = w, this.h = h, this.d = d;
- this.maxDim = Math.max(w, h, d);
- this.m = new Array(w*h*d);
- for(var i = 0; i < this.m.length; i++)
- this.m[i] = 1;
- this.v = new Array(this.m.length);
- this.rw = int(w/2+1), this.rh = int(h/2+1), this.rd = int(d/2+1);
- this.oSpace = new Array(this.rw*this.rh*this.rd);
- this.path = new Array(this.oSpace.length);
- for(var i = 0; i < this.path.length; i++)
- this.path[i] = {
- x: { type: -1, view: -1, time: 0, r: 0, g: 0, b: 0, a: 0.0 },
- y: { type: -1, view: -1, time: 0, r: 0, g: 0, b: 0, a: 0.0 },
- z: { type: -1, view: -1, time: 0, r: 0, g: 0, b: 0, a: 0.0 } };
- this.sw = w+1; this.sh = h+1; this.sd = d+1;
- this.space = new Array(this.sw*this.sh*this.sd);
- this.goal = { x: w-1, y: h-1, z: d-1 };
- }
- Map.prototype.getMIndex = function(x, y, z) {
- return z*this.w*this.h+y*this.w+x;
- }
- Map.prototype.getRIndex = function(x, y, z) {
- return z*this.rw*this.rh+y*this.rw+x;
- }
- Map.prototype.getSIndex = function(x, y, z) {
- return z*this.sw*this.sh+y*this.sw+x;
- }
- Map.prototype.getCell = function(x, y, z) {
- if(x >= 0 && x < this.w && y >= 0 && y < this.h && z >= 0 && z < this.d)
- return this.m[ this.getMIndex(x, y, z) ];
- return null;
- }
- Map.prototype.setCell = function(x, y, z, v) {
- this.m[ this.getMIndex(x, y, z) ] = v;
- }
- Map.prototype.getCellPoint = function(pos, t0, d0, t1, d1, t2, d2) {
- var p = new Object();
- p[t0] = pos[t0]+d0;
- p[t1] = pos[t1]+d1;
- p[t2] = pos[t2]+d2;
- return this.getCell(p.x, p.y, p.z);
- }
- Map.prototype.getVCell = function(x, y, z) {
- return this.v[ this.getMIndex(x, y, z) ];
- }
- Map.prototype.setVCell = function(x, y, z, v) {
- this.v[ this.getMIndex(x, y, z) ] = v;
- }
- Map.prototype.getPathCell = function(x, y, z) {
- return this.path[ this.getRIndex(x, y, z) ];
- }
- Map.prototype.setPathCell = function(x, y, z, dim, name, value) {
- this.path[ this.getRIndex(x, y, z) ][dim][name] = value;
- }
- var visColors = [ { r: 0, g: 0, b: 159 }, { r: 159, g: 0, b: 0 } ];
- function alphaValue(c, t) {
- return clip(c.a+(1.0-c.a)*c.time, 0.0, 1.0);
- }
- function getColor(c) {
- if(c.type == 0 || c.view == 1) {
- var t = 0;
- } else {
- var t = 1;
- }
- return RGBA(visColors[t].r, visColors[t].g, visColors[t].b, alphaValue(c, t));
- }
- function setColor(c) {
- if(c.type == 0 || c.view == 1) {
- var t = 0;
- } else {
- var t = 1;
- }
- c.r = visColors[t].r;
- c.g = visColors[t].g;
- c.b = visColors[t].b;
- c.a = alphaValue(c, t);
- }
- Map.prototype.setVisibleRoomFromCell = function(x, y, z, dim, view) {
- var c = this.getPathCell(int(x/2), int(y/2), int(z/2))[dim];
- if(c.view != 0) {
- if(c.view > -1)
- setColor(c);
- c.time = eps;
- c.view = view;
- }
- }
- Map.prototype.setVGroup = function(x, y, z, flag, v) {
- switch(flag) {
- case 0: // Along x-axis
- for(var i = y-1; i < y+2; i++)
- for(var j = z-1; j < z+2; j++)
- if(i >= 0 && i < this.h && j >= 0 && j < this.d)
- this.setVCell(x, i, j, v);
- break;
- case 1: // Along y-axis
- for(var i = x-1; i < x+2; i++)
- for(var j = z-1; j < z+2; j++)
- if(i >= 0 && i < this.w && j >= 0 && j < this.d)
- this.setVCell(i, y, j, v);
- break;
- case 2: // Along z-axis
- for(var i = x-1; i < x+2; i++)
- for(var j = y-1; j < y+2; j++)
- if(i >= 0 && i < this.w && j >= 0 && j < this.h)
- this.setVCell(i, j, z, v);
- break;
- }
- }
- Map.prototype.setVisibleAxes = function(px, py, pz, dir) {
- if(dir != 0) {
- for(var x = px; x >= 0; x--) {
- if(this.getCell(x, py, pz) == 0) {
- this.setVGroup(x, py, pz, 0, true);
- } else {
- this.setVGroup(x, py, pz, 0, true);
- break;
- }
- }
- }
- if(dir != 1) {
- for(var x = px; x < this.w; x++) {
- if(this.getCell(x, py, pz) == 0) {
- this.setVGroup(x, py, pz, 0, true);
- } else {
- this.setVGroup(x, py, pz, 0, true);
- break;
- }
- }
- }
- if(dir != 2) {
- for(var y = py; y >= 0; y--) {
- if(this.getCell(px, y, pz) == 0) {
- this.setVGroup(px, y, pz, 1, true);
- } else {
- this.setVGroup(px, y, pz, 1, true);
- break;
- }
- }
- }
- if(dir != 3) {
- for(var y = py; y < this.h; y++) {
- if(this.getCell(px, y, pz) == 0) {
- this.setVGroup(px, y, pz, 1, true);
- } else {
- this.setVGroup(px, y, pz, 1, true);
- break;
- }
- }
- }
- if(dir != 4) {
- for(var z = pz; z >= 0; z--) {
- if(this.getCell(px, py, z) == 0) {
- this.setVGroup(px, py, z, 2, true);
- } else {
- this.setVGroup(px, py, z, 2, true);
- break;
- }
- }
- }
- if(dir != 5) {
- for(var z = pz; z < this.d; z++) {
- if(this.getCell(px, py, z) == 0) {
- this.setVGroup(px, py, z, 2, true);
- } else {
- this.setVGroup(px, py, z, 2, true);
- break;
- }
- }
- }
- }
- Map.prototype.nonDeadEndRooms = function(x, y, z, d) {
- var xx = x*2, yy = y*2, zz = z*2;
- for(var i = 0; i < 2; i++) {
- var c = 0;
- if(xx > 0 && this.getCell(xx-1, yy, zz) == 0)
- c++;
- if(xx < this.w-1 && this.getCell(xx+1, yy, zz) == 0)
- c++;
- if(yy > 0 && this.getCell(xx, yy-1, zz) == 0)
- c++;
- if(yy < this.h-1 && this.getCell(xx, yy+1, zz) == 0)
- c++;
- if(zz > 0 && this.getCell(xx, yy, zz-1) == 0)
- c++;
- if(zz < this.d-1 && this.getCell(xx, yy, zz+1) == 0)
- c++;
- if(c < 2)
- return false;
- switch(d) {
- case 'x':
- xx += 2;
- break;
- case 'y':
- yy += 2;
- break;
- case 'z':
- zz += 2;
- break;
- }
- }
- return true;
- }
- Map.prototype.setAllPaths = function() {
- for(var z = 0; z < this.rd; z++)
- for(var y = 0; y < this.rh; y++)
- for(var x = 0; x < this.rw; x++) {
- if(x < this.rw-1 && this.getCell(x*2+1, y*2, z*2) == 0) {
- if(this.nonDeadEndRooms(x, y, z, 'x')) {
- this.setPathCell(x, y, z, 'x', 'type', 0);
- } else {
- this.setPathCell(x, y, z, 'x', 'type', 1);
- }
- }
- if(y < this.rh-1 && this.getCell(x*2, y*2+1, z*2) == 0) {
- if(this.nonDeadEndRooms(x, y, z, 'y')) {
- this.setPathCell(x, y, z, 'y', 'type', 0);
- } else {
- this.setPathCell(x, y, z, 'y', 'type', 1);
- }
- }
- if(z < this.rd-1 && this.getCell(x*2, y*2, z*2+1) == 0) {
- if(this.nonDeadEndRooms(x, y, z, 'z')) {
- this.setPathCell(x, y, z, 'z', 'type', 0);
- } else {
- this.setPathCell(x, y, z, 'z', 'type', 1);
- }
- }
- }
- }
- Map.prototype.setSurroundingRoomsFromCell = function(x, y, z, d, v) {
- if(d != 'x') {
- if(x > 0 && this.getCell(x-1, y, z) == 0)
- this.setVisibleRoomFromCell(x-1, y, z, 'x', v);
- if(x < this.w-1 && this.getCell(x+1, y, z) == 0)
- this.setVisibleRoomFromCell(x, y, z, 'x', v);
- }
- if(d != 'y') {
- if(y > 0 && this.getCell(x, y-1, z) == 0)
- this.setVisibleRoomFromCell(x, y-1, z, 'y', v);
- if(y < this.h-1 && this.getCell(x, y+1, z) == 0)
- this.setVisibleRoomFromCell(x, y, z, 'y', v);
- }
- if(d != 'z') {
- if(z > 0 && this.getCell(x, y, z-1) == 0)
- this.setVisibleRoomFromCell(x, y, z-1, 'z', v);
- if(z < this.d-1 && this.getCell(x, y, z+1) == 0)
- this.setVisibleRoomFromCell(x, y, z, 'z', v);
- }
- }
- Map.prototype.setSeenPathCells = function(plr) {
- var x = int(plr.x), y = int(plr.y), z = int(plr.z);
- if(x%2 == 1 || y%2 == 1 || z%2 == 1)
- return;
- for(var d = -1; d < 2; d += 2) {
- for(var xx = x; xx >= 0 && xx < this.w; xx += d) {
- if(this.getCell(xx, y, z) == 1)
- break;
- if(xx%2 == 0)
- this.setSurroundingRoomsFromCell(xx, y, z, 'x', 1);
- if(xx%2 == 1)
- this.setVisibleRoomFromCell(xx, y, z, 'x', 0);
- }
- for(var yy = y; yy >= 0 && yy < this.h; yy += d) {
- if(this.getCell(x, yy, z) == 1)
- break;
- if(yy%2 == 0)
- this.setSurroundingRoomsFromCell(x, yy, z, 'y', 1);
- if(yy%2 == 1)
- this.setVisibleRoomFromCell(x, yy, z, 'y', 0);
- }
- for(var zz = z; zz >= 0 && zz < this.d; zz += d) {
- if(this.getCell(x, y, zz) == 1)
- break;
- if(zz%2 == 0)
- this.setSurroundingRoomsFromCell(x, y, zz, 'z', 1);
- if(zz%2 == 1)
- this.setVisibleRoomFromCell(x, y, zz, 'z', 0);
- }
- }
- }
- Map.prototype.setVisibleCells = function(plr) {
- for(var z = 0; z < this.d; z++)
- for(var y = 0; y < this.h; y++)
- for(var x = 0; x < this.w; x++)
- this.setVCell(x, y, z, false);
- var x = int(plr.x), y = int(plr.y), z = int(plr.z);
- if(x < this.w-1)
- this.setVisibleAxes(x+1, y, z, 0);
- if(x > 0)
- this.setVisibleAxes(x-1, y, z, 1);
- if(y < this.h-1)
- this.setVisibleAxes(x, y+1, z, 2);
- if(y > 0)
- this.setVisibleAxes(x, y-1, z, 3);
- if(z < this.d-1)
- this.setVisibleAxes(x, y, z+1, 4);
- if(z > 0)
- this.setVisibleAxes(x, y, z-1, 5);
- }
- Map.prototype.sideExists = function(pos, side) {
- switch(side) {
- case 0:
- if(pos.z == 0 || this.getCell(pos.x, pos.y, pos.z-1) == 1)
- return false;
- break;
- case 1:
- if(pos.z == this.d-1 || this.getCell(pos.x, pos.y, pos.z+1) == 1)
- return false;
- break;
- case 2:
- if(pos.y == 0 || this.getCell(pos.x, pos.y-1, pos.z) == 1)
- return false;
- break;
- case 3:
- if(pos.y == this.h-1 || this.getCell(pos.x, pos.y+1, pos.z) == 1)
- return false;
- break;
- case 4:
- if(pos.x == 0 || this.getCell(pos.x-1, pos.y, pos.z) == 1)
- return false;
- break;
- case 5:
- if(pos.x == this.w-1 || this.getCell(pos.x+1, pos.y, pos.z) == 1)
- return false;
- break;
- }
- return true;
- }
- var dimName = { x: 'w', y: 'h', z: 'd' };
- Map.prototype.edgeIsDrawn = function(pos, side, edge) {
- var p0 = points[ prePolies[side][edge] ], p1 = points[ prePolies[side][(edge+1)%4] ];
- if(p1.x-p0.x != 0) {
- var t0 = 'y', t1 = 'z', t2 = 'x';
- } else if(p1.y-p0.y != 0) {
- var t0 = 'x', t1 = 'z', t2 = 'y';
- } else if(p1.z-p0.z != 0) {
- var t0 = 'x', t1 = 'y', t2 = 'z';
- } else {
- alert('Bad data passed to Map.edgeIsDrawn()');
- return false;
- }
- if(pos[t0] == p0[t0]*(this[ dimName[t0] ]-1) || pos[t1] == p0[t1]*(this[ dimName[t1] ]-1))
- return true;
- if(this.getCellPoint(pos, t0, p0[t0]*2-1, t1, p0[t1]*2-1, t2, 0) == 1)
- return true;
- if(this.getCellPoint(pos, t0, p0[t0]*2-1, t1, 0, t2, 0) == 1)
- return false;
- if(this.getCellPoint(pos, t0, 0, t1, p0[t1]*2-1, t2, 0) == 1)
- return false;
- return true;
- }
- var adjAry = [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ], [ 1, 1, 0 ], [ 1, 0, 1 ], [ 0, 1, 1 ], [ 1, 1, 1 ] ];
- Map.prototype.handleCollisions = function(plr, near, dim) {
- var x = 0, y = 0, z = 0;
- if(plr.x%1.0 < near && int(plr.x) > 0) {
- x = -1;
- } else if(plr.x%1.0 > 1.0-near && int(plr.x) < this.w-1) {
- x = 1;
- }
- if(plr.y%1.0 < near && int(plr.y) > 0) {
- y = -1;
- } else if(plr.y%1.0 > 1.0-near && int(plr.y) < this.h-1) {
- y = 1;
- }
- if(plr.z%1.0 < near && int(plr.z) > 0) {
- z = -1;
- } else if(plr.z%1.0 > 1.0-near && int(plr.z) < this.d-1) {
- z = 1;
- }
- var col = false;
- for(var i = 0; i < adjAry.length; i++) {
- var xx = (adjAry[i][0] == 1) ? x : 0;
- var yy = (adjAry[i][1] == 1) ? y : 0;
- var zz = (adjAry[i][2] == 1) ? z : 0;
- if(this.getCell(int(plr.x)+xx, int(plr.y)+yy, int(plr.z)+zz) == 1) {
- col = true;
- break;
- }
- }
- if(col) {
- switch(dim) {
- case 'x':
- if(x == 1) {
- plr.x = int(plr.x)+1-near-eps;
- return;
- } else if(x == -1) {
- plr.x = int(plr.x)+near+eps;
- return;
- }
- break;
- case 'y':
- if(y == 1) {
- plr.y = int(plr.y)+1-near-eps;
- return;
- } else if(y == -1) {
- plr.y = int(plr.y)+near+eps;
- return;
- }
- break;
- case 'z':
- if(z == 1) {
- plr.z = int(plr.z)+1-near-eps;
- return;
- } else if(z == -1) {
- plr.z = int(plr.z)+near+eps;
- return;
- }
- break;
- }
- }
- }
- Map.prototype.getSpace = function(x, y, z) {
- return this.space[ this.getSIndex(x, y, z) ];
- }
- Map.prototype.setSpace = function(x, y, z, v) {
- this.space[ this.getSIndex(x, y, z) ] = v;
- }
- Map.prototype.fillSpace = function(plr, tm) {
- for(var z = 0; z < this.sd; z += this.sd-1)
- for(var y = 0; y < this.sh; y += this.sh-1)
- for(var x = 0; x < this.sw; x += this.sw-1) {
- var mat = multiplyMatrices([ [ x-plr.x, y-plr.y, z-plr.z, 1 ] ], tm);
- this.setSpace(x, y, z, new SpacePoint(mat[0][0], mat[0][1], mat[0][2]));
- }
- if(this.sw > 2) {
- for(var z = 0; z < this.sd; z += this.sd-1)
- for(var y = 0; y < this.sh; y += this.sh-1)
- for(var x = 1; x < this.sw; x++) {
- var f = x/(this.sw-1);
- var p = interpPoint(this.getSpace(0, y, z), this.getSpace(this.sw-1, y, z), f);
- this.setSpace(x, y, z, p);
- }
- }
- if(this.sh > 2) {
- for(var z = 0; z < this.sd; z += this.sd-1)
- for(var y = 1; y < this.sh; y++)
- for(var x = 0; x < this.sw; x++) {
- var f = y/(this.sh-1);
- var p = interpPoint(this.getSpace(x, 0, z), this.getSpace(x, this.sh-1, z), f);
- this.setSpace(x, y, z, p);
- }
- }
- if(this.sd > 2) {
- for(var z = 1; z < this.sd; z++)
- for(var y = 0; y < this.sh; y++)
- for(var x = 0; x < this.sw; x++) {
- var f = z/(this.sd-1);
- var p = interpPoint(this.getSpace(x, y, 0), this.getSpace(x, y, this.sd-1), f);
- this.setSpace(x, y, z, p);
- }
- }
- }
- Map.prototype.getOSpace = function(x, y, z) {
- return this.oSpace[ this.getRIndex(x, y, z) ];
- }
- Map.prototype.setOSpace = function(x, y, z, v) {
- this.oSpace[ this.getRIndex(x, y, z) ] = v;
- }
- Map.prototype.fillOverviewSpace = function(plr, tm) {
- var w = (this.rw == 1) ? 2 : this.rw;
- var h = (this.rh == 1) ? 2 : this.rh;
- var d = (this.rd == 1) ? 2 : this.rd;
- for(var z = 0; z < this.rd; z += d-1)
- for(var y = 0; y < this.rh; y += h-1)
- for(var x = 0; x < this.rw; x += w-1) {
- var mat0 = [ [ x+0.25-plr.x/2, y+0.25-plr.y/2, z+0.25-plr.z/2, 1 ] ];
- var mat1 = multiplyMatrices(mat0, tm);
- this.setOSpace(x, y, z, new SpacePoint(mat1[0][0], mat1[0][1], mat1[0][2]));
- }
- if(this.rw > 1) {
- for(var z = 0; z < this.rd; z += d-1)
- for(var y = 0; y < this.rh; y += h-1)
- for(var x = 1; x < w; x++) {
- var f = x/(w-1);
- var p = interpPoint(this.getOSpace(0, y, z), this.getOSpace(w-1, y, z), f);
- this.setOSpace(x, y, z, p);
- }
- }
- if(this.rh > 1) {
- for(var z = 0; z < this.rd; z += d-1)
- for(var y = 1; y < h; y++)
- for(var x = 0; x < this.rw; x++) {
- var f = y/(h-1);
- var p = interpPoint(this.getOSpace(x, 0, z), this.getOSpace(x, h-1, z), f);
- this.setOSpace(x, y, z, p);
- }
- }
- if(this.rd > 1) {
- for(var z = 1; z < d; z++)
- for(var y = 0; y < this.rh; y++)
- for(var x = 0; x < this.rw; x++) {
- var f = z/(d-1);
- var p = interpPoint(this.getOSpace(x, y, 0), this.getOSpace(x, y, d-1), f);
- this.setOSpace(x, y, z, p);
- }
- }
- }
- Map.prototype.makeMaze = function(xs, ys, zs) {
- this.setCell(xs, ys, zs, 0);
- var x = xs, y = ys, z = zs;
- var c = 1, full = (int(this.w/2+1)*int(this.h/2+1)*int(this.d/2+1));
- var rc = 1;
- var cellStack = [ { x: x, y: y, z: z } ];
- var stackPtr = 0;
- while(c < full) {
- var open = new Array();
- if(x < this.w-1 && this.getCell(x+2, y, z) == 1)
- open.push(0);
- if(x > 0 && this.getCell(x-2, y, z) == 1)
- open.push(1);
- if(y < this.h-1 && this.getCell(x, y+2, z) == 1)
- open.push(2);
- if(y > 0 && this.getCell(x, y-2, z) == 1)
- open.push(3);
- if(z < this.d-1 && this.getCell(x, y, z+2) == 1)
- open.push(4);
- if(z > 0 && this.getCell(x, y, z-2) == 1)
- open.push(5);
- if(open.length == 0) {
- cellStack.splice(stackPtr, 1);
- stackPtr = int(Math.random()*cellStack.length);
- x = cellStack[stackPtr].x;
- y = cellStack[stackPtr].y;
- z = cellStack[stackPtr].z;
- continue;
- }
- var dir = open[ int(Math.random()*open.length) ];
- switch(dir) {
- case 0:
- this.setCell(x+1, y, z, 0);
- this.setCell(x+2, y, z, 0);
- x += 2;
- break;
- case 1:
- this.setCell(x-1, y, z, 0);
- this.setCell(x-2, y, z, 0);
- x -= 2;
- break;
- case 2:
- this.setCell(x, y+1, z, 0);
- this.setCell(x, y+2, z, 0);
- y += 2;
- break;
- case 3:
- this.setCell(x, y-1, z, 0);
- this.setCell(x, y-2, z, 0);
- y -= 2;
- break;
- case 4:
- this.setCell(x, y, z+1, 0);
- this.setCell(x, y, z+2, 0);
- z += 2;
- break;
- case 5:
- this.setCell(x, y, z-1, 0);
- this.setCell(x, y, z-2, 0);
- z -= 2;
- break;
- }
- cellStack.push({ x: x, y: y, z: z });
- c++;
- rc++;
- if(rc == MaxRun) {
- stackPtr = int(Math.random()*(cellStack.length-1));
- x = cellStack[stackPtr].x;
- y = cellStack[stackPtr].y;
- z = cellStack[stackPtr].z;
- rc = 0;
- }
- }
- }</script>
- <script type="text/javascript">/*
- * Stage One Maze
- * Copyright (c) 2012 Sean McKean (smckean AT systemsymmetry DOT com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
- Debug = false;
- var mc, bc, wc;
- var mcW, mcH, mcChange;
- var AspectMult = 0.72;
- var editBtn, editBtnPressed;
- var makeBtn, winCheck, sizeSelect, instructBtn, canvasSelect;
- var inTextW, inTextH, inTextD;
- var inW, inH, inD;
- var points = [
- { x: 0, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }, { x: 1, y: 1, z: 0 }, { x: 0, y: 1, z: 0 },
- { x: 0, y: 0, z: 1 }, { x: 1, y: 0, z: 1 }, { x: 1, y: 1, z: 1 }, { x: 0, y: 1, z: 1 } ];
- var prePolies = [ [ 0, 1, 2, 3 ], [ 5, 4, 7, 6 ], [ 0, 4, 5, 1 ], [ 7, 3, 2, 6 ], [ 0, 3, 7, 4 ], [ 2, 1, 5, 6 ] ];
- var polyVerts, polyDrawn, polyToCube;
- var plr, plrSpeed;
- var restart;
- var tm;
- var map;
- var mapZoom;
- var MapZoomMult = 1.2;
- var MaxRun = 8;
- var PathTimeInc = 0.03;
- var goalDis;
- var goalRad;
- var goalAlpha, goalAngle;
- var GoalAngleDelta = 0.04;
- var winState, winAlpha;
- var keys = {
- w: 0, s: 0, a: 0, d: 0, q: 0, e: 0, r: 0, f: 0, z: 0, x: 0, c: 0, v: 0,
- tab: false, spc: false, minus: false, plus: false };
- var msx = -1, msy = -1;
- var mbstate = [ 0, 0, 0 ];
- var mbpos = { x: -1, y: -1 };
- var KeyDelta = 0.036;
- var MouseDelta = 0.012;
- var SpeedDelta = 0.002;
- var MaxSpeed = KeyDelta*2;
- var zNear = 0.02;
- var wallNear = 0.24;
- var criticalFlag = 0.0;
- var showMap;
- var Pi = Math.PI;
- var Circ = 2.0*Pi;
- var eps = 0.00001;
- var requestFrame;
- var cancelFrame;
- var frameID = new Array(2);
- var frames;
- function int(n) {
- return Math.floor(n);
- }
- // Clips value v between min and max values
- function clip(v, min, max) {
- if(v < min) {
- return min;
- } else if(v > max) {
- return max;
- }
- return v;
- }
- // Similar to clip, flooring to an integer
- function clipInt(v, min, max) {
- if(v < min) {
- return int(min);
- } else if(v > max) {
- return int(max);
- }
- return int(v);
- }
- function RGB(r, g, b) {
- return 'rgb('+r+','+g+','+b+')';
- }
- function RGBA(r, g, b, a) {
- return 'rgba('+r+','+g+','+b+','+a+')';
- }
- // Pixel xy-coordinates
- function ScreenPoint(x, y) {
- this.x = x;
- this.y = y;
- }
- // Contains 3d xyz-components
- function SpacePoint(x, y, z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
- function Canvas(arg0, am) {
- if(typeof(arg0) == 'string') {
- this.cv = document.getElementById(arg0);
- } else {
- this.cv = document.createElement('canvas');
- this.cv.width = arg0[0];
- this.cv.height = arg0[1];
- }
- this.ct = this.cv.getContext('2d');
- if(!this.ct)
- alert('Unable to create 2D context for canvas');
- this.w = this.cv.width;
- this.h = this.cv.height;
- this.hw = int(this.w/2);
- this.hh = int(this.h/2);
- this.a = int(Math.min(this.w, this.h)*am);
- }
- Canvas.prototype.updateSize = function(w, h, am) {
- this.cv.width = this.w = w;
- this.cv.height = this.h = h;
- this.hw = int(this.w/2);
- this.hh = int(this.h/2);
- this.a = int(Math.min(this.w, this.h)*am);
- }
- function identityMatrix() {
- return [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ];
- }
- function multiplyMatrices(m0, m1) {
- var height = m0.length;
- var width = m1[0].length;
- var result = new Array(height);
- for(var y = 0; y < height; y++) {
- result[y] = new Array(width);
- for(var x = 0; x < width; x++) {
- var sum = 0;
- for(var z = 0; z < width; z++)
- sum += m0[y][z]*m1[z][x];
- result[y][x] = sum;
- }
- }
- return result;
- }
- // Multiply rotation matrix by selected matrix to rotate points incrementally.
- function rotateMatrix(m, x, y, z) {
- if(x) {
- var c = Math.cos(x);
- var s = Math.sin(x);
- var temp = [ [1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1] ];
- m = multiplyMatrices(m, temp);
- }
- if(y) {
- var c = Math.cos(y);
- var s = Math.sin(y);
- var temp = [ [c, 0, s, 0], [0, 1, 0, 0], [-s, 0, c, 0], [0, 0, 0, 1] ];
- m = multiplyMatrices(m, temp);
- }
- if(z) {
- var c = Math.cos(z);
- var s = Math.sin(z);
- var temp = [ [c, -s, 0, 0], [s, c, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ];
- m = multiplyMatrices(m, temp);
- }
- return m;
- }
- // Interpolates from p0 to p1 with the given ratio factor
- function interpPoint(p0, p1, factor) {
- var x = (p1.x-p0.x)*factor+p0.x;
- var y = (p1.y-p0.y)*factor+p0.y;
- var z = (p1.z-p0.z)*factor+p0.z;
- return new SpacePoint(x, y, z);
- }
- // Converts a 3d SpacePoint to a ScreenPoint centered on the given Canvas.
- function flattenPoint(p, c) {
- return new ScreenPoint(int(p.x*c.a/p.z+c.hw), int(p.y*c.a/p.z+c.hh));
- }
- function linePoints(p0, p1, canv) {
- if(p0.z < zNear) {
- if(p1.z < zNear)
- return null;
- var pt = interpPoint(p0, p1, (zNear-p0.z)/(p1.z-p0.z));
- var fp = flattenPoint(pt, canv);
- return [ fp, flattenPoint(p1, canv), false ];
- } else if(p1.z < zNear) {
- var pt = interpPoint(p0, p1, (zNear-p0.z)/(p1.z-p0.z));
- var fp = flattenPoint(pt, canv);
- return [ flattenPoint(p0, canv), fp, true ];
- }
- return [ flattenPoint(p0, canv), flattenPoint(p1, canv), false ];
- }
- function getFlatLines(s, p, d) {
- var flatLines = new Array();
- var len = s.length;
- var last = null;
- var nullCount = 0;
- // First space point is guaranteed to be ahead of view z-wise, but may be offscreen.
- for(var i = 0; i < len; i++) {
- var j = (i+1)%len;
- var ary = linePoints(s[i], s[j], mc);
- if(ary != null) {
- if(ary[2] == true) {
- var line = { f0: ary[0], f1: ary[1], p0: p[i], p1: p[j], draw: d[i] };
- flatLines.push(line);
- last = ary[1];
- } else {
- if(last != null) {
- var fl = { f0: last, f1: ary[0], p0: p[i], p1: p[j], draw: false };
- flatLines.push(fl);
- last = null;
- }
- var line = { f0: ary[0], f1: ary[1], p0: p[i], p1: p[j], draw: d[i] };
- flatLines.push(line);
- }
- } else {
- var fl = { f0: null, f1: null, draw: false };
- flatLines.push(fl);
- nullCount++;
- }
- }
- if(nullCount == 4)
- return null;
- return flatLines;
- }
- function handleMapKeys() {
- if(keys.tab) {
- showMap = !showMap;
- keys.tab = false;
- }
- if(keys.plus) {
- mapZoom = clip(mapZoom*MapZoomMult, 1.0, 16.0);
- keys.plus = false;
- }
- if(keys.minus) {
- mapZoom = clip(mapZoom/MapZoomMult, 1.0, 16.0);
- keys.minus = false;
- }
- }
- function handleRotation() {
- var x = keys.w-keys.s, y = keys.d-keys.a, z = keys.e-keys.q;
- tm = rotateMatrix(tm, x*KeyDelta, y*KeyDelta, z*KeyDelta);
- if(mouseButtonPrecedence(2, 1)) {
- var x = mbpos.y-msy, y = msx-mbpos.x;
- tm = rotateMatrix(tm, x*MouseDelta, y*MouseDelta, 0);
- mbpos = { x: msx, y: msy };
- } else if(mbstate[0] > 0 && mouseButtonPrecedence(1, 2)) {
- var z = msx-mbpos.x;
- tm = rotateMatrix(tm, 0, 0, z*MouseDelta);
- mbpos.x = msx;
- }
- }
- function solveLinearEquation(tm, x, y, z) {
- var m = identityMatrix();
- for(var yy = 0; yy < 3; yy++)
- for(var xx = 0; xx < 3; xx++) {
- m[yy][xx] = tm[yy][xx];
- }
- var xx = null, yy = null, zz = null;
- if(Math.abs(m[0][0]) > eps) {
- var f = m[0][1]/m[0][0];
- m[0][1] = 0.0; m[1][1] -= m[1][0]*f; m[2][1] -= m[2][0]*f; y -= x*f;
- f = m[0][2]/m[0][0];
- m[0][2] = 0.0; m[1][2] -= m[1][0]*f; m[2][2] -= m[2][0]*f; z -= x*f;
- if(Math.abs(m[1][1]) > eps) {
- f = m[1][2]/m[1][1];
- m[2][2] -= m[2][1]*f; z -= y*f;
- zz = z/m[2][2];
- yy = (y-m[2][1]*zz)/m[1][1];
- } else {
- zz = y/m[2][1];
- yy = (z-m[2][2]*zz)/m[1][2];
- }
- xx = (x-m[1][0]*yy-m[2][0]*zz)/m[0][0];
- } else if(Math.abs(m[1][0]) > eps) {
- var f = m[1][1]/m[1][0];
- m[1][1] = 0.0; m[2][1] -= m[2][0]*f; y -= x*f;
- f = m[1][2]/m[1][0];
- m[1][2] = 0.0; m[2][2] -= m[2][0]*f; z -= x*f;
- if(Math.abs(m[0][1]) > eps) {
- f = m[0][2]/m[0][1];
- m[2][2] -= m[2][1]*f; z -= y*f;
- zz = z/m[2][2];
- xx = (y-m[2][1]*zz)/m[0][1];
- } else {
- zz = y/m[2][1];
- xx = (z-m[2][2]*zz)/m[0][2];
- }
- yy = (x-m[2][0]*zz)/m[1][0];
- } else if(Math.abs(m[2][0]) > eps) {
- zz = x/m[2][0];
- if(Math.abs(m[0][1]) > eps) {
- var f = m[0][2]/m[0][1];
- m[1][2] -= m[1][1]*f; z -= y*f;
- yy = z/m[1][2];
- xx = (y-yy*m[1][1]-zz*m[2][1])/m[0][1];
- } else {
- yy = y/m[1][1];
- xx = (z-yy*m[1][2]-zz*m[2][2])/m[0][2];
- }
- }
- var badResult = false;
- if(xx == null || yy == null || zz == null || xx != xx || yy != yy || zz != zz)
- badResult = true;
- if(Math.abs(xx) == Infinity || Math.abs(yy) == Infinity || Math.abs(zz) == Infinity)
- badResult = true;
- if(badResult) {
- console.log('obtained bad result in solve function: ', xx, yy, zz);
- criticalFlag = 1.0;
- return new SpacePoint(0.0, 0.0, 0.0);
- }
- return new SpacePoint(xx, yy, zz);
- }
- function distanceCompare(a, b) {
- if(a.c == null)
- return -1;
- if(b.c == null)
- return 1;
- // Greater distance gets drawn first.
- var d1 = b.c.x*b.c.x+b.c.y*b.c.y+b.c.z*b.c.z;
- var d0 = a.c.x*a.c.x+a.c.y*a.c.y+a.c.z*a.c.z;
- return d1-d0;
- }
- function handleMovement() {
- if(map.getCell(int(plr.x), int(plr.y), int(plr.z)) == 1) {
- console.log('Player inside a wall: ', plr.x, plr.y, plr.z);
- criticalFlag = 1.0;
- plr.x = restart.x; plr.y = restart.y; plr.z = restart.z;
- }
- var x = (keys.v-keys.z)*KeyDelta;
- var y = (keys.x-keys.c)*KeyDelta;
- var z = (keys.r-keys.f)*KeyDelta;
- if(mbstate[0] > 0 && mouseButtonPrecedence(1, 2)) {
- plrSpeed = clip(plrSpeed+(mbpos.y-msy)*SpeedDelta, -MaxSpeed, MaxSpeed);
- mbpos.y = msy;
- }
- z = clip(z+plrSpeed, -MaxSpeed, MaxSpeed);
- if(mbstate[0] == 0 && mouseButtonPrecedence(1, 2)) {
- x = clip(x+(msx-mbpos.x)*KeyDelta, -KeyDelta, KeyDelta);
- y = clip(y+(msy-mbpos.y)*KeyDelta, -KeyDelta, KeyDelta);
- mbpos = { x: msx, y: msy };
- }
- var offset = solveLinearEquation(tm, x, y, z);
- // Add offset vector to player coordinates one dimension at a time,
- // correcting for collisions.
- // First handle outer maze limits, then handle inner cubes.
- var t = plr.x;
- plr.x = clip(plr.x+offset.x, wallNear, map.w-wallNear);
- map.handleCollisions(plr, wallNear, 'x');
- if(plr.x != plr.x) // NaN
- plr.x = t;
- var t = plr.y;
- plr.y = clip(plr.y+offset.y, wallNear, map.h-wallNear);
- map.handleCollisions(plr, wallNear, 'y');
- if(plr.y != plr.y) // NaN
- plr.y = t;
- var t = plr.z;
- plr.z = clip(plr.z+offset.z, wallNear, map.d-wallNear);
- map.handleCollisions(plr, wallNear, 'z');
- if(plr.z != plr.z) // NaN
- plr.z = t;
- }
- function setPixel(data, w, h, x, y, rc, gc, bc, ac) {
- if(x < 0 || x >= w || y < 0 || y >= h)
- return;
- var i = (y*w+x)*4;
- data[i] = rc;
- data[i+1] = gc;
- data[i+2] = bc;
- data[i+3] = ac;
- }
- function getGoalAlpha() {
- var a = 0.28*Math.cos(goalAngle)+0.72;
- goalAngle = (goalAngle+GoalAngleDelta)%Circ;
- return a;
- }
- function showFPS() {
- var div = document.getElementById('fpsCount');
- div.innerHTML = frames.toString();
- frames = 0;
- }
- function preInit() {
- editBtn = document.getElementById('edit');
- editBtn.addEventListener('click', onEditBtn, false);
- editBtnPressed = false;
- makeBtn = document.getElementById('makeMaze');
- makeBtn.addEventListener('click', onMakeBtn, false);
- winCheck = document.getElementById('winCheck');
- sizeSelect = document.getElementById('sizes');
- sizeSelect.addEventListener('change', onSelectChange, false);;
- instructBtn = document.getElementById('instructions');
- instructBtn.addEventListener('click', onInstructBtn, false);
- canvasSelect = document.getElementById('canvasSizes');
- canvasSelect.addEventListener('change', onCanvasChange, false);
- inTextW = document.getElementById('width');
- inTextH = document.getElementById('height');
- inTextD = document.getElementById('depth');
- inTextW.addEventListener('change', onTextChange, false);
- inTextH.addEventListener('change', onTextChange, false);
- inTextD.addEventListener('change', onTextChange, false);
- window.addEventListener('contextmenu', disableEvent, false);
- changeWindowListeners(true);
- inW = int(inTextW.value), inH = int(inTextH.value), inD = int(inTextD.value);
- mc = new Canvas('mainCanvas', AspectMult);
- mcW = mc.w;
- mcH = mc.h;
- mcChange = false;
- showMap = true;
- requestFrame = (
- window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function(drawFunc) { return setTimeout(drawFunc, 0); } );
- cancelFrame = (
- window.cancelAnimationFrame ||
- window.webkitCancelAnimationFrame ||
- window.mozCancelAnimationFrame ||
- window.msCancelAnimationFrame ||
- function(id) { clearTimeout(id); } );
- frames = 0;
- if(Debug) {
- setInterval(showFPS, 1000);
- } else {
- var fps = document.getElementById('fpsText');
- fps.innerHTML = '';
- }
- init();
- }
- function init() {
- cancelFrame(frameID[1]);
- mc.ct.globalAlpha = 1.0;
- if(mcChange) {
- mc.updateSize(mcW, mcH, AspectMult);
- mcChange = false;
- }
- plrSpeed = 0.0;
- mapZoom = 2.0;
- goalRad = mc.a/6;
- goalAngle = 0.0;
- goalAlpha = getGoalAlpha();
- winState = false;
- keys = {
- w: 0, s: 0, a: 0, d: 0, q: 0, e: 0, r: 0, f: 0, z: 0, x: 0, c: 0, v: 0,
- tab: false, spc: false, minus: false, plus: false };
- mbstate = [ 0, 0, 0 ];
- mbpos = { x: -1, y: -1 };
- // debugging features
- // criticalFlag flashes the screen red when set to 1.0 for a console message.
- criticalFlag = 0.0;
- plr = new SpacePoint(0.5, 0.5, 0.5);
- restart = new SpacePoint(plr.x, plr.y, plr.z);
- map = new Map(inW, inH, inD);
- map.makeMaze(int(plr.x), int(plr.y), int(plr.z));
- tm = identityMatrix();
- if(map.d == 1 || map.getCell(int(plr.x), int(plr.y), int(plr.z)+1) == 1) {
- tm = rotateMatrix(tm, 0, 0, -Pi/2);
- tm = rotateMatrix(tm, 0, -Pi/2, 0);
- if(map.h == 1 || map.getCell(int(plr.x), int(plr.y)+1, int(plr.z)) == 1) {
- tm = rotateMatrix(tm, 0, 0, -Pi/2);
- tm = rotateMatrix(tm, 0, -Pi/2, 0);
- }
- }
- map.setAllPaths();
- var polyPoints = new Array(map.w*map.h*map.d);
- for(var z = 0; z < map.sd; z++)
- for(var y = 0; y < map.sh; y++)
- for(var x = 0; x < map.sw; x++) {
- polyPoints[map.getSIndex(x, y, z)] = new SpacePoint(x, y, z);
- }
- polyVerts = new Array();
- polyDrawn = new Array();
- polyToCube = new Array();
- var len = prePolies[0].length;
- for(var i = 0; i < prePolies.length; i++) {
- var verts = new Array(len);
- var drawn = new Array(len);
- for(var j = 0; j < len; j++) {
- var pt = points[ prePolies[i][len-j-1] ];
- var sIndex = map.getSIndex(pt.x*map.w, pt.y*map.h, pt.z*map.d);
- verts[j] = polyPoints[sIndex];
- drawn[j] = true;
- }
- polyVerts.push(verts);
- polyDrawn.push(drawn);
- polyToCube.push(null);
- }
- for(var z = 0; z < map.d; z++)
- for(var y = 0; y < map.h; y++)
- for(var x = 0; x < map.w; x++) {
- if(map.getCell(x, y, z) == 1) {
- for(var i = 0; i < prePolies.length; i++) {
- if(map.sideExists({ x: x, y: y, z: z }, i)) {
- var verts = new Array(len);
- var drawn = new Array(len);
- for(var j = 0; j < len; j++) {
- var pt = points[ prePolies[i][j] ];
- var sIndex = map.getSIndex(pt.x+x, pt.y+y, pt.z+z);
- verts[j] = polyPoints[sIndex];
- if(map.edgeIsDrawn({ x: x, y: y, z: z}, i, j)) {
- drawn[j] = true;
- } else {
- drawn[j] = false;
- }
- }
- polyVerts.push(verts);
- polyDrawn.push(drawn);
- polyToCube.push({ x: x, y: y, z: z });
- }
- }
- }
- }
- frameID[0] = requestFrame(output);
- }
- function drawMaze() {
- map.fillSpace(plr, tm);
- map.setSeenPathCells(plr);
- map.setVisibleCells(plr);
- var visPolies = new Array();
- for(var i = 0; i < polyVerts.length; i++) {
- var vis = polyToCube[i];
- if(vis != null && !map.getVCell(vis.x, vis.y, vis.z)) {
- continue;
- }
- var p = polyVerts[i];
- var d = polyDrawn[i];
- var s = new Array(polyVerts[0].length);
- var xa = 0, ya = 0, za = 0;
- for(var j = 0; j < s.length; j++) {
- s[j] = map.getSpace(p[j].x, p[j].y, p[j].z);
- xa += s[j].x;
- ya += s[j].y;
- za += s[j].z;
- }
- var ahead = false;
- for(var j = 0; j < s.length; j++) {
- if(s[j].z >= zNear) {
- p = p.slice(j).concat(p.slice(0, j));
- d = d.slice(j).concat(d.slice(0, j));
- s = s.slice(j).concat(s.slice(0, j));
- ahead = true;
- break;
- }
- }
- if(ahead) {
- if(i < 6) {
- var c = null;
- } else {
- var c = new SpacePoint(xa/4, ya/4, za/4) };
- }
- visPolies.push({ p: p, d: d, s: s, c: c });
- }
- // Sort goal point with rest of the polygons
- var x = map.goal.x+0.5-plr.x, y = map.goal.y+0.5-plr.y, z = map.goal.z+0.5-plr.z;
- var mat = multiplyMatrices([ [ x, y, z, 1 ] ], tm);
- x = mat[0][0], y = mat[0][1], z = mat[0][2];
- goalDis = Math.sqrt(x*x+y*y+z*z);
- if(winCheck.checked)
- if(int(plr.x) == map.goal.x && int(plr.y) == map.goal.y && int(plr.z) == map.goal.z)
- setTimeout(showWinDisplay, 0);
- if(z >= zNear)
- visPolies.push({ p: null, d: null, s: null, c: { x: x, y: y, z: z } });
- visPolies.sort(distanceCompare);
- for(var i = 0; i < visPolies.length; i++) {
- var vp = visPolies[i];
- if(vp.p == null) {
- // Draw physical goal circle
- var f = flattenPoint(vp.c, mc);
- mc.ct.fillStyle = RGBA(223, 31, 31, goalAlpha);
- mc.ct.beginPath();
- mc.ct.closePath();
- var x = vp.c.x, y = vp.c.y, z = vp.c.z;
- mc.ct.arc(f.x, f.y, goalRad/goalDis, 0, Circ, false);
- mc.ct.fill();
- continue;
- }
- var flatLines = getFlatLines(vp.s, vp.p, vp.d);
- if(flatLines == null)
- continue;
- // Occlude polygons that have anticlockwise-running vertices.
- var t0 = flatLines[flatLines.length-1], t1 = flatLines[0];
- var a0 = Math.atan2(t1.f0.y-t0.f0.y, t1.f0.x-t0.f0.x);
- var a1 = Math.atan2(t1.f1.y-t0.f0.y, t1.f1.x-t0.f0.x);
- var delta = (a1-a0)%Circ;
- if(delta < 0.0)
- delta += Circ;
- if(delta < Pi) {
- mc.ct.beginPath();
- mc.ct.moveTo(flatLines[0].f0.x, flatLines[0].f0.y);
- for(var j = 1; j < flatLines.length; j++) {
- if(flatLines[j].f0 != null)
- mc.ct.lineTo(flatLines[j].f0.x, flatLines[j].f0.y);
- }
- mc.ct.closePath();
- if(i > 5) {
- mc.ct.fillStyle = '#fff';
- mc.ct.fill();
- }
- mc.ct.lineWidth = 1.0;
- mc.ct.strokeStyle = '#fff';
- mc.ct.stroke();
- mc.ct.strokeStyle = '#000';
- for(var j = 0; j < flatLines.length; j++) {
- if(flatLines[j].draw) {
- var x0 = flatLines[j].f0.x, y0 = flatLines[j].f0.y;
- var x1 = flatLines[j].f1.x, y1 = flatLines[j].f1.y;
- mc.ct.beginPath();
- mc.ct.moveTo(x0, y0);
- mc.ct.lineTo(x1, y1);
- mc.ct.stroke();
- mc.ct.closePath();
- }
- }
- }
- }
- if(showMap) {
- // Draw the maze overview map.
- map.fillOverviewSpace(plr, tm);
- mc.ct.lineWidth = 1.0;
- var d = map.maxDim*2;
- for(var z = 0; z < map.rd; z++)
- for(var y = 0; y < map.rh; y++)
- for(var x = 0; x < map.rw; x++) {
- var pc = map.getPathCell(x, y, z);
- if(pc.x.type == -1 && pc.y.type == -1 && pc.z.type == -1)
- continue;
- var t = map.getOSpace(x, y, z);
- var s = { x: t.x*mapZoom, y: t.y*mapZoom, z: t.z*mapZoom+d };
- if(s.z < zNear)
- continue;
- var f0 = flattenPoint(s, mc);
- if(x < map.rw-1 && pc.x.view > -1) {
- t = map.getOSpace(x+1, y, z);
- s = { x: t.x*mapZoom, y: t.y*mapZoom, z: t.z*mapZoom+d };
- if(s.z < zNear)
- continue;
- var f1 = flattenPoint(s, mc);
- mc.ct.strokeStyle = getColor(pc.x);
- mc.ct.beginPath();
- mc.ct.moveTo(f0.x, f0.y);
- mc.ct.lineTo(f1.x, f1.y);
- mc.ct.stroke();
- mc.ct.closePath();
- if(pc.x.time > 0) {
- pc.x.time = clip(pc.x.time+PathTimeInc, 0.0, 1.0);
- if(pc.x.time > 1.0-eps) {
- setColor(pc.x);
- pc.x.time = 0;
- }
- }
- }
- if(y < map.rh-1 && pc.y.view > -1) {
- t = map.getOSpace(x, y+1, z);
- s = { x: t.x*mapZoom, y: t.y*mapZoom, z: t.z*mapZoom+d };
- if(s.z < zNear)
- continue;
- var f1 = flattenPoint(s, mc);
- mc.ct.strokeStyle = getColor(pc.y);
- mc.ct.beginPath();
- mc.ct.moveTo(f0.x, f0.y);
- mc.ct.lineTo(f1.x, f1.y);
- mc.ct.stroke();
- mc.ct.closePath();
- if(pc.y.time > 0) {
- pc.y.time = clip(pc.y.time+PathTimeInc, 0.0, 1.0);
- if(pc.y.time > 1.0-eps) {
- setColor(pc.y);
- pc.y.time = 0;
- }
- }
- }
- if(z < map.rd-1 && pc.z.view > -1) {
- t = map.getOSpace(x, y, z+1);
- s = { x: t.x*mapZoom, y: t.y*mapZoom, z: t.z*mapZoom+d };
- if(s.z < zNear)
- continue;
- var f1 = flattenPoint(s, mc);
- mc.ct.strokeStyle = getColor(pc.z);
- mc.ct.beginPath();
- mc.ct.moveTo(f0.x, f0.y);
- mc.ct.lineTo(f1.x, f1.y);
- mc.ct.stroke();
- mc.ct.closePath();
- if(pc.z.time > 0) {
- pc.z.time = clip(pc.z.time+PathTimeInc, 0.0, 1.0);
- if(pc.z.time > 1.0-eps) {
- setColor(pc.z);
- pc.z.time = 0;
- }
- }
- }
- }
- // Draw goal map circle
- mc.ct.strokeStyle = '#f44';
- mc.ct.lineWidth = 2.0;
- var x = (map.goal.x-plr.x+0.5)/2;
- var y = (map.goal.y-plr.y+0.5)/2;
- var z = (map.goal.z-plr.z+0.5)/2;
- var mat = multiplyMatrices([ [ x, y, z, 1 ] ], tm);
- x = mat[0][0]*mapZoom;
- y = mat[0][1]*mapZoom;
- z = mat[0][2]*mapZoom+d;
- if(z >= zNear) {
- var f = flattenPoint({ x: x, y: y, z: z }, mc);
- mc.ct.beginPath();
- mc.ct.closePath();
- mc.ct.arc(f.x, f.y, 4, 0.0, Circ, false);
- mc.ct.stroke();
- }
- // Draw player circle
- mc.ct.fillStyle = '#0bb';
- var f = flattenPoint({ x: 0, y: 0, z: d }, mc);
- mc.ct.beginPath();
- mc.ct.closePath();
- mc.ct.arc(f.x, f.y, 4, 0.0, Circ, false);
- mc.ct.fill();
- }
- if(criticalFlag > 0.0) {
- mc.ct.fillStyle = RGBA(255, 0, 0, 0.5*criticalFlag);
- mc.ct.fillRect(0, 0, mc.w, mc.h);
- criticalFlag = clip(criticalFlag-0.006, 0.0, 1.0);
- }
- }
- function output() {
- mc.ct.clearRect(0, 0, mc.w, mc.h);
- drawMaze();
- handleRotation();
- handleMovement();
- handleMapKeys();
- goalAlpha = getGoalAlpha();
- frames++;
- frameID[0] = requestFrame(output);
- }
- function showWinDisplay() {
- cancelFrame(frameID[0]);
- winState = true;
- bc = new Canvas([ mc.w, mc.h ], AspectMult);
- bc.ct.clearRect(0, 0, bc.w, bc.h);
- bc.ct.drawImage(mc.cv, 0, 0);
- wc = new Canvas([ mc.w, mc.h ], AspectMult);
- wc.ct.fillStyle = '#fff';
- wc.ct.fillRect(0, 0, wc.w, wc.h);
- var msgs = [
- 'you have completed', 'stage one maze', '',
- 'good job', '',
- 'stage two is', 'under development' ];
- var size = int(mc.h/12);
- var grad = wc.ct.createRadialGradient(wc.hw, wc.hh, 0, wc.hw, wc.hh, wc.hh);
- grad.addColorStop(0.0, '#0f0');
- grad.addColorStop(1.0, '#080');
- wc.ct.fillStyle = grad;
- wc.ct.strokeStyle = '#080';
- wc.ct.lineWidth = 1.0;
- wc.ct.font = size.toString()+'px sans-serif';
- wc.ct.textAlign = 'center';
- wc.ct.textBaseline = 'middle';
- for(var i = 0; i < msgs.length; i++) {
- var y = wc.hh+(i-msgs.length/2)*size*1.2;
- wc.ct.fillText(msgs[i], wc.hw, y);
- wc.ct.strokeText(msgs[i], wc.hw, y);
- }
- winAlpha = 0.0;
- editBtnPressed = false;
- onEditBtn()
- winDisplay();
- }
- function winDisplay() {
- winAlpha = clip(winAlpha+0.01, 0.0, 1.0);
- mc.ct.clearRect(0, 0, mc.w, mc.h);
- mc.ct.globalAlpha = 1.0;
- mc.ct.drawImage(bc.cv, 0, 0);
- mc.ct.globalAlpha = winAlpha;
- mc.ct.drawImage(wc.cv, 0, 0);
- frameID[1] = requestFrame(winDisplay);
- }
- function renderPrompt(msg) {
- var size = int(mc.h/10);
- var grad = mc.ct.createRadialGradient(mc.hw, mc.hh, 0, mc.hw, mc.hh, mc.hh);
- grad.addColorStop(0.0, '#0bb');
- grad.addColorStop(1.0, '#066');
- mc.ct.fillStyle = grad;
- mc.ct.strokeStyle = '#066';
- mc.ct.lineWidth = 1.0;
- mc.ct.font = size.toString()+'px sans-serif';
- mc.ct.textAlign = 'center';
- mc.ct.textBaseline = 'middle';
- mc.ct.fillText(msg, mc.hw, mc.hh);
- mc.ct.strokeText(msg, mc.hw, mc.hh);
- }
- window.addEventListener('load', preInit, false);</script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment