Procedural Dungeon

by Sam Fereday

HTML

<canvas id="viewport" width=500 height=500></canvas>

CSS

#out {
  width: 100%;
  font-family: arial;
  border: 1px solid #ccc;
  padding: 1em;
  box-sizing: border-box;
  float: left;
}

span {
  display: block;
  float: left;
  width: 6.25%;
  padding: 6px;
  text-align: center;
  border: 1px solid #777;
  box-sizing: border-box;
}

JavaScript

console.clear();

var corridors = [];

// Think fibonnacci, it's basically drawing squares in squares, except they're called leaves. Dicks.
// https://eskerda.com/bsp-dungeon-generation/
//var SEED = CryptoJS.MD5("" + new Date().getTime()).toString()
var MAP_SIZE = 50
var SQUARE   = 400 / MAP_SIZE // You end up with 8... I don't get it
var N_ITERATIONS = 4 // Starts to break after 5
var W_RATIO = 0.45
var H_RATIO = 0.45
var DISCARD_BY_RATIO = true
var D_GRID = true
var D_BSP = true
var D_ROOMS = true
var D_PATHS = true

function random(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min)
}

function rectIntersect(r1, r2) {
    return !(
        r1.x > r2.x + r2.w ||
        r1.x + r1.w < r2.x ||
        r1.y > r2.y + r2.h ||
        r1.y + r1.h < r2.y
    )
}

var Point = function(x, y) {
		// May cause issues with centering.
		this.x = Math.floor(x);
    this.y = Math.floor(y);
}

var Room = function(x, y, w, h) {
    this.x = x
    this.y = y
    this.w = w
    this.h = h
    this.center = new Point(this.x + this.w/2, this.y + this.h/2)
}

Room.prototype.paint = function(c) {
    c.fillStyle = "#888"
    c.fillRect(this.x * SQUARE, this.y * SQUARE,
               this.w * SQUARE, this.h * SQUARE)
}

// Usually, this would dig across tiles. But here the slag has just done it using a simple
// line drawing function. I'm sure we can come to some arrangement of course.
var Corridor = function(){
		this.start = {
    	x: 0,
      y: 0
    }
    this.end = {
    	x: 0,
      y: 0
    }
		this.trail = [];
};

Room.prototype.drawPath = function(c, point) {

	var corridorThickness = 1;
	c.beginPath()
    
    // Line widht should match up with the reference to the grid square. Hence why we use 'SQUARE'.
    c.lineWidth   = SQUARE * corridorThickness;  // This is where you'd set your corridor thickness.
        
    // Incorrect values, central location doesn't actually care about grid...
    c.strokeStyle = "#888"
    // We subtract the line width to...