From 6f292102e4595dc29b14c04c152ff3468aa33fed Mon Sep 17 00:00:00 2001 From: Catalin Constantin Mititiuc Date: Mon, 16 Jun 2025 22:41:33 -0700 Subject: [PATCH] WIP: counters --- public/assets/css/map.css | 116 +++++++++-- public/assets/css/style.css | 15 ++ public/assets/images/counter_1st_floor.png | Bin 0 -> 8593 bytes public/assets/images/counter_2nd_floor.png | Bin 0 -> 7961 bytes public/assets/images/counter_3rd_floor.png | Bin 0 -> 8250 bytes public/assets/images/counter_basement.png | Bin 0 -> 7876 bytes public/assets/images/counter_grenade.png | Bin 0 -> 14868 bytes public/assets/images/counter_prone.png | Bin 0 -> 6761 bytes public/assets/images/scenario_template.svg | 16 +- public/index.html | 19 +- src/index.js | 5 +- src/modules/game/soldier.js | 12 ++ src/modules/gameboard.js | 231 ++++++++------------- 13 files changed, 233 insertions(+), 181 deletions(-) create mode 100644 public/assets/images/counter_1st_floor.png create mode 100644 public/assets/images/counter_2nd_floor.png create mode 100644 public/assets/images/counter_3rd_floor.png create mode 100644 public/assets/images/counter_basement.png create mode 100644 public/assets/images/counter_grenade.png create mode 100644 public/assets/images/counter_prone.png diff --git a/public/assets/css/map.css b/public/assets/css/map.css index cd7ea6a..e6a25aa 100644 --- a/public/assets/css/map.css +++ b/public/assets/css/map.css @@ -82,10 +82,6 @@ g.troop-counter-template text { transform: translate(-5px, 6px); } -[href="#counter-grenade"] { - transform: translate(-5px, -5px); -} - g.clone { stroke: white; stroke-width: 0.5px; @@ -173,10 +169,35 @@ polygon.firing-arc[data-allegiance="attacker"] { stroke-opacity: inherit; } -g.counter use { +/*g.counter use {*/ +/* r: 5px;*/ +/*}*/ + +g.counter { r: 5px; } +[data-q][data-r][data-s][data-t]:hover g.counter { + /*transform: scale(3);*/ +} + +g.counter:hover { + /*transform: scale(3);*/ + /*r: 20px;*/ +} + +/*g.counter:hover * {*/ +/* r: 20px;*/ +/*}*/ + +g.counter.selected { + r: 6px; +} + +g.counter use.primary-weapon { + r: inherit; +} + g.counter use.troop-number, g.counter use.squad-number { --scale: 0.25; } @@ -197,7 +218,8 @@ g.selected use.primary-weapon { animation: 1s selected 0.25s linear infinite; stroke-width: 2px; stroke: yellow; - r: 6px; + /*r: 6px;*/ + r: inherit; } pattern use { @@ -247,23 +269,42 @@ g[data-y]:nth-child(odd) { fill: orange; stroke: black; } +/**/ +/*[data-q][data-r][data-s][data-t] g.counter,*/ +/*[data-q][data-r][data-s][data-t] g.counter .troop-number,*/ +/*[data-q][data-r][data-s][data-t] g.counter .squad-number {*/ +/* transition: transform 0.25s;*/ +/*}*/ -[data-x]:hover g.counter, -[data-q][data-r][data-s][data-t]:hover g.counter { - transform: scale(1.5); -} +/*[data-q][data-r][data-s][data-t]:hover g.counter {*/ +/* transform: scale(2);*/ +/*}*/ -[data-x]:hover g.counter .troop-number, -[data-q][data-r][data-s][data-t]:hover g.counter .troop-number { - --translateX: -5px; - --scale: 0.5; -} +/*[data-q][data-r][data-s][data-t]:hover use[href="#hex"] {*/ +/* scale: 0.5;*/ +/*}*/ -[data-x]:hover g.counter .squad-number, -[data-q][data-r][data-s][data-t]:hover g.counter .squad-number { - --translateX: 5px; - --scale: 0.5; -} + + +/*[data-x]:hover g.counter,*/ +/*[data-q][data-r][data-s][data-t]:hover g.counter {*/ +/* transform: scale(1.5);*/ +/* transition: transform 0.25s;*/ +/*}*/ +/**/ +/*[data-x]:hover g.counter .troop-number,*/ +/*[data-q][data-r][data-s][data-t]:hover g.counter .troop-number {*/ +/* --translateX: -5px;*/ +/* --scale: 0.5;*/ +/* transition: transform 0.25s;*/ +/*}*/ +/**/ +/*[data-x]:hover g.counter .squad-number,*/ +/*[data-q][data-r][data-s][data-t]:hover g.counter .squad-number {*/ +/* --translateX: 5px;*/ +/* --scale: 0.5;*/ +/* transition: transform 0.25s;*/ +/*}*/ [data-x] { --scale: 1; @@ -462,10 +503,43 @@ text.elevation { [data-q][data-r][data-s][data-t] .radial-icon { cx: calc(var(--cx) / 20); - cy: calc(var(--cy) / 20) + cy: calc(var(--cy) / 20); } [data-q][data-r][data-s][data-t]:hover .radial-icon { cx: var(--cx); cy: var(--cy); } + +use[class^="counter-"] { + --scale: 1; + --translateX: -5px; + --translateY: -5px; + transform: scale(var(--scale)) translate(var(--translateX), var(--translateY)); + /*transform: translate(var(--translateX), var(--translateY)) scale(var(--scale));*/ +} + +use[class^="counter-"] { + transition: x 0.25s, y 0.25s; + --scale: 0.5; + /*--translateY: 0px;*/ +} + +.counter use[href^="#counter"] { + /*transform: scale(0.5);*/ +} + +g.counter use[class^="counter-"] { + x: calc(var(--x) * 1.25); + y: calc(var(--y) * 1.25); + /*y: 10px;*/ + /*x: var(--x);*/ + /*y: var(--y);*/ +} + +[data-q][data-r][data-s][data-t]:hover use[class^="counter-"], + x: calc(var(--x) * 1.5); + y: calc(var(--y) * 1.5); + /*--scale: 1;*/ + --translateY: -5px; +} diff --git a/public/assets/css/style.css b/public/assets/css/style.css index e1257a4..af9dd2a 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -576,6 +576,21 @@ div#status { pointer-events: none; } +.counters-list { + user-select: none; +} + +.counters-list > img { + vertical-align: middle; + height: 20px; + border: 1px solid lightgray; + border-radius: 2px; +} + +.counters-list > img:hover { + border: 1px solid gray; +} + @keyframes roll-out { 0% { transform: scaleX(1); diff --git a/public/assets/images/counter_1st_floor.png b/public/assets/images/counter_1st_floor.png new file mode 100644 index 0000000000000000000000000000000000000000..0728ac038976b4f71a829ceee0f1de742f8405ca GIT binary patch literal 8593 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 VnAH$o3cjX5aK@HKr3S~N{|h{rBCY@c literal 0 HcmV?d00001 diff --git a/public/assets/images/counter_2nd_floor.png b/public/assets/images/counter_2nd_floor.png new file mode 100644 index 0000000000000000000000000000000000000000..8417461b72da8bde960d971cf7f8273b5e97fdc2 GIT binary patch literal 7961 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 - - - - - - - @@ -33,8 +26,12 @@ - - + + + + + + @@ -48,5 +45,6 @@ + diff --git a/public/index.html b/public/index.html index f4b28a9..dcaad12 100644 --- a/public/index.html +++ b/public/index.html @@ -231,11 +231,24 @@ - + +
    + + + + + + + - - + + + + + +
    diff --git a/src/index.js b/src/index.js index 46f39fd..d2c1b01 100644 --- a/src/index.js +++ b/src/index.js @@ -158,7 +158,10 @@ document.querySelectorAll('.set-firing-arc').forEach(el => el.addEventListener('click', gameboard.setFiringArc) ); -document.querySelector('.set-grenade').addEventListener('click', gameboard.setGrenade); +document.querySelectorAll('.counters-list button').forEach(el => { + el.addEventListener('click', e => gameboard.setCounter(el.className)); +}); + document.querySelector('.set-mech-template').addEventListener('click', gameboard.setMechTemplate); document.querySelectorAll('#toggle-firing-arc-vis input').forEach(el => diff --git a/src/modules/game/soldier.js b/src/modules/game/soldier.js index 3ac7b37..a024f9f 100644 --- a/src/modules/game/soldier.js +++ b/src/modules/game/soldier.js @@ -108,6 +108,18 @@ export function getTrace(svg, counter) { } export function place(svg, selected, cell) { + //console.log(selected.parentElement); + //const piecesContainer = svg.querySelector('.pieces'); + //const parent = selected.parentElement; + //if (parent) + // parent.setAttributeNS(null, 'transform', cell.getAttributeNS(null, 'transform')); + //else { + // const container = document.createElementNS(svgns, 'g'); + // container.setAttributeNS(null, 'transform', cell.getAttributeNS(null, 'transform')); + // container.append(selected); + // piecesContainer.append(container); + //} + if (svg.querySelector('.grid').contains(selected)) { const clone = addMoveToHistory(selected); updatePlacement(cell, selected, clone) diff --git a/src/modules/gameboard.js b/src/modules/gameboard.js index ae03364..0c33f05 100644 --- a/src/modules/gameboard.js +++ b/src/modules/gameboard.js @@ -196,12 +196,25 @@ function endMove() { } } +function returnPieces(collection) { + [...svg.querySelector('.pieces').children].forEach(piece => { + collection.get(piece).parent.append(piece); + collection.delete(piece); + }); +} + export function start(el) { svg = el; const startingLocations = svg.querySelector('.start-locations'); startingLocations && getUnits(startingLocations).forEach(unit => unit.addEventListener('click', selectOffBoard)); + + const pieces = svg.querySelector('.pieces'); + const inFront = new Map(); + let inFrontParent; + //addEventListener('pointerout', e => { returnPieces(inFront) }); + getCells(svg).forEach(cell => { cell.addEventListener('click', e => { const occupant = getCellOccupant(cell); @@ -269,6 +282,12 @@ export function start(el) { }); cell.addEventListener('pointerover', () => { + if (!pieces.contains(cell)) { + returnPieces(inFront); + inFront.set(cell, { parent: cell.parentElement }); + pieces.append(cell); + } + const selected = getSelected(); if (placing[0]?.getAttributeNS(null, 'class') == 'mech-template') { @@ -288,6 +307,22 @@ export function start(el) { }); cell.addEventListener('pointerout', () => { + //if (inFront && inFrontParent) { + // inFrontParent.append(inFront); + // inFront = null; + // inFrontParent = null; + //} + + //for (const [el, parent] of inFront) { + // parent.append(el); + // inFront.delete(el); + //} + //[...pieces.children].forEach(piece => { + // inFront.get(piece).parent.append(piece); + // inFront.delete(piece); + //}); + //returnPieces(inFront); + getActiveSightLine(svg) && clearSightLine(); const occupant = getCellOccupant(cell); @@ -299,156 +334,27 @@ export function start(el) { }); // debug // - // const attacker = { dataset: { allegiance: 'attacker', number: 1, squad: 1 }}; + const attacker = { dataset: { allegiance: 'attacker', number: 1, squad: 1 }}; // const defender = { dataset: { allegiance: 'defender', number: 1, squad: 2 }}; - // soldier.place(svg, soldier.createCounter(attacker, 'blazer'), getCell(0, 0, 0, 0)); - // soldier.place(svg, soldier.createCounter(defender, 'rifle'), getCell(-1, 0, 1, 0)); - - const svgns = "http://www.w3.org/2000/svg"; - const img = document.createElementNS(svgns, 'image'); - img.setAttribute('href', '/assets/images/mech_template.png'); - img.setAttribute('width', '77'); - img.setAttribute('height', '77'); - img.setAttribute('transform', 'translate(-38.75, -38.5)'); - img.style.opacity = 0.2; - img.style.pointerEvents = 'none'; - - const mech = document.createElementNS(svgns, 'g'); - mech.setAttribute('transform', 'rotate(0) translate(-2.25, 0)'); - mech.style.pointerEvents = 'none'; - - const deadZone = document.createElementNS(svgns, 'circle'); - deadZone.style.stroke = 'red'; - deadZone.style.strokeOpacity = 0.5; - deadZone.style.pointerEvents = 'none'; - deadZone.setAttribute('r', '36.5'); - - const leftFoot = document.createElementNS(svgns, 'rect'); - leftFoot.style.fill = 'red'; - leftFoot.style.fillOpacity = 0.5; - leftFoot.setAttribute('x', '-16.25'); - leftFoot.setAttribute('y', '5.75'); - leftFoot.setAttribute('width', '34.5'); - leftFoot.setAttribute('height', '12.25'); - - const rightFoot = document.createElementNS(svgns, 'rect'); - rightFoot.style.fill = 'red'; - rightFoot.style.fillOpacity = 0.5; - rightFoot.setAttribute('x', '-16.25'); - rightFoot.setAttribute('y', '5.75'); - rightFoot.setAttribute('width', '34.5'); - rightFoot.setAttribute('height', '12.25'); - rightFoot.setAttribute('transform', 'scale(1 -1)'); - - const forwardArc = document.createElementNS(svgns, 'path'); - forwardArc.setAttribute('d', 'M -4,0 L -32.55,-16.5 A 36.5 36.5 0 0 0 -32.55,16.5 Z'); - - const rearArc = document.createElementNS(svgns, 'path'); - rearArc.setAttribute('d', 'M 4,0 L 32.55,-16.5 A 36.5 36.5 0 0 1 32.55,16.5 Z'); - - const forwardRightArc = document.createElementNS(svgns, 'path'); - forwardRightArc.setAttribute('d', 'M 0,2.3 L -32.55,-16.5 A 36.5 36.5 0 0 1 0,-36.5 Z'); - - const forwardLeftArc = document.createElementNS(svgns, 'path'); - forwardLeftArc.setAttribute('d', 'M 0,-2.3 L -32.55,16.5 A 36.5 36.5 0 0 0 0,36.5 Z'); - - const rightArc = document.createElementNS(svgns, 'path'); - rightArc.setAttribute('d', 'M 0,2.3 L 32.55,-16.5 A 36.5 36.5 0 0 0 0,-36.5 Z'); - - const leftArc = document.createElementNS(svgns, 'path'); - leftArc.setAttribute('d', 'M 0,-2.3 L 32.55,16.5 A 36.5 36.5 0 0 1 0,36.5 Z'); - - const arcs = document.createElementNS(svgns, 'g'); - arcs.setAttribute('mask', 'url(#mech-template-mask)'); - arcs.style.stroke = 'white'; - arcs.style.strokeOpacity = 0.5; - - const mask = document.createElementNS(svgns, 'mask'); - mask.id = 'mech-template-mask'; - - const visible = document.createElementNS(svgns, 'circle'); - visible.setAttribute('fill', 'white'); - visible.setAttribute('r', '36.5'); - - const invisible = document.createElementNS(svgns, 'rect'); - invisible.setAttribute('x', '-16.25'); - invisible.setAttribute('y', '-18'); - invisible.setAttribute('width', '34.5'); - invisible.setAttribute('height', '36'); - invisible.setAttribute('fill', 'black'); - - const arrow = document.createElementNS(svgns, 'polyline'); - arrow.setAttribute('points', '-23,-3 -25,0 -23,3'); - arrow.style.stroke = 'black'; - - mask.append(visible); - mask.append(invisible); - - mech.append(img); - mech.append(deadZone); - mech.append(leftFoot); - mech.append(rightFoot); - mech.append(arrow); - arcs.append(forwardArc); - arcs.append(rearArc); - arcs.append(forwardRightArc); - arcs.append(forwardLeftArc); - arcs.append(rightArc); - arcs.append(leftArc); - mech.append(arcs); - const cell = getCell(2, 0, -2, 0); - - //cell.append(mask); - //cell.append(mech); - - const icons = Array(4).fill(null); - const length = 10; - - const gravity = 1; - const lateralForce = gravity; - const rads = Math.atan(lateralForce / gravity); - const mult = icons.length % 2 ? index => Math.ceil(index / 2) : index => Math.floor(index / 2) + 0.5; - const iconBestFitCount = 8; - const divider = icons.length > iconBestFitCount ? iconBestFitCount / icons.length : 1; - - function getRandomIntInclusive(min, max) { - const minCeiled = Math.ceil(min); - const maxFloored = Math.floor(max); - return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled); // The maximum is inclusive and the minimum is inclusive - } - - icons.forEach((color, index) => { - const theta = rads * (index % 2 ? -1 : 1) * mult(index) * divider; - const cx = length * Math.sin(theta); - const cy = length * Math.cos(theta); - - const randomColor = `rgb(${getRandomIntInclusive(0, 200)}, ${getRandomIntInclusive(0, 200)}, ${getRandomIntInclusive(0, 200)})`; - const pt = document.createElementNS(svgns, 'circle'); - pt.classList.add('radial-icon'); - pt.setAttributeNS(null, 'r', 3); - pt.setAttributeNS(null, 'fill', randomColor); - //pt.setAttributeNS(null, 'fill-opacity', 0.5); - pt.setAttributeNS(null, 'style', `--cx: ${cx}px; --cy: ${cy}px`); - //pt.style.cx = `--cx: ${cx}px`; - //pt.style.cy = `--cy: ${cy}px`; - //pt.setAttributeNS(null, 'cx', cx); - //pt.setAttributeNS(null, 'cy', cy); - - cell.append(pt); - }); - - //const mechTemplate = document.createElementNS(svgns, 'use'); - //mechTemplate.setAttributeNS(null, 'href', '#fallen-mech-template'); - //mechTemplate.setAttribute('href', '#standing-mech-template'); - //mechTemplate.setAttributeNS(null, 'href', '#vehicle-template'); - //cell.append(mechTemplate); - console.log(cell); + const trooper = soldier.createCounter(attacker, 'blazer'); + soldier.place(svg, trooper, cell); /////////// Observable.subscribe('select', select); Observable.subscribe('endmove', endMove); + + Observable.notify('select', trooper); + + //Array(1).fill(null).forEach(() => { + // const counter = document.createElementNS(svgns, 'use'); + // counter.setAttributeNS(null, 'href', '#counter-grenade'); + // counter.classList.add('counter-grenade'); + // trooper.appendChild(counter); + //}); + // + //setGrenade(); console.log('gameboard.js loaded'); } @@ -483,11 +389,42 @@ export function setFiringArc() { } } -export function setGrenade() { - let counter = document.createElementNS(svgns, 'use'); - counter.setAttributeNS(null, 'href', '#counter-grenade'); +export function setCounter(name) { + const selected = getSelected(); - placing.push(counter); + const counter = document.createElementNS(svgns, 'use'); + counter.addEventListener('click', e => { + e.stopPropagation() + counter.remove() + }); + //counter.setAttributeNS(null, 'href', '#counter-grenade'); + counter.setAttributeNS(null, 'href', `#counter-${name}`); + counter.classList.add(`counter-${name}`); + + if (selected) { + const icons = [...selected.querySelectorAll('use[class^="counter-"]'), counter]; + const length = 12; + const gravity = 1; + const lateralForce = gravity; + const rads = Math.atan(lateralForce / gravity); + const mult = icons.length % 2 ? index => Math.ceil(index / 2) : index => Math.floor(index / 2) + 0.5; + const iconBestFitCount = 8; + const divider = icons.length > iconBestFitCount ? iconBestFitCount / icons.length : 1; + + icons + .map((icon, index) => [icon, (index % 2 ? -1 : 1) * mult(index)]) + .sort(([_ic1, i1], [_ic2, i2]) => i1 < i2) + .forEach(([icon, index]) => { + const theta = rads * index * divider; + const x = length * Math.sin(theta); + const y = length * Math.cos(theta); + icon.setAttributeNS(null, 'style', `--x: ${x}px; --y: ${y}px`); + //selected.appendChild(icon); + if (!selected.contains(icon)) selected.append(icon); + }); + } + else + placing.push(counter); } function handleMechTemplateRotation(event) {