|
43 | 43 | ctx.strokeStyle = LINE; ctx.lineWidth = 1; |
44 | 44 | for(let x=0;x<=COLS;x++){ ctx.beginPath(); ctx.moveTo(x*CELL,0); ctx.lineTo(x*CELL,cv.height); ctx.stroke(); } |
45 | 45 | for(let y=0;y<=ROWS;y++){ ctx.beginPath(); ctx.moveTo(0,y*CELL); ctx.lineTo(cv.width,y*CELL); ctx.stroke(); } |
46 | | - // hills (large bordered square in the owner's color) |
| 46 | + // hills — an anthill glyph: a soft owner-tinted base, a mound with an entrance |
| 47 | + // hole, and a bold owner-colored ring that stays visible even with an ant on top. |
47 | 48 | (f.hills||[]).forEach(h => { |
48 | | - const x = h[1]*CELL, y = h[0]*CELL; |
49 | | - ctx.fillStyle = col(h[2]); ctx.globalAlpha = 0.35; ctx.fillRect(x, y, CELL, CELL); ctx.globalAlpha = 1; |
50 | | - ctx.strokeStyle = col(h[2]); ctx.lineWidth = 2; ctx.strokeRect(x+1.5, y+1.5, CELL-3, CELL-3); |
| 49 | + const cc = col(h[2]); |
| 50 | + const cx = h[1]*CELL + CELL/2, cy = h[0]*CELL + CELL/2, R = CELL*0.55; |
| 51 | + // soft glow base |
| 52 | + ctx.globalAlpha = 0.22; ctx.fillStyle = cc; |
| 53 | + ctx.beginPath(); ctx.arc(cx, cy, R, 0, 7); ctx.fill(); ctx.globalAlpha = 1; |
| 54 | + // mound (dome) with a white rim for contrast |
| 55 | + ctx.fillStyle = cc; |
| 56 | + ctx.beginPath(); |
| 57 | + ctx.moveTo(cx - R*0.82, cy + R*0.52); |
| 58 | + ctx.quadraticCurveTo(cx, cy - R*0.92, cx + R*0.82, cy + R*0.52); |
| 59 | + ctx.closePath(); ctx.fill(); |
| 60 | + ctx.strokeStyle = 'rgba(255,255,255,0.9)'; ctx.lineWidth = 1.5; ctx.stroke(); |
| 61 | + // entrance hole |
| 62 | + ctx.fillStyle = '#0d1117'; |
| 63 | + ctx.beginPath(); ctx.ellipse(cx, cy + R*0.14, R*0.24, R*0.3, 0, 0, 7); ctx.fill(); |
| 64 | + // framing ring (marks the cell as a hill regardless of an ant sitting on it) |
| 65 | + ctx.strokeStyle = cc; ctx.lineWidth = 2.5; |
| 66 | + ctx.beginPath(); ctx.arc(cx, cy, CELL*0.5 - 1, 0, 7); ctx.stroke(); |
51 | 67 | }); |
52 | 68 | // food (small white diamonds) |
53 | 69 | ctx.fillStyle = FOOD; |
|
0 commit comments