SVG BSP Generator
How do I make an svg bsp generator?
Generates an SVG grid with a BSP tree overlay. Page/grid size and generator options are editable.. What is a svg bsp generator? How do you make a svg bsp generator? This script and codes were developed by Laerin on 26 December 2022, Monday.
SVG BSP Generator - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>SVG BSP Generator</title>
</head>
<body> <script src='js/vdoix.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js'></script> <script src="js/index.js"></script>
</body>
</html>
SVG BSP Generator - Script Codes JS Codes
(function (_x, gen){ // SVG Helper // ============= var ns = 'http://www.w3.org/2000/svg'; function SVG(options){ this.element = document.createElementNS(ns, 'svg'); for (var prop in options) this.element.setAttribute(prop, options[prop]); } // SVG Helper Prototype // ====================== SVG.prototype = { createElement: function(name){ var el = document.createElementNS(ns, name); return el; }, appendChild: function(el){ this.element.appendChild(el); }, addElement: function(name){ var el = document.createElementNS(ns, name); this.element.appendChild(el); return el; }, setFill: function(el, fill){ el.setAttribute('fill', fill); }, setStroke: function(el, stroke, width){ el.setAttribute('stroke', stroke); el.setAttribute('stroke-width', width); }, createLine: function(x1, x2, y1, y2){ var l = this.createElement('line'); l.setAttribute('x1', x1); l.setAttribute('y1', y1); l.setAttribute('x2', x2); l.setAttribute('y2', y2); return l; }, createRect: function(x, y, w, h){ var r = this.createElement('rect'); r.setAttribute('x', x); r.setAttribute('y', y); r.setAttribute('width', w); r.setAttribute('height', h); return r; }, addLine: function(x1, x2, y1, y2){ var l = this.createLine(x1, x2, y1, y2); this.appendChild(l); return l; }, addRect: function(x, y, w, h){ var r = this.createRect(x, y, w, h); this.appendChild(r); return r; } }; function makePatterns(svg){ var defs = svg.addElement('defs'); var grid = svg.createElement('pattern'); var path = document.createElementNS(ns, 'path'); grid.setAttribute('id', 'grid'); grid.setAttribute('width', '10'); grid.setAttribute('height', '10'); grid.setAttribute('patternUnits', 'userSpaceOnUse'); path.setAttribute('d', 'M 10 0 L 0 0 0 10'); svg.setFill(path, 'none'); svg.setStroke(path, 'gray', 0.5); grid.appendChild(path); var hatch = svg.createElement('pattern'); var l1 = svg.createLine(0, 5, 0, 5); var l2 = svg.createLine(5, 0, 0, 5); hatch.setAttribute('id', 'hatch'); hatch.setAttribute('width', '5'); hatch.setAttribute('height', '5'); hatch.setAttribute('patternUnits', 'userSpaceOnUse'); svg.setStroke(l1, 'gray', 0.5); svg.setStroke(l2, 'gray', 0.5); hatch.appendChild(l1); hatch.appendChild(l2); defs.appendChild(grid); defs.appendChild(hatch); } // Render the walls // ================= function renderWalls(svg, bsp){ renderWallsH(svg, bsp); renderWallsV(svg, bsp); } // Render Vertical Walls // ====================== function renderWallsV(svg, bsp){ // Handle Vertical Walls for (var x = 0; x < bsp.width; x++){ var lines = []; var cLeft = undefined; var cRight = undefined; for (var y = 0; y < bsp.height; y++){ var t = bsp.map[y * bsp.width + x]; var clearL = false; var clearR = false; // Get cleared lines if (x == 0) clearL = true; else{ var t1 = bsp.map[y * bsp.width + x - 1]; clearL = !(t1 == bsp.mapDef.WALL); } if (x == bsp.width - 1) clearR = true; else{ var t1 = bsp.map[y * bsp.width + x + 1]; clearR = !(t1 == bsp.mapDef.WALL); } // Deal with the left if (cLeft){ if (t == bsp.mapDef.WALL && clearL){ cLeft.l += 1; } else cLeft = undefined; } else{ if (t == bsp.mapDef.WALL && clearL){ cLeft = { x: x, y: y, l: 1}; lines.push(cLeft); } } // Deal with the right if (cRight){ if (t == bsp.mapDef.WALL && clearR){ cRight.l += 1; } else cRight = undefined; } else{ if (t == bsp.mapDef.WALL && clearR){ cRight = { x: x + 1, y: y, l: 1}; lines.push(cRight); } } } for(var i = 0; i < lines.length; i++){ var l = svg.addLine(lines[i].x * 10, lines[i].x * 10, lines[i].y * 10, (lines[i].y + lines[i].l) * 10); svg.setStroke(l, 'gray', 1); } } } // Render the horizontal walls // ============================== function renderWallsH(svg, bsp){ // Handle the horizontal walls for (var y = 0; y < bsp.height; y++){ var lines = []; var cTop = undefined; var cBottom = undefined; for (var x = 0; x < bsp.width; x++){ var t = bsp.map[y * bsp.width + x]; var clearT = false; var clearB = false; // Get cleared lines if (y == 0) clearT = true; else{ var t1 = bsp.map[(y - 1) * bsp.width + x]; clearT = !(t1 == bsp.mapDef.WALL); } if (y == bsp.height - 1) clearB = true; else{ var t1 = bsp.map[(y + 1) * bsp.width + x]; clearB = !(t1 == bsp.mapDef.WALL); } // Deal with the top if (cTop){ if (t == bsp.mapDef.WALL && clearT){ cTop.l += 1; } else cTop = undefined; } else{ if (t == bsp.mapDef.WALL && clearT){ cTop = { x: x, y: y, l: 1 }; lines.push(cTop); } } // Deal with the bottom if (cBottom){ if (t == bsp.mapDef.WALL && clearB){ cBottom.l += 1; } else cBottom = undefined; } else{ if (t == bsp.mapDef.WALL && clearB){ cBottom = {x: x, y: y + 1, l: 1 }; lines.push(cBottom); } } } for(var i = 0; i < lines.length; i++){ var l = svg.addLine(lines[i].x * 10, (lines[i].x + lines[i].l) * 10, lines[i].y * 10, lines[i].y * 10); svg.setStroke(l, 'gray', 1); } } } // Render the floors // Break up the floor rendering to be better able to // print the SVG when finished function renderFloors(svg, bsp){ var leaves = renderRoomFloors(svg, bsp); renderCorridorFloors(svg, bsp, leaves); } // Render the floors of the rooms as a single rect function renderRoomFloors(svg, bsp){ var stack = []; var leaves = []; stack.push(bsp.tree); while (stack.length > 0){ var room = stack.pop(); if (room === undefined) continue; if (room.left === undefined && room.right === undefined){ var rect = svg.addRect((room.size.x + 1) * 10, (room.size.y + 1) * 10 + 1, (room.size.width - 2) * 10, (room.size.height - 2) * 10); svg.setStroke(rect, 'none', 0); svg.setFill(rect, 'url(#grid)'); leaves.push(room); } else{ stack.push(room.right); stack.push(room.left); } } return leaves; } // Render each tile of the corridor as a rect // - Not the greatest of methods function renderCorridorFloors(svg, bsp, leaves){ // Not the greatest implementation right now for (var y = 0; y < bsp.height; y++){ for (var x = 0; x < bsp.width; x++){ var t = bsp.map[y * bsp.width + x]; if (t == bsp.mapDef.FLOOR){ var renderIt = true; // ewwwwww for (var i = 0; i < leaves.length; i++){ var leaf = leaves[i]; if (x >= leaf.size.x + 1 && x <= leaf.size.x + leaf.size.width - 2 && y >= leaf.size.y + 1 && y <= leaf.size.y + leaf.size.height - 2) { renderIt = false; break; } } if (renderIt){ var rect = svg.addRect(x * 10, y * 10, 10, 10); svg.setStroke(rect, 'none', 0); svg.setFill(rect, 'url(#grid)'); } } } } } // SVG Dungeon Gen // ================ function svgD(options){ var opt = { width: 7.5, height: 10, gridSize: 0.125, units: 'in', seed: Date.now(), renderFloors: true, renderWalls: true, renderGrid: true, renderPartitions: true, roomSize: 10, minDepth: 4, splitChance: 0.35 }; for (var prop in options){ if (opt.hasOwnProperty(prop)) opt[prop] = options[prop]; } var w = (opt.width / opt.gridSize) | 0; var h = (opt.height / opt.gridSize) | 0; var bsp = gen.BSP({ width: w, height: h, roomSize: opt.roomSize, minDepth: opt.minDepth, splitChance: opt.splitChance, seed: opt.seed }); var svg = new SVG({ width: opt.width + opt.units, height: opt.height + opt.units, viewBox: '0 0 ' + (w * 10 + 1) + ' ' + (h * 10 + 1) }); makePatterns(svg); // Add grid if needed var grid = svg.addRect(0, 0, '100%', '100%'); if (opt.renderGrid) svg.setFill(grid, 'url(#grid)'); else svg.setFill(grid, 'none'); // Render floors if (opt.renderFloors && !opt.renderGrid) renderFloors(svg, bsp); // Render walls if (opt.renderWalls) renderWalls(svg, bsp); // Render Partitions if (opt.renderPartitions){ for (var i = 0; i < bsp.connections.length; i++){ var l = bsp.connections[i].left.bounds; var r = bsp.connections[i].right.bounds; var lR = svg.addRect(l.x * 10, l.y * 10, l.width * 10, l.height * 10); var rR = svg.addRect(r.x * 10, r.y * 10, r.width * 10, r.height * 10); svg.setFill(lR, 'none'); svg.setFill(rR, 'none'); svg.setStroke(lR, 'gray', 1); svg.setStroke(rR, 'gray', 1); } } return { svg: svg.element, width: opt.width, height: opt.height, seed: opt.seed }; } _x.SVGDungeon = svgD;
})(window.XG5 || (window.XG5 = {}), window.DGEN);
var options = { width: 7.5, height: 10, gridSize: 0.125, units: 'in', roomSize: 10, depth: 4, split: 0.35, seed: Date.now(), floors: true, walls: true, grid: false, partitions: false, svgDungeon: undefined, render: function(){ if (this.svgDungeon) document.body.removeChild(this.svgDungeon.svg); this.svgDungeon = XG5.SVGDungeon({ width: this.width, height: this.height, gridSize: this.gridSize, units: this.units, seed: this.seed, renderFloors: this.floors, renderWalls: this.walls, renderGrid: this.grid, renderPartitions: this.partitions, roomSize: this.roomSize, minDepth: this.depth, splitChance: this.split }); document.body.appendChild(this.svgDungeon.svg); }, newSeed: function(){ this.seed = Date.now(); }, download: function(){ var a = document.createElement('a'); // Save SVG document // Uses code from this Stackoverflow answer: // http://stackoverflow.com/a/23218877/813114 var serializer = new XMLSerializer(); var svg = serializer.serializeToString(this.svgDungeon.svg); if(!svg.match(/^<svg[^>]+xmlns="http\:\/\/www\.w3\.org\/2000\/svg"/)) svg = svg.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"'); if(!svg.match(/^<svg[^>]+"http\:\/\/www\.w3\.org\/1999\/xlink"/)) svg = svg.replace(/^<svg/, '<svg xmlns:xlink="http://www.w3.org/1999/xlink"'); svg = '<?xml version="1.0" standalone="no"?>\r\n' + svg; var blob = new Blob([svg], {type: "image/svg+xml"}); a.setAttribute('download', 'dungeon.svg'); a.href = URL.createObjectURL(blob); a.click(); }
};
var gui = new dat.GUI();
gui.add(options, 'render');
gui.add(options, 'newSeed');
gui.add(options, 'seed').listen();
var siz = gui.addFolder('Size');
siz.add(options, 'width');
siz.add(options, 'height');
siz.add(options, 'gridSize');
siz.add(options, 'units', ['in', 'mm']);
var genOpt = gui.addFolder('Generator Options');
genOpt.add(options, 'roomSize');
genOpt.add(options, 'depth');
genOpt.add(options, 'split');
var renOpt = gui.addFolder('Render Options');
renOpt.add(options, 'floors');
renOpt.add(options, 'walls');
renOpt.add(options, 'grid');
renOpt.add(options, 'partitions');
gui.add(options, 'download');
options.render();
Developer | Laerin |
Username | xgundam05 |
Uploaded | December 26, 2022 |
Rating | 3 |
Size | 16,181 Kb |
Views | 6,072 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Node Editor UI | 4,055 Kb |
Threaded Voxel-based Terrain example | 13,810 Kb |
Stat Polygon using JS and SVG | 2,954 Kb |
Matrix Effect | 2,532 Kb |
Perlin Terrain | 17,857 Kb |
CSS Loading Graphic | 1,765 Kb |
Slalom Prototype | 4,133 Kb |
Perlin Noise Density Visualization | 4,494 Kb |
WebGL Shader Editor mockup | 3,722 Kb |
YALP - Yet Another Life Pen | 2,994 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Nested table email layout | Massimo-cassandro | 2,355 Kb |
Page Transitions in Backbone | Mikefowler | 3,691 Kb |
FCC - Tribute Page | Cmwebby | 0 Kb |
Experiments with Vertical Centering | KatieK2 | 3,924 Kb |
CSS Variables | Jdsteinbach | 4,759 Kb |
Popover Example | Seanboom | 2,429 Kb |
Text Blocks Over Image, Updated | KatieK2 | 3,122 Kb |
BSP Dungeon Generation | Xgundam05 | 5,326 Kb |
Scroll effect with text with help from Skrollr | Luxonglassing | 2,935 Kb |
Countdown Timer | Massiebn | 3,001 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!