Web Dev Solutions

Catalin Mititiuc

From 9aada19dbd36f45dc50a2dc745dfc613feac675d Mon Sep 17 00:00:00 2001 From: Catalin Mititiuc Date: Sat, 27 Apr 2024 10:24:11 -0700 Subject: Remove calling the gme module with 'new' --- src/modules/game.js | 550 ++++++++++++++++++++++++++-------------------------- 1 file changed, 280 insertions(+), 270 deletions(-) (limited to 'src/modules') diff --git a/src/modules/game.js b/src/modules/game.js index b849124..2633320 100644 --- a/src/modules/game.js +++ b/src/modules/game.js @@ -4,350 +4,360 @@ import Counter from './game/counter.js'; const svgns = "http://www.w3.org/2000/svg"; -export default class Game { - info; - placing = []; - - constructor(svg) { - this.svg = svg; - - const board = this.getBoard(); - - this.firingArc = FiringArc(svg, board); - this.sightLine = SightLine(board); - this.counter = Counter(svg, board); - - this.setUpCells(); - - // debug - const counter = this.counter.getCounter({ dataset: { allegiance: 'davion', number: '1' }}); - this.counter.place(counter, this.getCell(17, 25)); - this.select(counter); - } - - getCells() { - return this.svg.querySelectorAll('g[data-y] > g[data-x]'); - } - - getCell(x, y) { - return this.svg.querySelector(`g[data-y="${y}"] > g[data-x="${x}"]`); - } +function getCellContents(cell) { + return cell.querySelectorAll('*:not(use[href="#hex"])'); +} - getCellOccupant(cell) { - return cell.querySelector('.counter'); - } +function getGridIndex({ parentElement: { dataset: { x }, parentElement: { dataset: { y }}}}) { + return { x: +x, y: +y }; +} - getCellContents(cell) { - return cell.querySelectorAll('*:not(use[href="#hex"])'); - } +function getCounterAtGridIndex(x, y) { + return getCell(x, y).querySelector('.counter'); +} - getHex(cell) { - return cell.querySelector('use[href="#hex"]'); - } +function getHex(cell) { + return cell.querySelector('use[href="#hex"]'); +} - getSelected() { - return this.svg.querySelector(`.counter.selected[data-allegiance][data-number]`); - } +function getCellOccupant(cell) { + return cell.querySelector('.counter'); +} - getSightLine() { - return this.svg.querySelector('line.sight-line'); - } +function getCells(svg) { + return svg.querySelectorAll('g[data-y] > g[data-x]'); +} - getActiveSightLine() { - return this.svg.querySelector('line.sight-line.active'); - } +function getLockedSightLine(svg) { + return svg.querySelector('line.sight-line:not(.active)'); +} - getLockedSightLine() { - return this.svg.querySelector('line.sight-line:not(.active)'); - } +function getSightLine(svg) { + return svg.querySelector('line.sight-line'); +} - getGridIndex({ parentElement: { dataset: { x }, parentElement: { dataset: { y }}}}) { - return { x: +x, y: +y }; - } +function getActiveSightLine(svg) { + return svg.querySelector('line.sight-line.active'); +} - getCounterAtGridIndex(x, y) { - return this.getCell(x, y).querySelector('.counter'); - } +function isGrenade(el) { + return el && el.getAttribute('href') === '#counter-grenade'; +} - getBoard() { - return this.svg.querySelector('.board'); - } +function isClone(counter) { + const isClone = counter.classList.contains('clone'), + { allegiance: clAl, number: clNum } = counter.dataset; - getCellPosition(cell) { - let pt = new DOMPoint(0, 0), - transform = getComputedStyle(cell).transform.match(/-?\d+\.?\d*/g), - mtx = new DOMMatrix(transform); - pt = pt.matrixTransform(mtx); + return { + of: function ({ dataset: { allegiance, number }}) { + return isClone && clAl == allegiance && clNum == number; + } + }; +} - transform = getComputedStyle(cell.parentElement).transform.match(/-?\d+\.?\d*/g); +function getCellPosition(cell) { + let pt = new DOMPoint(0, 0), + transform = getComputedStyle(cell).transform.match(/-?\d+\.?\d*/g), mtx = new DOMMatrix(transform); pt = pt.matrixTransform(mtx); - return pt; - } - - endMove() { - const selected = this.getSelected(); - - if (selected) { - this.counter.endMove(selected); - this.unSelect(); - } - } - - select(selected) { - const counter = this.counter.getCounter(selected); - - if (counter) { - this.unSelect(); - this.placing.push(counter); - counter.classList.add(this.counter.selectedClass); - this.firingArc.get(counter).forEach(el => el.removeAttribute('clip-path')); - this.selectCallback && this.selectCallback({ prone: this.counter.hasProne(counter), ...counter.dataset }); - } - } - - unSelect() { - const selected = this.getSelected(); - - if (selected) { - this.placing = []; - this.getSelected().classList.remove(this.counter.selectedClass); - this.clearSightLine(); - this.firingArc.clipAll(); - } - } + transform = getComputedStyle(cell.parentElement).transform.match(/-?\d+\.?\d*/g); + mtx = new DOMMatrix(transform); + pt = pt.matrixTransform(mtx); - endTurn(allegiance) { - this.firingArc.clear(allegiance); - } - - toggleProne() { - const selected = this.getSelected(), - isOnBoard = selected && selected.parentElement.hasAttribute('data-x'); - - if (selected && isOnBoard) { - this.counter.toggleProne(selected); - } - } + return pt; +} - toggleFiringArcVisibility(allegiance) { - this.firingArc.toggleVisibility(allegiance); - } +export default function (svg) { + let distanceCallback, proneFlagCallback, selectCallback, + placing = []; + + const board = svg.querySelector('.board'), + firingArc = FiringArc(svg, board), + sightLine = SightLine(board), + counterMod = Counter(svg, board); + + getCells(svg).forEach(cell => { + cell.addEventListener('click', e => { + const state = { + placing: placing, + hex: getHex(cell), + occupant: getCellOccupant(cell), + contents: getCellContents(cell) + }; - setUpCells() { - function isGrenade(el) { - return el && el.getAttribute('href') === '#counter-grenade'; - } + let toPlace = placing.pop(); - function isClone(counter) { - const isClone = counter.classList.contains('clone'), - { allegiance: clAl, number: clNum } = counter.dataset; + if (isGrenade(toPlace)) { + state.hex.after(toPlace); + } else if (toPlace && !state.occupant) { + counterMod.place(toPlace, cell); + placing.push(toPlace); + const lockedSl = getLockedSightLine(svg); - return { - of: function ({ dataset: { allegiance, number }}) { - return isClone && clAl == allegiance && clNum == number; + if (!lockedSl) { + clearSightLine(); + } else { + updateSightLine(cell); } - }; - } + } else if (toPlace && state.occupant) { + if (toPlace === state.occupant) { + if ('previous' in toPlace.dataset) { + const trace = counterMod.getTrace(toPlace); + toPlace.remove(); + toPlace = getCounterAtGridIndex(...toPlace.dataset.previous.split(',')); + toPlace.classList.remove('clone'); + toPlace.classList.add(counterMod.selectedClass); + if (!('previous' in toPlace.dataset)) { + trace.remove(); + } else { + const points = trace.getAttribute('points').split(' '); + points.pop(); + trace.setAttributeNS(null, 'points', points.join(' ')); + } + placing.push(toPlace); + const lockedSl = getLockedSightLine(svg); - this.getCells().forEach(cell => { - cell.addEventListener('click', e => { - const state = { - placing: this.placing, - hex: this.getHex(cell), - occupant: this.getCellOccupant(cell), - contents: this.getCellContents(cell) - }; - - let toPlace = this.placing.pop(); - - if (isGrenade(toPlace)) { - state.hex.after(toPlace); - } else if (toPlace && !state.occupant) { - this.counter.place(toPlace, cell); - this.placing.push(toPlace); - const lockedSl = this.getLockedSightLine(); - - if (!lockedSl) { - this.clearSightLine(); + if (!lockedSl) { + clearSightLine(); + } else { + updateSightLine(toPlace.parentElement); + } } else { - this.updateSightLine(cell); + unSelect(); } - } else if (toPlace && state.occupant) { - if (toPlace === state.occupant) { - if ('previous' in toPlace.dataset) { - const trace = this.counter.getTrace(toPlace); + } else if (!state.occupant.classList.contains('clone')) { + select(state.occupant); + } else { + if (isClone(state.occupant).of(toPlace)) { + if (!('previous' in state.occupant.dataset)) { + state.occupant.classList.remove('clone'); + state.occupant.classList.add(counterMod.selectedClass); toPlace.remove(); - toPlace = this.getCounterAtGridIndex(...toPlace.dataset.previous.split(',')); - toPlace.classList.remove('clone'); - toPlace.classList.add(this.counter.selectedClass); - if (!('previous' in toPlace.dataset)) { - trace.remove(); - } else { - const points = trace.getAttribute('points').split(' '); - points.pop(); - trace.setAttributeNS(null, 'points', points.join(' ')); - } - this.placing.push(toPlace); - const lockedSl = this.getLockedSightLine(); + toPlace = state.occupant; + counterMod.removeClones(toPlace); + counterMod.getTrace(toPlace).remove(); + const lockedSl = getLockedSightLine(svg); if (!lockedSl) { - this.clearSightLine(); + clearSightLine(); } else { - this.updateSightLine(toPlace.parentElement); + updateSightLine(cell); } } else { - this.unSelect(); - } - } else if (!state.occupant.classList.contains('clone')) { - this.select(state.occupant); - } else { - if (isClone(state.occupant).of(toPlace)) { - if (!('previous' in state.occupant.dataset)) { - state.occupant.classList.remove('clone'); - state.occupant.classList.add(this.counter.selectedClass); - toPlace.remove(); - toPlace = state.occupant; - this.counter.removeClones(toPlace); - this.counter.getTrace(toPlace).remove(); - const lockedSl = this.getLockedSightLine(); - - if (!lockedSl) { - this.clearSightLine(); - } else { - this.updateSightLine(cell); - } - } else { - const index = this.getGridIndex(state.occupant), - trace = this.counter.getTrace(toPlace), - pos = this.getCellPosition(cell), - points = trace.getAttribute('points').split(' ').filter(p => p != `${pos.x},${pos.y}`).join(' ');; - - let current = toPlace; + const index = getGridIndex(state.occupant), + trace = counterMod.getTrace(toPlace), + pos = getCellPosition(cell), + points = trace.getAttribute('points').split(' ').filter(p => p != `${pos.x},${pos.y}`).join(' ');; - trace.setAttributeNS(null, 'points', points); + let current = toPlace; - while (current.dataset.previous != `${index.x},${index.y}`) { - current = this.getCounterAtGridIndex(...current.dataset.previous.split(',')); - } + trace.setAttributeNS(null, 'points', points); - current.dataset.previous = state.occupant.dataset.previous; - state.occupant.remove(); + while (current.dataset.previous != `${index.x},${index.y}`) { + current = getCounterAtGridIndex(...current.dataset.previous.split(',')); } + + current.dataset.previous = state.occupant.dataset.previous; + state.occupant.remove(); } - this.placing.push(toPlace); } - } else if (!toPlace && state.occupant) { - this.select(state.occupant); - } else { - console.log('removing cell contents'); - state.contents.forEach(el => el.remove()); + placing.push(toPlace); } - }); + } else if (!toPlace && state.occupant) { + select(state.occupant); + } else { + console.log('removing cell contents'); + state.contents.forEach(el => el.remove()); + } + }); - cell.addEventListener('dblclick', e => { - const toPlace = this.placing.pop(), - occupant = this.getCellOccupant(cell); + cell.addEventListener('dblclick', e => { + const toPlace = placing.pop(), + occupant = getCellOccupant(cell); - if (toPlace && occupant && toPlace == occupant) { - const { number, allegiance } = toPlace.dataset, - selector = `[data-allegiance="${allegiance}"][data-number="${number}"]`; + if (toPlace && occupant && toPlace == occupant) { + const { number, allegiance } = toPlace.dataset, + selector = `[data-allegiance="${allegiance}"][data-number="${number}"]`; - this.svg.querySelectorAll(selector).forEach(el => el.remove()); - } - }); + svg.querySelectorAll(selector).forEach(el => el.remove()); + } + }); - cell.addEventListener('contextmenu', e => { - e.preventDefault(); + cell.addEventListener('contextmenu', e => { + e.preventDefault(); - this.sightLine.toggleLock(cell); - cell.dispatchEvent(new MouseEvent('pointerover')); - }); + sightLine.toggleLock(cell); + cell.dispatchEvent(new MouseEvent('pointerover')); + }); - cell.addEventListener('pointerover', e => { - let selected = this.getSelected(); + cell.addEventListener('pointerover', e => { + let selected = getSelected(); - if (selected) { - let sl = this.getSightLine(), - isOnBoard = selected.parentElement.hasAttribute('data-x'), - sourceCell = selected.parentElement; + if (selected) { + let sl = getSightLine(svg), + isOnBoard = selected.parentElement.hasAttribute('data-x'), + sourceCell = selected.parentElement; - if (isOnBoard && (!sl || sl.classList.contains('active')) && sourceCell != cell) { - this.drawSightLine(sourceCell, cell); - } + if (isOnBoard && (!sl || sl.classList.contains('active')) && sourceCell != cell) { + drawSightLine(sourceCell, cell); } + } - let occupant = this.getCellOccupant(cell); + let occupant = getCellOccupant(cell); - if (occupant) { - this.firingArc.toggleCounterVisibility(occupant, true); - } - }); + if (occupant) { + firingArc.toggleCounterVisibility(occupant, true); + } + }); - cell.addEventListener('pointerout', e => { - let sl = this.getActiveSightLine(); + cell.addEventListener('pointerout', e => { + let sl = getActiveSightLine(svg); - if (sl) { - this.clearSightLine(); - } + if (sl) { + clearSightLine(); + } - let occupant = this.getCellOccupant(cell); + let occupant = getCellOccupant(cell); - if (occupant) { - this.firingArc.toggleCounterVisibility(occupant, false); - } - }); + if (occupant) { + firingArc.toggleCounterVisibility(occupant, false); + } }); - } + }); - setFiringArc(size) { - const counter = this.getSelected(), - isOnBoard = counter => counter && counter.parentElement.hasAttribute('data-x'); + // debug + const c = counterMod.getCounter({ dataset: { allegiance: 'davion', number: '1' }}); + counterMod.place(c, getCell(17, 25)); + select(c); - if (isOnBoard(counter)) { - this.firingArc.set(size, counter, this.getCellPosition(counter.parentElement)); - } + function getCell(x, y) { + return svg.querySelector(`g[data-y="${y}"] > g[data-x="${x}"]`); } - setGrenade() { - let counter = document.createElementNS(svgns, 'use'); - counter.setAttributeNS(null, 'href', '#counter-grenade'); + function getSelected() { + return svg.querySelector(`.counter.selected[data-allegiance][data-number]`); + } - this.placing.push(counter); + function clearSightLine() { + sightLine.hexes = []; + sightLine.clear(); + distanceCallback && distanceCallback(); } - updateSightLine(cell) { + function updateSightLine(cell) { const { dataset: { x: sX }, parentElement: { dataset: { y: sY }}} = cell, - { dataset: { x: tX }, parentElement: { dataset: { y: tY }}} = this.sightLine.lockTarget; + { dataset: { x: tX }, parentElement: { dataset: { y: tY }}} = sightLine.lockTarget; - const selector = this.sightLine.calcIndexes(+sX, +sY, +tX, +tY) + const selector = sightLine.calcIndexes(+sX, +sY, +tX, +tY) .map(([x, y]) => `g[data-y="${y}"] g[data-x="${x}"] use[href="#hex"]`) .join(', '); - const hexes = this.svg.querySelectorAll(selector); - this.sightLine.hexes = hexes; - this.sightLine.update(this.getCellPosition(cell)); - this.distanceCallback && this.distanceCallback(hexes.length - 1); + const hexes = svg.querySelectorAll(selector); + sightLine.hexes = hexes; + sightLine.update(getCellPosition(cell)); + distanceCallback && distanceCallback(hexes.length - 1); } - drawSightLine(sourceCell, targetCell) { + function drawSightLine(sourceCell, targetCell) { const { dataset: { x: sX }, parentElement: { dataset: { y: sY }}} = sourceCell, { dataset: { x: tX }, parentElement: { dataset: { y: tY }}} = targetCell; - const selector = this.sightLine.calcIndexes(+sX, +sY, +tX, +tY) + const selector = sightLine.calcIndexes(+sX, +sY, +tX, +tY) .map(([x, y]) => `g[data-y="${y}"] g[data-x="${x}"] use[href="#hex"]`) .join(', '); - const hexes = this.svg.querySelectorAll(selector); - this.sightLine.hexes = hexes; - this.sightLine.drawLine(this.getCellPosition(sourceCell), this.getCellPosition(targetCell)); - this.distanceCallback && this.distanceCallback(hexes.length - 1); + const hexes = svg.querySelectorAll(selector); + sightLine.hexes = hexes; + sightLine.drawLine(getCellPosition(sourceCell), getCellPosition(targetCell)); + distanceCallback && distanceCallback(hexes.length - 1); } - clearSightLine() { - this.sightLine.hexes = []; - this.sightLine.clear(); - this.distanceCallback && this.distanceCallback(); + function select(selected) { + const counter = counterMod.getCounter(selected); + + if (counter) { + unSelect(); + placing.push(counter); + counter.classList.add(counterMod.selectedClass); + firingArc.get(counter).forEach(el => el.removeAttribute('clip-path')); + selectCallback && selectCallback({ prone: counterMod.hasProne(counter), ...counter.dataset }); + } } + + function unSelect() { + const selected = getSelected(); + + if (selected) { + placing = []; + getSelected().classList.remove(counterMod.selectedClass); + clearSightLine(); + firingArc.clipAll(); + } + } + + function endMove() { + const selected = getSelected(); + + if (selected) { + counterMod.endMove(selected); + unSelect(); + } + } + + function endTurn(allegiance) { + firingArc.clear(allegiance); + } + + function toggleProne() { + const selected = getSelected(), + isOnBoard = selected && selected.parentElement.hasAttribute('data-x'); + + if (selected && isOnBoard) { + counterMod.toggleProne(selected); + } + } + + function toggleFiringArcVisibility(allegiance) { + firingArc.toggleVisibility(allegiance); + } + + function setFiringArc(size) { + const counter = getSelected(), + isOnBoard = counter => counter && counter.parentElement.hasAttribute('data-x'); + + if (isOnBoard(counter)) { + firingArc.set(size, counter, getCellPosition(counter.parentElement)); + } + } + + function setGrenade() { + let counter = document.createElementNS(svgns, 'use'); + counter.setAttributeNS(null, 'href', '#counter-grenade'); + + placing.push(counter); + } + + return { + set distanceCallback(callback) { + distanceCallback = callback; + }, + + set proneFlagCallback(callback) { + proneFlagCallback = callback; + }, + + set selectCallback(callback) { + selectCallback = callback; + }, + + select, + unSelect, + endMove, + endTurn, + setFiringArc, + setGrenade, + toggleFiringArcVisibility, + toggleProne + }; } -- cgit v1.2.3