index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/radial.js')
-rw-r--r-- | src/radial.js | 409 |
1 files changed, 176 insertions, 233 deletions
diff --git a/src/radial.js b/src/radial.js index a6ddd25..1ab2642 100644 --- a/src/radial.js +++ b/src/radial.js @@ -135,6 +135,7 @@ function drawHexes(el, list, renderText = false) { if (renderText) addHexText(q, r, s, t).forEach(txt => cell.appendChild(txt)); + list.set(key, cell); el.appendChild(cell); } } @@ -194,117 +195,61 @@ function translateCoords(map, translator) { return translated; } -function placeBuilding(buildingSelector, mapsheetSelector) { - const building = svg.querySelector(buildingSelector); - const bld2grid = document.createElementNS(xmlns, 'g'); - const bld2origin = { q: 0, r: 0, s: 0 }; +document.querySelectorAll('[name="select-elevation"]').forEach(el => { + const gameboard = document.querySelector('.gameboard'); - const bld2map2 = svg.querySelector(`${mapsheetSelector} ${buildingSelector}`); - const [q, r, s] = bld2map2.dataset.placement.split(',').map(n => +n); - const map2bld2place = { q, r, s }; - - bld2hexes = building.querySelector('[data-grid-footprint]').dataset.gridFootprint.split(':').map(coords => { - const [q, r, s] = coords.split(',').map(n => +n); - const { q: tq, r: tr, s: ts } = translateRadialCoords({ q, r, s }, map2bld2place); - - return [toKey({ q: tq, r: tr, s: ts }), null]; - }); - - const bld2screenCoords = radialToScreenCoords(translateRadialCoords(bld2origin, map2bld2place)); - const bld2structure = document.createElementNS(xmlns, 'g'); - bld2structure.setAttributeNS(null, 'transform', `translate(${bld2screenCoords.x}, ${bld2screenCoords.y})`) - - building.querySelectorAll('[data-grid-footprint] > *').forEach(el => { - const use = document.createElementNS(xmlns, 'use'); - use.setAttributeNS(null, 'href', `#${el.id}`); - el.classList.forEach(className => use.classList.add(className)); - bld2structure.appendChild(use); + el.addEventListener('change', function (e) { + gameboard.dataset.viewElevation = this.value }); +}); - drawHexes(bld2grid, new Map(bld2hexes), true); - - const bld2elvBasement = bld2grid.cloneNode(true); - bld2elvBasement.classList.add('elevation-basement'); - bld2map2.appendChild(bld2elvBasement); - - const bld2elv1 = bld2grid.cloneNode(true); - bld2elv1.classList.add('elevation-0'); - bld2map2.appendChild(bld2elv1); - - const bld2elv2 = bld2grid.cloneNode(true); - bld2elv2.classList.add('elevation-1'); - bld2map2.appendChild(bld2elv2); - - const bld2elvRoof = bld2grid.cloneNode(true); - bld2elvRoof.classList.add('elevation-roof'); - bld2map2.appendChild(bld2elvRoof); - - bld2map2.appendChild(bld2structure); -} - -// const building1 = generateRadialCoordsRect({ rows: 5, columns: 3, equal: false }, { q: 7, r: -4, s: -3 }); -// const building2 = generateRadialCoordsRect({ rows: 4, columns: 3, odd: true }, { q: 0, r: -4, s: 4 }); -// const building3 = generateRadialCoords(new Map(), { q: -1, r: 2, s: -1 }, 1); - - -// const buildingCoords = [ -// generateRadialCoordsRect({ rows: 4, columns: 8, equal: false }, { q: 18, r: -8, s: -10 }), -// generateRadialCoordsRect({ rows: 8, columns: 2, equal: false }, { q: 9, r: -10, s: 1 }), -// generateRadialCoordsRect({ rows: 6, columns: 13, odd: true }, { q: 2, r: -8, s: 6 }), -// generateRadialCoordsRect({ rows: 1, columns: 10 }, { q: -1, r: -9, s: 10 }), -// generateRadialCoordsRect({ rows: 1, columns: 2 }, { q: -1, r: -2, s: 3 }), -// generateRadialCoordsRect({ rows: 1, columns: 6 }, { q: -8, r: -2, s: 10 }), -// // generateRadialCoordsRect({ rows: 8, columns: 4, odd: true }, { q: 4, r: 3, s: -7 }), -// generateRadialCoordsRect({ rows: 8, columns: 4, odd: true }, { q: -5, r: 3, s: 2 }), -// generateRadialCoordsRect({ rows: 6, columns: 3, equal: false }, { q: -12, r: 3, s: 9 }), - -// // hex building -// // generateRadialCoordsRect({ rows: 8, columns: 4 }, { q: 10, r: 3, s: -13 }), -// // generateRadialCoordsRect({ rows: 3, columns: 1 }, { q: 9, r: 7, s: -16 }), -// // generateRadialCoordsRect({ rows: 5, columns: 1, odd: true }, { q: 5, r: 6, s: -11 }), -// ] - -// building2.forEach(coords => grid.delete(coords)); -// building3.forEach(coords => grid.delete(coords)); +// function placeBuilding(buildingSelector, mapsheetSelector) { +// const building = svg.querySelector(buildingSelector); +// const bld2grid = document.createElementNS(xmlns, 'g'); +// const bld2origin = { q: 0, r: 0, s: 0 }; -// drawHexes(svg, generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, 16)); +// const bld2map2 = svg.querySelector(`${mapsheetSelector} ${buildingSelector}`); +// const [q, r, s] = bld2map2.dataset.placement.split(',').map(n => +n); +// const map2bld2place = { q, r, s }; -// const rectEven = generateRadialCoordsRect({ rows: 2, columns: 2 }, { q: 9, r: -5, s: -4 }); -// const rectOdd = generateRadialCoordsRect({ rows: 2, columns: 2, odd: true }, { q: 8, r: -2, s: -6 }); -// const rectEvenUnevenCols = generateRadialCoordsRect({ rows: 2, columns: 1, equal: false}, { q: 6, r: 1, s: -7 }); -// const rectOddUnevenCols = generateRadialCoordsRect({ rows: 2, columns: 1, odd: true, equal: false}, { q: 5, r: 4, s: -9 }); +// bld2hexes = building.querySelector('[data-grid-footprint]').dataset.gridFootprint.split(':').map(coords => { +// const [q, r, s] = coords.split(',').map(n => +n); +// const { q: tq, r: tr, s: ts } = translateRadialCoords({ q, r, s }, map2bld2place); -// drawHexes(svg, rectEven); -// drawHexes(svg, rectOdd); -// drawHexes(svg, rectEvenUnevenCols); -// drawHexes(svg, rectOddUnevenCols); +// return [toKey({ q: tq, r: tr, s: ts }), null]; +// }); -// drawHexes(svg, generateRadialCoordsRect({ rows: 7, columns: 6, odd: true, equal: false }, { q: 5, r: -5, s: 0 })); +// const bld2screenCoords = radialToScreenCoords(translateRadialCoords(bld2origin, map2bld2place)); +// const bld2structure = document.createElementNS(xmlns, 'g'); +// bld2structure.setAttributeNS(null, 'transform', `translate(${bld2screenCoords.x}, ${bld2screenCoords.y})`) -// const buildings = document.createElementNS(xmlns, 'g'); -// buildings.classList.add('buildings'); +// building.querySelectorAll('[data-grid-footprint] > *').forEach(el => { +// const use = document.createElementNS(xmlns, 'use'); +// use.setAttributeNS(null, 'href', `#${el.id}`); +// el.classList.forEach(className => use.classList.add(className)); +// bld2structure.appendChild(use); +// }); -// const bldElevationBasement = document.createElementNS(xmlns, 'g'); -// bldElevationBasement.classList.add('elevation-basement'); -// buildingCoords.forEach(building => drawHexes(bldElevationBasement, building)); +// drawHexes(bld2grid, new Map(bld2hexes), true); -// const bldElevation1 = document.createElementNS(xmlns, 'g'); -// bldElevation1.classList.add('elevation-0'); -// buildingCoords.forEach(building => drawHexes(bldElevation1, building)); +// const bld2elvBasement = bld2grid.cloneNode(true); +// bld2elvBasement.classList.add('elevation-basement'); +// bld2map2.appendChild(bld2elvBasement); -// const bldElevation2 = document.createElementNS(xmlns, 'g'); -// bldElevation2.classList.add('elevation-1'); -// buildingCoords.forEach(building => drawHexes(bldElevation2, building)); +// const bld2elv1 = bld2grid.cloneNode(true); +// bld2elv1.classList.add('elevation-0'); +// bld2map2.appendChild(bld2elv1); -// buildings.appendChild(bldElevationBasement); -// buildings.appendChild(bldElevation1); -// buildings.appendChild(bldElevation2); +// const bld2elv2 = bld2grid.cloneNode(true); +// bld2elv2.classList.add('elevation-1'); +// bld2map2.appendChild(bld2elv2); -const elevation1 = document.createElementNS(xmlns, 'g'); -elevation1.classList.add('elevation-0'); +// const bld2elvRoof = bld2grid.cloneNode(true); +// bld2elvRoof.classList.add('elevation-roof'); +// bld2map2.appendChild(bld2elvRoof); -const elevation2 = document.createElementNS(xmlns, 'g'); -elevation2.classList.add('elevation-1'); +// bld2map2.appendChild(bld2structure); +// } const buildingHexes = {}; @@ -389,22 +334,14 @@ buildingHexes.bld7 = generateRadialCoords( const grid = generateRadialCoordsRect({ rows: 25, columns: 33 }, { q: 22, r: -12, s: -10 }); // const grid = generateRadialCoordsRect({ rows: 52, columns: 33 }, translateRadialCoords({ q: 22, r: -12, s: -10 }, { q: 1, r: -2, s: 1 }, 7)); -const mapsheet1BuildingData = [ - [{ rows: 6, columns: 3, equal: false }, { q: -4, r: -8, s: 12 }], - [{ rows: 8, columns: 2, equal: false, odd: true }, { q: -10, r: 4, s: 6 }], - - [{ rows: 9, columns: 4, odd: true, equal: false }, { q: 11, r: 3, s: -14 }], - [{ rows: 5, columns: 1 }, { q: 10, r: 6, s: -16 }], - [{ rows: 5, columns: 1, odd: true }, { q: 5, r: 6, s: -11 }], - - [{ rows: 8, columns: 4 }, { q: 17, r: -10, s: -7 }], - - // tree/brush copse - [{ rows: 9, columns: 6, equal: false }, { q: 5, r: -4, s: -1 }], +const mapsheet1BuildingCoords = [ + translateCoords(buildingHexes.bld2, ({ q, r, s }) => ({ q: q + 7, r: r + 7, s: s - 14 })), + translateCoords(buildingHexes.bld4, ({ q, r, s }) => ({ q: -s + 14, r: -r - 6, s: -q - 8 })), + translateCoords(buildingHexes.bld3, ({ q, r, s }) => ({ q: q - 6, r: r - 6, s: s + 12 })), + translateCoords(buildingHexes.bld6, ({ q, r, s }) => ({ q: -s - 12, r: -r + 7, s: -q + 5 })), + generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 4, top: 5, right: 3, bottom: 5 }), ]; -const mapsheet1BuildingCoords = mapsheet1BuildingData.map(([size, start]) => generateRadialCoordsRect(size, start)); - const mapsheet2BuildingCoords = [ translateCoords(buildingHexes.bld1, ({ q, r, s }) => ({ q: q, r: r + 7, s: s - 7 })), translateCoords(buildingHexes.bld2, ({ q, r, s }) => ({ q: q + 7, r: r + 7, s: s - 14 })), @@ -425,15 +362,16 @@ const mapsheet3BuildingCoords = [ translateCoords(buildingHexes.bld7, ({ q, r, s }) => ({ q: q - 12, r: r + 8, s: s + 4 })), ] -// drawHexes(elevation2, translateCoords(buildingHexes.bld7, ({ q, r, s }) => ({ q: q - 12, r: r + 8, s: s + 4 })), true); -// drawHexes(elevation1, buildingHexes.bld7, true); - const mapsheetHexCoords = generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 17, top: 13, right: 17, bottom: 14 }, 'left'); const mapsheet1hexCoords = new Map(mapsheetHexCoords); const mapsheet2hexCoords = new Map(mapsheetHexCoords); const mapsheet3hexCoords = new Map(mapsheetHexCoords); +mapsheet1BuildingCoords.forEach(building => { + for ([coords, v] of building) mapsheet1hexCoords.delete(coords); +}); + mapsheet2BuildingCoords.forEach(building => { for ([coords, v] of building) mapsheet2hexCoords.delete(coords); }); @@ -442,158 +380,163 @@ mapsheet3BuildingCoords.forEach(building => { for ([coords, v] of building) mapsheet3hexCoords.delete(coords); }); -function coordsScenario2() { - const grid = generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 17, top: 39, right: 17, bottom: 40 }); - - // mapsheet2BuildingCoords - // // .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, 13)]) - // .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, 13)]) - // .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { - // for ([coords, v] of building) grid.delete(coords); - // } - // ); - - // mapsheet3BuildingCoords - // .map(([size, start]) => [size, translateRadialCoords(start, { q: 1, r: -2, s: 1 }, -13)]) - // .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { - // for ([coords, v] of building) grid.delete(coords); - // } - // ); - - // mapsheet1BuildingData - // .map(([size, start]) => generateRadialCoordsRect(size, start)).forEach(building => { - // for ([coords, v] of building) grid.delete(coords); - // } - // ); - - return new Map([...mapsheet2hexCoords]); -} - -// drawHexes(elevation1, coordsScenario1(), true); - const gameboard = svg.querySelector('.gameboard'); -function drawScenario1() { - const mapsheet2container = document.createElementNS(xmlns, 'g'); - mapsheet2container.id = 'mapsheet2'; - gameboard.appendChild(mapsheet2container); - - const mapsheet3container = document.createElementNS(xmlns, 'g'); - mapsheet3container.id = 'mapsheet3'; - gameboard.appendChild(mapsheet3container); - - const [map2elevation1, map3elevation1] = [mapsheet2container, mapsheet3container].map(el => { - const hexContainer = document.createElementNS(xmlns, 'g'); - hexContainer.classList.add('elevation-0'); - el.appendChild(hexContainer); - return hexContainer; - }); +let mapsheet1 = { + id: 'mapsheet1', + grid: mapsheet1hexCoords, + buildings: mapsheet1BuildingCoords +}; + +let mapsheet2 = { + id: 'mapsheet2', + grid: mapsheet2hexCoords, + buildings: mapsheet2BuildingCoords +}; + +let mapsheet3 = { + id: 'mapsheet3', + grid: mapsheet3hexCoords, + buildings: mapsheet3BuildingCoords +}; + +function drawMapsheet(gameboard, { id, grid, buildings }) { + const container = document.createElementNS(xmlns, 'g'); + container.id = id; + gameboard.appendChild(container); - [ - [map2elevation1, mapsheet2hexCoords, ({ q, r, s }) => ({ q: q + 7, r: r - 14, s: s + 7 })], - [map3elevation1, mapsheet3hexCoords, ({ q, r, s }) => ({ q: q - 6, r: r + 12, s: s - 6 })], - ].forEach(([el, coords, translator]) => drawHexes(el, translateCoords(coords, translator), true)); + const gridContainer = document.createElementNS(xmlns, 'g'); + gridContainer.classList.add('elevation-0'); + container.appendChild(gridContainer); + drawHexes(gridContainer, grid, true); - mapsheet2BuildingCoords.forEach((buildingCoords, index) => { + const buildingHexes = buildings.reduce((acc, buildingCoords, index) => { const buildingContainer = document.createElementNS(xmlns, 'g'); buildingContainer.classList.add(`building`); buildingContainer.classList.add(`building${index}`); - mapsheet2container.appendChild(buildingContainer); - - const translatedCoords = translateCoords(buildingCoords, ({ q, r, s }) => - ({ q: q + 7, r: r - 14, s: s + 7 }) - ); + container.appendChild(buildingContainer); - ['elevation-0', 'elevation-1', 'elevation-basement'].forEach(elevation => { + [-1, 0, 1].forEach(elevationLevel => { const hexContainer = document.createElementNS(xmlns, 'g'); - hexContainer.classList.add(elevation); + hexContainer.classList.add(`elevation-${elevationLevel === -1 ? 'basement' : elevationLevel}`); buildingContainer.appendChild(hexContainer); - drawHexes(hexContainer, translatedCoords, true); + const hexes = translateCoords(buildingCoords, ({ q, r, s }) => ({ q, r, s, t: elevationLevel })); + drawHexes(hexContainer, hexes, true); + acc = new Map([...acc, ...hexes]); }); - }); - mapsheet3BuildingCoords.forEach((buildingCoords, index) => { - const buildingContainer = document.createElementNS(xmlns, 'g'); - buildingContainer.classList.add(`building`); - buildingContainer.classList.add(`building${index}`); - mapsheet3container.appendChild(buildingContainer); + return acc; + }, new Map()); - const translatedCoords = translateCoords(buildingCoords, ({ q, r, s }) => - ({ q: q - 6, r: r + 12, s: s - 6 }) - ); + return new Map([...grid, ...buildingHexes]); +} - ['elevation-0', 'elevation-1', 'elevation-basement'].forEach(elevation => { - const hexContainer = document.createElementNS(xmlns, 'g'); - hexContainer.classList.add(elevation); - buildingContainer.appendChild(hexContainer); +// const mapsheetHexCoords = generateRadialCoords( +// new Map(), +// { q: 0, r: 0, s: 0 }, +// { left: 17, top: 13, right: 17, bottom: 14 }, +// 'left' +// ); - drawHexes(hexContainer, translatedCoords, true); - }); - }); -} +function drawScenario1() { + const northMapsheet = function(map) { + return translateCoords(map, ({ q, r, s }) => ({ q: q + 7, r: r - 14, s: s + 7 })); + } -// const gameboardGrid = svg.querySelector('.grid'); + const southMapsheet = function(map) { + return translateCoords(map, ({ q, r, s }) => ({ q: q - 6, r: r + 12, s: s - 6 })); + } -// drawScenario1(); + const westMapsheet = function(map) { + return translateCoords(map, ({ q, r, s }) => ({ q: q + 16, r, s: s - 16 })); + } + const eastMapsheet = function(map) { + return translateCoords(map, ({ q, r, s }) => ({ q: q - 17, r, s: s + 17 })); + } -function drawMapsheets([mapsheet]) { - // const mapsheetHexCoords = generateRadialCoords(new Map(), { q: 0, r: 0, s: 0 }, { left: 17, top: 13, right: 17, bottom: 14 }, 'left'); + mapsheet2.grid = westMapsheet(mapsheet2.grid); + mapsheet2.buildings = mapsheet2.buildings.map(westMapsheet); + mapsheet2 = drawMapsheet(gameboard, mapsheet2); - const container = document.createElementNS(xmlns, 'g'); - container.id = 'mapsheet2'; - gameboard.appendChild(container); + mapsheet3.grid = eastMapsheet(mapsheet3.grid); + mapsheet3.buildings = mapsheet3.buildings.map(eastMapsheet); + mapsheet3 = drawMapsheet(gameboard, mapsheet3); - const [elevation1] = [container].map(el => { - const hexContainer = document.createElementNS(xmlns, 'g'); - hexContainer.classList.add('elevation-0'); - el.appendChild(hexContainer); - return hexContainer; - }); + return new Map([...mapsheet2, ...mapsheet3]); +} - [ - [elevation1, mapsheetHexCoords, ({ q, r, s }) => ({ q, r, s })], - ].forEach(([el, coords, translator]) => drawHexes(el, translateCoords(coords, translator), true)); +function drawScenario2() { + const northMapsheet = function(map) { + return translateCoords(map, ({ q, r, s }) => ({ q: q + 13, r: r - 26, s: s + 13 })); + } - mapsheet2BuildingCoords.forEach((buildingCoords, index) => { - const buildingContainer = document.createElementNS(xmlns, 'g'); - buildingContainer.classList.add(`building`); - buildingContainer.classList.add(`building${index}`); - container.appendChild(buildingContainer); + const southMapsheet = function(map) { + return translateCoords(map, ({ q, r, s }) => ({ q: q - 13, r: r + 26, s: s - 13 })); + } - const translatedCoords = translateCoords(buildingCoords, ({ q, r, s }) => - ({ q, r, s }) - ); + mapsheet1 = drawMapsheet(gameboard, mapsheet1); - [-1, 0, 1].forEach(elevationLevel => { - const hexContainer = document.createElementNS(xmlns, 'g'); - hexContainer.classList.add(`elevation-${elevationLevel === -1 ? 'basement' : elevationLevel}`); - buildingContainer.appendChild(hexContainer); + mapsheet2.grid = northMapsheet(mapsheet2.grid); + mapsheet2.buildings = mapsheet2.buildings.map(northMapsheet); + mapsheet2 = drawMapsheet(gameboard, mapsheet2); - drawHexes(hexContainer, translateCoords(translatedCoords, ({ q, r, s }) => ({ q, r, s, t: elevationLevel })), true); - }); - }); + mapsheet3.grid = southMapsheet(mapsheet3.grid); + mapsheet3.buildings = mapsheet3.buildings.map(southMapsheet); + mapsheet3 = drawMapsheet(gameboard, mapsheet3); + + return new Map([...mapsheet1, ...mapsheet2, ...mapsheet3]); } -drawMapsheets([]); +// const scenario1grid = drawScenario1(); +// const scenario2grid = drawScenario2(); -function addGroup(container, className) { - const g = document.createElementNS(xmlns, 'g'); - g.classList.add(className); - container.appendChild(g); - return g; +const horzMapVect = function(map) { + const direction = 1; + // right, { q: -1, r: 0, s: 1 }, 33 + // left, { q: 1, r: 0, s: -1 }, 33 + return translateCoords(map, ({ q, r, s }) => ({ q: q - 33 * direction, r, s: s + 33 * direction })); } +// [-16, 17], [-33, 0, 33], [-49, -16, 17, 50] -// drawHexes(addGroup(gameboard, 'elevation-0'), buildingHexes.bld2, true); +const vertMapVect = function(map) { + const direction = 1; + // up, { q: 1, r: -2, s: 1 }, 13 + // down, { q: -1, r: 2, s: -1 }, 13 + return translateCoords(map, ({ q, r, s }) => ({ q: q - 13 * direction, r: r + 26 * direction, s: s - 13 * direction })); +} -// placeBuilding('.building2', '#mapsheet2'); -// drawHexes(document.querySelector('#mapsheet2 .grid'), mapsheet2, true); +// [[7], [[13], [[14], +// [-6]] [0], [7], +// [-13]] [-6] +// [-12]] -// placeBuilding('.building2', '#mapsheet3'); -// drawHexes(document.querySelector('#mapsheet3 .grid'), mapsheet3, true); +mapsheet2 = drawMapsheet(gameboard, mapsheet2); +mapsheet3.grid = vertMapVect(mapsheet3.grid); +mapsheet3.buildings = mapsheet3.buildings.map(vertMapVect); +mapsheet3 = drawMapsheet(gameboard, mapsheet3); -// defs.after(elevation2); -// gameboardGrid.appendChild(elevation1); -// gameboardGrid.appendChild(elevation2); +const circle = document.createElementNS(xmlns, 'circle'); +circle.setAttributeNS(null, 'r', 5); +circle.setAttributeNS(null, 'fill', 'green'); +circle.setAttributeNS(null, 'stroke', 'gold'); +circle.setAttributeNS(null, 'stroke-width', 1); + +const circle1 = circle.cloneNode(); +circle1.setAttributeNS(null, 'fill', 'blue'); + +const circle2 = circle.cloneNode(); +circle2.setAttributeNS(null, 'fill', 'red'); + +// mapsheet2.get('0,0,0,0').appendChild(circle); +// mapsheet2.get('0,6,-6,1').appendChild(circle1); +// mapsheet2.get('0,9,-9,0').appendChild(circle2); + +function addGroup(container, className) { + const g = document.createElementNS(xmlns, 'g'); + g.classList.add(className); + container.appendChild(g); + return g; +} |