maze.js
22/2 2012gjort ▦ ☯︎ js slump
Maze.js draws a maze to a canvas. It works like this, and looks like this:
//
// © 2012 lhli.net.
// Licence: http://creativecommons.org/licenses/by-sa/3.0/
//
/* example:
var maze = new Maze(
document.getElementById("mazeCanvas").getContext("2d"),
100,
100,
'#000',
true,
true); */
function Maze(canvasContext, width, height, color, fullWindow, drawRandomly) {
var _c = canvasContext;
var _width = width || 10;
var _height = height || 10;
var _drawRandomly = drawRandomly || true;
var _color = color || 'rgba(0, 0, 0, 1)';
var _pixelWidth = 5;
var _lineWidth = 2;
var _thisPixel = null;
var _prevPixel = new Pixel(0,0,-1);
var _chunkSize = 10;
var _tick = 0;
if (fullWindow) {
_c.canvas.width = window.innerWidth;
_c.canvas.height = window.innerHeight;
_width = Math.floor(window.innerWidth/_pixelWidth);
_height = Math.floor(window.innerHeight/_pixelWidth);
} else {
_c.canvas.width = _width*_pixelWidth;
_c.canvas.height = _height*_pixelWidth;
}
var _matrix = (function () {
var m = [];
for (var x=0; x < _width; x++) {
m.push([]);
for (var y=0; y < _height; y++) {
m[x].push(new Pixel(x,y,0));
};
};
return m;
})();
var _whitePixels = (function () {
var w = [];
for (var x=0; x < _width; x++) {
for (var y=0; y < _height; y++) {
w.push(new Pixel(x,y,0));
};
};
return w;
})();
_c.fillStyle = _color;
_c.strokeStyle = _color;
_c.lineWidth = _lineWidth;
_c.lineJoin = _c.lineCap = 'round';
render();
function render() {
if (_thisPixel === null) {
_thisPixel = getWhitePixel();
if (_thisPixel === null) return;
};
_thisPixel.state = getState(_thisPixel);
renderPixel(_thisPixel, _prevPixel);
setAsBlackPixel(_thisPixel);
_prevPixel = _thisPixel;
_thisPixel = setNextPixel(_thisPixel);
if (_tick<_chunkSize) {
_tick++;
render();
} else {
_tick = 0;
setTimeout(function() { render(); }, 1);
}
}
function getState(p) {
var states = [1,2,3,4];
while (true) {
if (states.length > 0) {
var state = states[Math.floor(Math.random()*states.length)];
states.splice(states.indexOf(state),1);
} else { return -1; }
try {
switch (state){
// u,r,d,l
case 1: if (_matrix[p.x][p.y-1].state === 0) return state;
break;
case 2: if (_matrix[p.x+1][p.y].state === 0) return state;
break;
case 3: if (_matrix[p.x][p.y+1].state === 0) return state;
break;
case 4: if (_matrix[p.x-1][p.y].state === 0) return state;
break;
}
} catch (e) {}
}
}
function setNextPixel(p) {
switch (p.state){
// u,r,d,l
case 1: return _matrix[p.x][p.y-1];
case 2: return _matrix[p.x+1][p.y];
case 3: return _matrix[p.x][p.y+1];
case 4: return _matrix[p.x-1][p.y];
default: return null;
}
}
function renderPixel(p, pp) {
var x = p.x*_pixelWidth, y = p.y*_pixelWidth;
//_c.fillRect(x,y,_pixelWidth,_pixelWidth)
_c.beginPath();
switch (pp.state){
// u,r,d,l
case 1: _c.moveTo(x+_pixelWidth/2, y+_pixelWidth);
break;
case 2: _c.moveTo(x, y+_pixelWidth/2);
break;
case 3: _c.moveTo(x+_pixelWidth/2, y);
break;
case 4: _c.moveTo(x+_pixelWidth, y+_pixelWidth/2);
break;
default: _c.moveTo(x+_pixelWidth/2, y+_pixelWidth/2);
break;
}
_c.lineTo(x+_pixelWidth/2, y+_pixelWidth/2);
switch (p.state){
case 1: _c.lineTo(x+_pixelWidth/2, y);
break;
case 2: _c.lineTo(x+_pixelWidth, y+_pixelWidth/2);
break;
case 3: _c.lineTo(x+_pixelWidth/2, y+_pixelWidth);
break;
case 4: _c.lineTo(x, y+_pixelWidth/2);
break;
default: _c.lineTo(x+_pixelWidth/2, y+_pixelWidth/2+.5);
break;
}
_c.stroke();
}
function getWhitePixel() {
if (!_drawRandomly) {
for (var y=0; y < _height; y++) {
for (var x=0; x < _width; x++) {
if (_matrix[x][y].state == 0) return _matrix[x][y];
};
};
} else {
if (_whitePixels.length > 0) {
var p = _whitePixels[Math.floor(Math.random()*_whitePixels.length)];
return _matrix[p.x][p.y]
};
}
return null;
}
function setAsBlackPixel(p) {
for (var i=0, l=_whitePixels.length; i < l; i++) {
if (_whitePixels[i].x == p.x && _whitePixels[i].y == p.y ) {
_whitePixels.splice(i, 1);
break;
}
};
}
function Pixel(x, y, state) {
this.x = x;
this.y = y;
this.state = state;
}
}
// © 2012 lhli.net.
// Licence: http://creativecommons.org/licenses/by-sa/3.0/
//
/* example:
var maze = new Maze(
document.getElementById("mazeCanvas").getContext("2d"),
100,
100,
'#000',
true,
true); */
function Maze(canvasContext, width, height, color, fullWindow, drawRandomly) {
var _c = canvasContext;
var _width = width || 10;
var _height = height || 10;
var _drawRandomly = drawRandomly || true;
var _color = color || 'rgba(0, 0, 0, 1)';
var _pixelWidth = 5;
var _lineWidth = 2;
var _thisPixel = null;
var _prevPixel = new Pixel(0,0,-1);
var _chunkSize = 10;
var _tick = 0;
if (fullWindow) {
_c.canvas.width = window.innerWidth;
_c.canvas.height = window.innerHeight;
_width = Math.floor(window.innerWidth/_pixelWidth);
_height = Math.floor(window.innerHeight/_pixelWidth);
} else {
_c.canvas.width = _width*_pixelWidth;
_c.canvas.height = _height*_pixelWidth;
}
var _matrix = (function () {
var m = [];
for (var x=0; x < _width; x++) {
m.push([]);
for (var y=0; y < _height; y++) {
m[x].push(new Pixel(x,y,0));
};
};
return m;
})();
var _whitePixels = (function () {
var w = [];
for (var x=0; x < _width; x++) {
for (var y=0; y < _height; y++) {
w.push(new Pixel(x,y,0));
};
};
return w;
})();
_c.fillStyle = _color;
_c.strokeStyle = _color;
_c.lineWidth = _lineWidth;
_c.lineJoin = _c.lineCap = 'round';
render();
function render() {
if (_thisPixel === null) {
_thisPixel = getWhitePixel();
if (_thisPixel === null) return;
};
_thisPixel.state = getState(_thisPixel);
renderPixel(_thisPixel, _prevPixel);
setAsBlackPixel(_thisPixel);
_prevPixel = _thisPixel;
_thisPixel = setNextPixel(_thisPixel);
if (_tick<_chunkSize) {
_tick++;
render();
} else {
_tick = 0;
setTimeout(function() { render(); }, 1);
}
}
function getState(p) {
var states = [1,2,3,4];
while (true) {
if (states.length > 0) {
var state = states[Math.floor(Math.random()*states.length)];
states.splice(states.indexOf(state),1);
} else { return -1; }
try {
switch (state){
// u,r,d,l
case 1: if (_matrix[p.x][p.y-1].state === 0) return state;
break;
case 2: if (_matrix[p.x+1][p.y].state === 0) return state;
break;
case 3: if (_matrix[p.x][p.y+1].state === 0) return state;
break;
case 4: if (_matrix[p.x-1][p.y].state === 0) return state;
break;
}
} catch (e) {}
}
}
function setNextPixel(p) {
switch (p.state){
// u,r,d,l
case 1: return _matrix[p.x][p.y-1];
case 2: return _matrix[p.x+1][p.y];
case 3: return _matrix[p.x][p.y+1];
case 4: return _matrix[p.x-1][p.y];
default: return null;
}
}
function renderPixel(p, pp) {
var x = p.x*_pixelWidth, y = p.y*_pixelWidth;
//_c.fillRect(x,y,_pixelWidth,_pixelWidth)
_c.beginPath();
switch (pp.state){
// u,r,d,l
case 1: _c.moveTo(x+_pixelWidth/2, y+_pixelWidth);
break;
case 2: _c.moveTo(x, y+_pixelWidth/2);
break;
case 3: _c.moveTo(x+_pixelWidth/2, y);
break;
case 4: _c.moveTo(x+_pixelWidth, y+_pixelWidth/2);
break;
default: _c.moveTo(x+_pixelWidth/2, y+_pixelWidth/2);
break;
}
_c.lineTo(x+_pixelWidth/2, y+_pixelWidth/2);
switch (p.state){
case 1: _c.lineTo(x+_pixelWidth/2, y);
break;
case 2: _c.lineTo(x+_pixelWidth, y+_pixelWidth/2);
break;
case 3: _c.lineTo(x+_pixelWidth/2, y+_pixelWidth);
break;
case 4: _c.lineTo(x, y+_pixelWidth/2);
break;
default: _c.lineTo(x+_pixelWidth/2, y+_pixelWidth/2+.5);
break;
}
_c.stroke();
}
function getWhitePixel() {
if (!_drawRandomly) {
for (var y=0; y < _height; y++) {
for (var x=0; x < _width; x++) {
if (_matrix[x][y].state == 0) return _matrix[x][y];
};
};
} else {
if (_whitePixels.length > 0) {
var p = _whitePixels[Math.floor(Math.random()*_whitePixels.length)];
return _matrix[p.x][p.y]
};
}
return null;
}
function setAsBlackPixel(p) {
for (var i=0, l=_whitePixels.length; i < l; i++) {
if (_whitePixels[i].x == p.x && _whitePixels[i].y == p.y ) {
_whitePixels.splice(i, 1);
break;
}
};
}
function Pixel(x, y, state) {
this.x = x;
this.y = y;
this.state = state;
}
}