Title of State:
Resource Interaction
Goal of Change:
Goal: you can click a resource, it becomes selected + highlighted, and you get a readout (Type + world coords + distance + count index) in the HUD.
What we add:
- HUD includes
SEL:line when selected S.selectedResourceIndexfindResourceAtWorld(wx, wy)(hit-test)- Update
onClick(x,y)to convert screen → world usingcamX/camYand select a node - Draw highlight ring + crosshair label for selected node
PATCH 1 — State: add selected index
Code to Remove
381 -
resourceSettings: null,
resources: [], // [{Type, X, Y, Radius}...]
Code to Add
381 -
resourceSettings: null,
resources: [], // [{Type, X, Y, Radius}...]
selectedResourceIndex: -1, // index into S.resources
PATCH 2 — Replace onClick() with selection logic (screen → world)
Code to Remove
459 -
function onClick(x,y){
// placeholder: prove it works
// replace with selection / commands later
}
Code to Add
459 -
function onClick(x,y){
if(S.view !== "GAME") return;
// screen -> world
const wx = x + S.camX;
const wy = y + S.camY;
const idx = findResourceAtWorld(wx, wy);
S.selectedResourceIndex = idx;
// small HUD feedback (selection also reflected in draw + HUD lines)
// idx === -1 means cleared selection
}
PATCH 3 — Add hit-test + selection helpers (insert right before drawResources())
Code to Remove
628 -
function drawResources(){
Code to Add
628 -
function findResourceAtWorld(wx, wy){
if(!S.resources || S.resources.length === 0) return -1;
// pick nearest within radius
let best = -1;
let bestD2 = Infinity;
for(let i=0;i<S.resources.length;i++){
const n = S.resources[i];
const dx = wx - n.X;
const dy = wy - n.Y;
const r = (n.Radius || 16) + 6; // click tolerance
const d2 = dx*dx + dy*dy;
if(d2 <= r*r && d2 < bestD2){
bestD2 = d2;
best = i;
}
}
return best;
}
function drawSelectedResourceOverlay(){
const i = S.selectedResourceIndex;
if(i == null || i < 0) return;
if(!S.resources || i >= S.resources.length) return;
const n = S.resources[i];
const sx = n.X - S.camX;
const sy = n.Y - S.camY;
// if selected is offscreen, do nothing
if(sx < -80 || sy < -80 || sx > (VIEW+80) || sy > (VIEW+80)) return;
// highlight ring
ctx.save();
ctx.globalAlpha = 0.95;
ctx.strokeStyle = "rgba(255,255,255,.85)";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.arc(sx, sy, (n.Radius || 16) + 10, 0, Math.PI*2);
ctx.stroke();
// small crosshair
ctx.globalAlpha = 0.6;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(sx-18, sy); ctx.lineTo(sx+18, sy);
ctx.moveTo(sx, sy-18); ctx.lineTo(sx, sy+18);
ctx.stroke();
// label
ctx.globalAlpha = 0.9;
ctx.fillStyle = "rgba(0,0,0,.75)";
ctx.font = "12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
ctx.fillText(`SEL ${n.Type}`, sx + 16, sy - 16);
ctx.restore();
}
function drawResources(){
PATCH 4 — Draw: render selected overlay on top of resources
Code to Remove
773 -
// map first (so other debug overlays draw on top)
drawMapNative();
// resources on top of map
drawResources();
Code to Add
773 -
// map first (so other debug overlays draw on top)
drawMapNative();
// resources on top of map
drawResources();
// selected resource overlay
drawSelectedResourceOverlay();
PATCH 5 — HUD: include selected resource info
Code to Remove
812 -
setHUD(
(S.paused ? "PAUSED" : "READY") +
`\\nFPS: ${S.fps}` +
`\\nM: ${Math.floor(S.mouseX)},${Math.floor(S.mouseY)}` +
`\\nCAM: ${Math.floor(S.camX)},${Math.floor(S.camY)}` +
`\\nRES: ${S.resources ? S.resources.length : 0}`
);
Code to Add
812 -
const si = S.selectedResourceIndex;
let selLine = "\\nSEL: -";
if(si != null && si >= 0 && S.resources && si < S.resources.length){
const n = S.resources[si];
selLine = `\\nSEL: #${si} ${n.Type} @ ${Math.floor(n.X)},${Math.floor(n.Y)}`;
}
setHUD(
(S.paused ? "PAUSED" : "READY") +
`\\nFPS: ${S.fps}` +
`\\nM: ${Math.floor(S.mouseX)},${Math.floor(S.mouseY)}` +
`\\nCAM: ${Math.floor(S.camX)},${Math.floor(S.camY)}` +
`\\nRES: ${S.resources ? S.resources.length : 0}` +
selLine
);
PATCH 6 — Clear selection when starting a new game
Code to Remove
566 -
reseed(seedInput.value);
generateResources();
setView("GAME");
Code to Add
566 -
reseed(seedInput.value);
generateResources();
S.selectedResourceIndex = -1;
setView("GAME");