xxxxxxxxxx
141
// Based on this article:
// http://www.roguebasin.com/index.php/Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels
let tiles = [];
let tileMap = [];
const w = 40;
const h = 40;
let tileSet = {};
const groundBones = 3;
const groundStone = 2;
const ground = 1;
const wall = 0;
const wallBottom = -1;
const wallVoid = -2;
const generationSteps = 5;
function preload() {
tileSet[groundBones] = loadImage("textures/groundBones.png");
tileSet[groundStone] = loadImage("textures/groundStone.png");
tileSet[ground] = loadImage("textures/ground.png");
tileSet[wall] = loadImage("textures/wall.png");
tileSet[wallBottom] = loadImage("textures/wallBottom.png");
tileSet[wallVoid] = loadImage("textures/wallVoid.png");
}
function setup() {
createCanvas(600, 600);
generate();
noStroke();
}
function draw() {
background(220);
const cellSize = width/w;
for(let j = 0; j < h; j ++) {
for(let i = 0; i < w; i ++) {
const tile = tileMap[i + j * w];
const img = tileSet[tile];
image(img, i * cellSize, j * cellSize, cellSize, cellSize);
}
}
}
function mouseReleased() {
generate();
}
function generate() {
tiles = [];
for(let j = 0; j < h; j ++) {
for(let i = 0; i < w; i ++) {
const solid = random(1) < 0.45;
tiles.push(solid);
}
}
for(let i = 0; i < generationSteps; i ++) {
iterateTiles();
}
toTileSet();
}
function toTileSet() {
tileMap = [];
for(let j = 0; j < h; j ++) {
for(let i = 0; i < w; i ++) {
const solid = isSolid(i, j);
const solidBelow = isSolid(i, j + 1);
const num = numWallsAround(i, j);
if(num === 9) {
tileMap.push(wallVoid);
} else if(solid) {
if(solidBelow) {
tileMap.push(wall);
} else {
tileMap.push(wallBottom);
}
} else {
if(random() < 0.02) {
if(random() < 0.5) {
tileMap.push(groundStone);
} else {
tileMap.push(groundBones);
}
} else {
tileMap.push(ground);
}
}
}
}
}
function iterateTiles() {
newTiles = [];
for(let j = 0; j < h; j ++) {
for(let i = 0; i < w; i ++) {
const num = numWallsAround(i, j);
const newTile = num >= 5;
newTiles.push(newTile);
}
}
tiles = newTiles;
}
function numWallsAround(x, y) {
let num = 0;
for(let i = -1; i <= 1; i ++) {
for(let j = -1; j <= 1; j ++) {
if(isSolid(x + i, y + j)) {
num ++;
}
}
}
return num;
}
function isSolid(x, y) {
if(x < 0 || x >= w || y < 0 || y >= h) {
return true;
}
return tiles[x + y * w];
}