Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Mititiuc <webdevcat@proton.me>2024-04-23 19:01:29 -0700
committerCatalin Mititiuc <webdevcat@proton.me>2024-04-23 19:01:29 -0700
commitf60969ef8dc72d3b97c5abb9f637171d2a6f2921 (patch)
treeab71b28f67116d473ef799bcc6db24facbae258e
parent1a75bf469aa72f9845fe86ac2ebb34424c262f33 (diff)
WIP: handle clicking on counters at the cell level
-rw-r--r--src/modules/counter.js44
-rw-r--r--src/modules/game.js128
2 files changed, 117 insertions, 55 deletions
diff --git a/src/modules/counter.js b/src/modules/counter.js
index de393a0..162e56e 100644
--- a/src/modules/counter.js
+++ b/src/modules/counter.js
@@ -6,8 +6,6 @@ export default class Counter {
constructor(svg, container) {
this.svg = svg;
this.container = container;
-
- this.getCounters().forEach(c => this.addEventListeners(c));
}
dataSelector(troopNumber, allegiance) {
@@ -60,13 +58,6 @@ export default class Counter {
return pt;
}
- addEventListeners(counter) {
- counter.addEventListener('pointerover', this.pointerOver.bind(this));
- counter.addEventListener('pointerout', this.pointerOut.bind(this));
- counter.addEventListener('click', this.click.bind(this));
- // counter.addEventListener('dblclick', dblClick);
- }
-
pointerOver(e) {
const { number: troopNumber, allegiance: troopAllegiance } = e.target.dataset,
cp = this.svg.querySelector(`#clip-path-${troopAllegiance}-${troopNumber}`);
@@ -245,32 +236,33 @@ export default class Counter {
troopAllegiance = selected.dataset.allegiance,
troopNumber = selected.dataset.number;
- let counter, points,
+ let points,
counterNodeList = this.getCounterAndClones(troopAllegiance, troopNumber);
if (counterNodeList.length > 0 && selected.parentElement.hasAttribute('data-x')) {
- let counters = Array.from(counterNodeList),
- original = counters.find(el => !el.classList.contains('clone')),
- trace = this.svg.querySelector(this.traceSelector(troopNumber, troopAllegiance));
+ let trace = this.svg.querySelector(this.traceSelector(troopNumber, troopAllegiance));
+
+ let prevCoords = [
+ selected.parentElement.dataset.x,
+ selected.parentElement.parentElement.dataset.y
+ ]
- counter = original.cloneNode();
- counter.setAttributeNS(null, 'x', 0);
- counter.setAttributeNS(null, 'y', 0);
- counter.classList.remove(selectedClass);
- counter.classList.add('clone');
+ let clone = selected.cloneNode();
+ clone.classList.remove(selectedClass);
+ clone.classList.add('clone');
- original.setAttributeNS(null, 'x', 0);
- original.setAttributeNS(null, 'y', 0);
+ selected.dataset.previous = prevCoords;
+ selected.parentElement.appendChild(clone);
+ point.parentElement.appendChild(selected);
- original.parentElement.appendChild(counter);
- point.parentElement.appendChild(original);
+ console.log(this.getCounterAndClones(troopAllegiance, troopNumber));
- if (counter.parentElement.querySelector('[href="#counter-prone"]')) {
+ if (clone.parentElement.querySelector('[href="#counter-prone"]')) {
this.toggleProne();
}
- let previous = this.getCellPosition(counter.parentElement),
- current = this.getCellPosition(original.parentElement);
+ let previous = this.getCellPosition(clone.parentElement),
+ current = this.getCellPosition(selected.parentElement);
if (!trace) {
trace = document.createElementNS(svgns, 'polyline');
@@ -287,7 +279,7 @@ export default class Counter {
}
trace.setAttributeNS(null, 'points', points);
- counter.addEventListener('click', this.clickClone.bind(this));
+ // clone.addEventListener('click', this.clickClone.bind(this));
} else {
selected.removeAttribute('data-x');
point.parentElement.appendChild(selected);
diff --git a/src/modules/game.js b/src/modules/game.js
index b3f1797..ca911ed 100644
--- a/src/modules/game.js
+++ b/src/modules/game.js
@@ -4,14 +4,6 @@ import Counter from './counter.js';
const svgns = "http://www.w3.org/2000/svg";
-function isEven(n) {
- return n % 2 === 0;
-}
-
-function radToDeg(radians) {
- return radians * 180 / Math.PI;
-}
-
export default class Game {
info;
placing = [];
@@ -27,7 +19,6 @@ export default class Game {
this.sightLine = new SightLine(svg);
this.counter = new Counter(svg, this);
- // this.setUpCounter(this);
this.setUpCells();
}
@@ -59,8 +50,12 @@ export default class Game {
return this.svg.querySelectorAll('#firing-arcs polygon:not([clip-path])');
}
- getGridIndex({ parentElement }) {
- return { x: parentElement.dataset.x, y: parentElement.parentElement.dataset.y };
+ getGridIndex({ parentElement: { dataset: { x }, parentElement: { dataset: { y }}}}) {
+ return { x, y };
+ }
+
+ getCounterAtGridIndex(x, y) {
+ return this.getCell(x, y).querySelector('use[href*="#t-"');
}
getBoard() {
@@ -141,33 +136,109 @@ export default class Game {
let group = cell,
point = this.getHex(cell);
- point.addEventListener('click', e => {
- const toPlace = this.placing.pop();
+ function isGrenade(el) {
+ return el && el.getAttribute('href') === '#counter-grenade';
+ }
- // TODO
- let existingOccupant =
- this.svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`);
+ function isClone(counter) {
+ const isClone = counter.classList.contains('clone'),
+ { allegiance: clAl, number: clNum } = counter.dataset;
- if (toPlace && toPlace.getAttribute('href') === '#counter-grenade') {
- point.parentElement.appendChild(toPlace);
- return;
- }
+ return {
+ of: function ({ dataset: { allegiance, number }}) {
+ return isClone && clAl == allegiance && clNum == number;
+ }
+ };
+ }
- if (this.getSelected() && !existingOccupant) {
- let sl = this.svg.querySelector('.sight-line');
- this.placing.push(toPlace);
- this.counter.place(point);
+ cell.addEventListener('click', e => {
+ const state = {
+ placing: this.placing,
+ hex: cell.querySelector('use[href="#hex"]'),
+ occupant: cell.querySelector('use[href*="#t-"'),
+ contents: cell.querySelectorAll('*:not(use[href="#hex"])')
+ };
- if (sl) {
- if (sl.classList.contains('active')) {
- this.sightLine.clear();
+ let toPlace = this.placing.pop();
+
+ if (isGrenade(toPlace)) {
+ state.hex.after(toPlace);
+ } else if (toPlace && !state.occupant) {
+ this.counter.place(point);
+ this.placing.push(toPlace);
+ } else if (toPlace && state.occupant) {
+ if (toPlace === state.occupant) {
+ if ('previous' in toPlace.dataset) {
+ toPlace.remove();
+ toPlace = this.getCounterAtGridIndex(...toPlace.dataset.previous.split(','));
+ toPlace.classList.remove('clone');
+ toPlace.classList.add('selected');
+ console.log(toPlace);
+ this.placing.push(toPlace);
} else {
- this.sightLine.update(point, this.getCellPosition(point.parentElement));
+ this.counter.unSelect();
+ }
+ } else if (!state.occupant.classList.contains('clone')) {
+ this.counter.select(state.occupant);
+ this.placing.push(state.occupant);
+ } else {
+ if (isClone(state.occupant).of(toPlace)) {
+ if (!('previous' in state.occupant.dataset)) {
+ state.occupant.classList.remove('clone');
+ state.occupant.classList.add('selected');
+ toPlace.remove();
+ toPlace = state.occupant;
+ this.counter.removeClones(toPlace);
+ } else {
+ const index = this.getGridIndex(state.occupant);
+ let current = toPlace;
+
+ while (current.dataset.previous != `${index.x},${index.y}`) {
+ current = this.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.counter.select(state.occupant);
+ this.placing.push(state.occupant);
+ } else {
+ console.log('removing cell contents');
+ state.contents.forEach(el => el.remove());
}
});
+ // point.addEventListener('click', e => {
+ // const toPlace = this.placing.pop();
+
+ // // TODO
+ // let existingOccupant =
+ // this.svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`);
+
+ // if (toPlace && toPlace.getAttribute('href') === '#counter-grenade') {
+ // point.after(toPlace);
+ // return;
+ // }
+
+ // if (this.getSelected() && !existingOccupant) {
+ // let sl = this.svg.querySelector('.sight-line');
+ // this.placing.push(toPlace);
+ // this.counter.place(point);
+
+ // if (sl) {
+ // if (sl.classList.contains('active')) {
+ // this.sightLine.clear();
+ // } else {
+ // this.sightLine.update(point, this.getCellPosition(point.parentElement));
+ // }
+ // }
+ // }
+ // });
+
// Logic for this event:
// If there's a locked sightline, unlock it. Otherwise, if there's an
// active sightline, lock it.
@@ -233,7 +304,6 @@ export default class Game {
setGrenade() {
let counter = document.createElementNS(svgns, 'use');
counter.setAttributeNS(null, 'href', '#counter-grenade');
- counter.addEventListener('click', () => counter.remove());
this.placing.push(counter);
}