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')
-rw-r--r-- | src/modules/game.js | 50 | ||||
-rw-r--r-- | src/modules/game/counter.js | 5 | ||||
-rw-r--r-- | src/modules/game/sightLine.js | 170 |
3 files changed, 106 insertions, 119 deletions
diff --git a/src/modules/game.js b/src/modules/game.js index 40d0623..b44d605 100644 --- a/src/modules/game.js +++ b/src/modules/game.js @@ -10,13 +10,16 @@ export default class Game { constructor(svg) { this.svg = svg; - this.firingArc = new FiringArc(svg); - this.sightLine = new SightLine(svg); + + const board = this.getBoard(); + this.firingArc = new FiringArc(svg, board); + this.sightLine = new SightLine(svg, board); this.counter = new Counter(svg); this.setUpCells(); - let counter = this.counter.getCounter({ dataset: { allegiance: 'davion', number: '1' }}); + // debug + const counter = this.counter.getCounter({ dataset: { allegiance: 'davion', number: '1' }}); this.counter.place(counter, this.getCell(17, 25)); this.select(counter); } @@ -58,7 +61,7 @@ export default class Game { } getGridIndex({ parentElement: { dataset: { x }, parentElement: { dataset: { y }}}}) { - return { x, y }; + return { x: +x, y: +y }; } getCounterAtGridIndex(x, y) { @@ -177,7 +180,7 @@ export default class Game { if (!lockedSl) { this.sightLine.clear(); } else { - this.sightLine.update(cell, this.getCellPosition(cell)); + this.updateSightLine(cell); } } else if (toPlace && state.occupant) { if (toPlace === state.occupant) { @@ -200,7 +203,7 @@ export default class Game { if (!lockedSl) { this.sightLine.clear(); } else { - this.sightLine.update(toPlace.parentElement, this.getCellPosition(toPlace.parentElement)); + this.updateSightLine(toPlace.parentElement); } } else { this.unSelect(); @@ -221,7 +224,7 @@ export default class Game { if (!lockedSl) { this.sightLine.clear(); } else { - this.sightLine.update(cell, this.getCellPosition(cell)); + this.updateSightLine(cell); } } else { const index = this.getGridIndex(state.occupant), @@ -266,19 +269,8 @@ export default class Game { cell.addEventListener('contextmenu', e => { e.preventDefault(); - let sl = this.getSightLine(); - - if (sl) { - sl.classList.toggle('active'); - - if (sl.classList.contains('active')) { - this.sightLine.clear(); - } else { - this.getHex(cell).classList.add('sight-line-target'); - } - - cell.dispatchEvent(new MouseEvent('pointerover')); - } + this.sightLine.toggleLock(cell); + cell.dispatchEvent(new MouseEvent('pointerover')); }); cell.addEventListener('pointerover', e => { @@ -290,7 +282,7 @@ export default class Game { sourceCell = selected.parentElement; if (isOnBoard && (!sl || sl.classList.contains('active')) && sourceCell != cell) { - this.sightLine.draw(sourceCell, cell); + this.drawSightLine(sourceCell, cell); } } @@ -332,4 +324,20 @@ export default class Game { this.placing.push(counter); } + + updateSightLine(cell) { + const { dataset: { x: sX }, parentElement: { dataset: { y: sY }}} = cell, + source = { index: { x: sX, y: sY }, position: this.getCellPosition(cell) }; + + this.sightLine.update(source); + } + + drawSightLine(sourceCell, targetCell) { + const { dataset: { x: sX }, parentElement: { dataset: { y: sY }}} = sourceCell, + { dataset: { x: tX }, parentElement: { dataset: { y: tY }}} = targetCell, + source = { index: { x: sX, y: sY }, position: this.getCellPosition(sourceCell) }, + target = { index: { x: tX, y: tY }, position: this.getCellPosition(targetCell) }; + + this.sightLine.draw(source, target); + } } diff --git a/src/modules/game/counter.js b/src/modules/game/counter.js index 69552d8..cc15509 100644 --- a/src/modules/game/counter.js +++ b/src/modules/game/counter.js @@ -1,8 +1,11 @@ const svgns = "http://www.w3.org/2000/svg"; export default class Counter { - constructor(svg) { + #board; + + constructor(svg, board) { this.svg = svg; + this.#board = board; this.selectedClass = 'selected'; } diff --git a/src/modules/game/sightLine.js b/src/modules/game/sightLine.js index 4790bd8..83cab9b 100644 --- a/src/modules/game/sightLine.js +++ b/src/modules/game/sightLine.js @@ -1,4 +1,6 @@ -const svgns = "http://www.w3.org/2000/svg"; +const svgns = "http://www.w3.org/2000/svg", + targetClassName = 'sight-line-target', + activeClassName = 'active'; function evenr_to_axial(x, y) { return { q: x - (y + (y & 1)) / 2, r: y }; @@ -13,26 +15,26 @@ function axial_distance(q1, r1, q2, r2) { } function offset_distance(x1, y1, x2, y2) { - let { q: q1, r: r1 } = evenr_to_axial(x1, y1), + const { q: q1, r: r1 } = evenr_to_axial(x1, y1), { q: q2, r: r2 } = evenr_to_axial(x2, y2); return axial_distance(q1, r1, q2, r2); } -function cube_to_axial(q, r, s) { - return { q: q, r: r }; +function cube_to_axial(q, r, _) { + return { q, r }; } function axial_to_cube(q, r) { - return { q: q, r: r, s: -q - r }; + return { q, r, s: -q - r }; } function cube_round(q, r, s) { - rQ = Math.round(q); - rR = Math.round(r); - rS = Math.round(s); + let rQ = Math.round(q), + rR = Math.round(r), + rS = Math.round(s); - let q_diff = Math.abs(rQ - q), + const q_diff = Math.abs(rQ - q), r_diff = Math.abs(rR - r), s_diff = Math.abs(rS - s); @@ -48,7 +50,7 @@ function cube_round(q, r, s) { } function axial_round(q, r) { - let cube = axial_to_cube(q, r), + const cube = axial_to_cube(q, r), round = cube_round(cube.q, cube.r, cube.s), axial = cube_to_axial(round.q, round.r, round.s); @@ -64,13 +66,13 @@ function axial_lerp(q1, r1, q2, r2, t) { } function linedraw(x1, y1, x2, y2) { - let axial1 = evenr_to_axial(x1, y1), + const axial1 = evenr_to_axial(x1, y1), axial2 = evenr_to_axial(x2, y2), n = offset_distance(x1, y1, x2, y2), results = []; for (let i = 0; i <= n; i++) { - let lerp = axial_lerp(axial1.q, axial1.r, axial2.q, axial2.r, 1.0 / n * i), + const lerp = axial_lerp(axial1.q, axial1.r, axial2.q, axial2.r, 1.0 / n * i), round = axial_round(lerp.q, lerp.r), { x, y } = axial_to_evenr(round.q, round.r); @@ -81,119 +83,93 @@ function linedraw(x1, y1, x2, y2) { } export default class SightLine { - constructor(svg) { + #board; + #lockTarget; + #activeHexes = []; + sightLine; + + constructor(svg, board) { this.svg = svg; + this.#board = board; } - getBoard() { - return this.svg.querySelector('.board'); - } + #drawHexes(...coords) { + this.#clearHexes() - getActiveHexes() { - return this.svg.querySelectorAll('use[href="#hex"].active'); - } + if (this.distanceCallback) { + this.distanceCallback(offset_distance(...coords)); + } - clear() { - const board = this.getBoard(), - sl = board.querySelector('line.sight-line'), - target = board.querySelector(`use[href="#hex"].sight-line-target`); + const lineCoords = linedraw(...coords), - if (sl) { - sl.remove(); - } + selector = lineCoords + .map(([x, y]) => `g[data-y="${y}"] g[data-x="${x}"] use[href="#hex"]`) + .join(', '), - if (target) { - target.classList.remove('sight-line-target'); - } + hexes = this.svg.querySelectorAll(selector); - this.clearHexes(); + hexes.forEach(p => p.classList.add(activeClassName)); + this.#activeHexes = hexes; } - clearHexes() { + #clearHexes() { if (this.distanceCallback) { this.distanceCallback(); } - this.getActiveHexes().forEach(el => el.classList.remove('active')); + this.#activeHexes.forEach(el => el.classList.remove(activeClassName)); + this.#activeHexes = []; } - draw(source, target) { - this.clear(); - - let pt = new DOMPoint(0, 0), - transform = getComputedStyle(source).transform.match(/-?\d+\.?\d*/g), - mtx = new DOMMatrix(transform); - - pt = pt.matrixTransform(mtx); - - transform = getComputedStyle(source.parentElement).transform.match(/-?\d+\.?\d*/g); - mtx = new DOMMatrix(transform); - pt = pt.matrixTransform(mtx); - - let slX1 = pt.x, - slY1 = pt.y; - - pt = new DOMPoint(0, 0); - transform = getComputedStyle(target).transform.match(/-?\d+\.?\d*/g); - mtx = new DOMMatrix(transform); + clear() { + if (this.sightLine) { + this.sightLine.remove(); + delete this.sightLine; + } - pt = pt.matrixTransform(mtx); + if (this.#lockTarget) { + this.#lockTarget.classList.remove(targetClassName); + this.#lockTarget = undefined; + } - transform = getComputedStyle(target.parentElement).transform.match(/-?\d+\.?\d*/g); - mtx = new DOMMatrix(transform); - pt = pt.matrixTransform(mtx); + this.#clearHexes(); + } - let slX2 = pt.x, - slY2 = pt.y; + draw(source, target) { + this.clear(); - let sightLine = document.createElementNS(svgns, 'line'); + const sightLine = document.createElementNS(svgns, 'line'); sightLine.classList.add('sight-line'); - sightLine.classList.add('active'); - sightLine.setAttributeNS(null, 'x1', slX1); - sightLine.setAttributeNS(null, 'y1', slY1); - sightLine.setAttributeNS(null, 'x2', slX2); - sightLine.setAttributeNS(null, 'y2', slY2); - - this.getBoard().appendChild(sightLine); - - let coords = [ - source.dataset.x, - source.parentElement.dataset.y, - target.dataset.x, - target.parentElement.dataset.y - ].map(n => parseInt(n)); - - this.drawHexes(...coords); + sightLine.classList.add(activeClassName); + sightLine.setAttributeNS(null, 'x1', source.position.x); + sightLine.setAttributeNS(null, 'y1', source.position.y); + sightLine.setAttributeNS(null, 'x2', target.position.x); + sightLine.setAttributeNS(null, 'y2', target.position.y); + + this.sightLine = sightLine; + this.#board.appendChild(sightLine); + this.#drawHexes(+source.index.x, +source.index.y, +target.index.x, +target.index.y); } - update(cell, { x, y }) { - const sl = this.svg.querySelector('.sight-line'), - target = this.svg.querySelector('.sight-line-target').parentElement, - x1 = cell.dataset.x, - y1 = cell.parentElement.dataset.y, - x2 = target.dataset.x, - y2 = target.parentElement.dataset.y; + update(source) { + const { dataset: { x }, parentElement: { dataset: { y }}} = this.#lockTarget; - sl.setAttributeNS(null, 'x1', x); - sl.setAttributeNS(null, 'y1', y); + this.sightLine.setAttributeNS(null, 'x1', source.position.x); + this.sightLine.setAttributeNS(null, 'y1', source.position.y); - this.drawHexes(...[x1, y1, x2, y2].map(n => parseInt(n))); + this.#drawHexes(+source.index.x, +source.index.y, +x, +y); } - drawHexes(...coords) { - this.clearHexes() - - if (this.distanceCallback) { - this.distanceCallback(offset_distance(...coords)); + toggleLock(cell) { + if (this.#lockTarget) { + this.sightLine.classList.add(activeClassName); + this.#lockTarget.classList.remove(targetClassName); + this.#lockTarget = undefined; + } else { + this.sightLine.classList.remove(activeClassName); + cell.classList.add(targetClassName); + this.#lockTarget = cell; } - - let lineCoords = linedraw(...coords); - - let s = lineCoords - .map(([x, y]) => `g[data-y="${y}"] g[data-x="${x}"] use[href="#hex"]`) - .join(', '); - - this.svg.querySelectorAll(s).forEach(p => p.classList.add('active')); } } |