Last active
December 5, 2020 11:11
-
-
Save Larkenx/b5dfb53a8ca041d79e5462617f41453e to your computer and use it in GitHub Desktop.
Javascript unicode box drawing & 8bit bitmasking, see https://gamedevelopment.tutsplus.com/tutorials/how-to-use-tile-bitmasking-to-auto-tile-your-level-layouts--cms-25673
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const key = (x, y) => { | |
return x + ',' + y | |
} | |
const unkey = k => { | |
return k.split(',').map(s => parseInt(s)) | |
} | |
/* Given an x, y coordinate and a hashmap "x,y" => boolean values that indicate whether or not the tile at that | |
coordinate is blocked, this function will calculate the bitmask sum of the given coordinate. */ | |
function computeBitmask(x, y, blockedCells) { | |
let sum = 0 | |
let above = `${x},${y - 1}` | |
let below = `${x},${y + 1}` | |
let left = `${x - 1},${y}` | |
let right = `${x + 1},${y}` | |
let ur = `${x + 1},${y - 1}` | |
let ll = `${x - 1},${y + 1}` | |
let ul = `${x - 1},${y - 1}` | |
let lr = `${x + 1},${y + 1}` | |
let blocked = coord => { | |
return !(coord in blockedCells) || blockedCells[coord] | |
} | |
if (blocked(above)) sum += 2 | |
if (blocked(right)) sum += 16 | |
if (blocked(below)) sum += 64 | |
if (blocked(left)) sum += 8 | |
if (blocked(ul) && blocked(above) && blocked(left)) sum += 1 | |
if (blocked(ur) && blocked(above) && blocked(right)) sum += 4 | |
if (blocked(ll) && blocked(below) && blocked(left)) sum += 32 | |
if (blocked(lr) && blocked(below) && blocked(right)) sum += 128 | |
return sum | |
} | |
/* A map of bitmask sums to a corresponding index of a unicode character */ | |
const sumToTileIdMap = { | |
2: 1, 8: 2, 10: 3, 11: 4, 16: 5, 18: 6, 22: 7, 24: 8, 26: 9, 27: 10, 30: 11, 31: 12, | |
64: 13, 66: 14, 72: 15, 74: 16, 75: 17, 80: 18, 82: 19, 86: 20, 88: 21, 90: 22, 91: | |
23, 94: 24, 95: 25, 104: 26, 106: 27, 107: 28, 120: 29, 122: 30, 123: 31, 126: 32, | |
127: 33, 208: 34, 210: 35, 214: 36, 216: 37, 218: 38, 219: 39, 222: 40, 223: 41, | |
246: 36, 248: 42, 250: 43, 251: 44, 254: 45, 255: 46, 0: 47 | |
} | |
/* This pre-computed matrix of unicode box tiles corresponds to this resource's corner tiles | |
https://gamedevelopment.tutsplus.com/tutorials/how-to-use-tile-bitmasking-to-auto-tile-your-level-layouts--cms-25673 | |
*/ | |
const unicodeBoxTiles = [ | |
['╦', '║', '═', '╝', '╝', '═', '╚', '╚'], | |
['═', '╩', '╩', '╩', '═', '║', '║', '╗'], | |
['╣', '╣', '╔', '╠', '╠', '╦', '╬', '╦'], | |
['═', '╦', '╗', '╣', '║', '╦', '╠', '╠'], | |
['╬', '╔', '╔', '╠', '║', '╦', '╬', '╬'], | |
['╣', '╗', '═', '╩', '╚', '╝', '', '╬'] | |
] | |
const flattenedUnixBoxTiles = [ | |
'╦', '║', '═', '╝', '╝', '═', '╚', '╚', | |
'═', '╩', '╩', '╩', '═', '║', '║', '╗', | |
'╣', '╣', '╔', '╠', '╠', '╦', '╬', '╦', | |
'═', '╦', '╗', '╣', '║', '╦', '╠', '╠', | |
'╬', '╔', '╔', '╠', '║', '╦', '╬', '╬', | |
'╣', '╗', '═', '╩', '╚', '╝', '', '╬' | |
] | |
function getCharacter(sum) { | |
return !(sumToTileIdMap[sum] in flattenedUnixBoxTiles) ? '!' : flattenedUnixBoxTiles[sumToTileIdMap[sum]] | |
} | |
/* Example of a simple room | |
#### ╔══╗ | |
# # ║ ║ | |
#### ╚══╝ | |
*/ | |
/* Generate a boolean matrix of blocked and not blocked tiles */ | |
let T = true | |
let F = false | |
let map = [ | |
[T, T, T, T, T], | |
[T, F, F, F, T], | |
[T, F, F, F, T], | |
[T, T, T, T, T] | |
] | |
/* Create hashmap of blocked cells (this is a standard format for generating maps with rot-js) */ | |
let blockedCells = {} | |
for (let y = 0; y < map.length; y++) { | |
for (let x = 0; x < map[0].length; x++) { | |
blockedCells[key(x, y)] = map[y][x] | |
} | |
} | |
/* For each tile in 2D Matrix, find the corresponding unicode box character associated with it by calculating the bit mask sum | |
if it's wall */ | |
let result = '' | |
for (let y = 0; y < map.length; y++) { | |
for (let x = 0; x < map[0].length; x++) { | |
if (map[y][x]) { | |
let sum = computeBitmask(x, y, blockedCells) | |
result += getCharacter(sum) | |
} else { | |
result += '.' | |
} | |
} | |
result += '\n' | |
} | |
console.log(result) | |
/* Output: | |
╔═══╗ | |
║...║ | |
║...║ | |
╚═══╝ | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment