diff --git a/public/assets/water.jpg b/public/assets/water.jpg index c63ac49..dbd9876 100644 Binary files a/public/assets/water.jpg and b/public/assets/water.jpg differ diff --git a/src/components/game/VillageView.tsx b/src/components/game/VillageView.tsx index 61fef3a..62197da 100644 --- a/src/components/game/VillageView.tsx +++ b/src/components/game/VillageView.tsx @@ -253,25 +253,33 @@ export default function VillageView() { const water = waterImgRef.current; if (water) { - // 물 영역 바운딩 박스를 덮도록 cover 배치 + 흐르는 방향으로 느린 드리프트 - const left = isoX(COLS - 1, ROWS - 1) - TW / 2; - const right = isoX(COLS - 1, 0) + TW / 2; - const top = isoY(COLS - 1, 0); - const bottom = isoY(COLS - 1, ROWS - 1) + TH; - const boxW = right - left; - const boxH = bottom - top; - const scale = Math.max(boxW / water.width, boxH / water.height) * 1.15; - const w = water.width * scale; - const h = water.height * scale; - // 강 줄기 방향(좌하향)으로 왕복 드리프트 - const drift = Math.sin(now / 4000) * 14; - ctx.drawImage( - water, - left + (boxW - w) / 2 - drift, - top + (boxH - h) / 2 + drift / 2, - w, - h, - ); + // 강 줄기 방향(상류→하류, 좌하향)으로 한 방향 흐름: + // 컨텍스트를 강 방향으로 회전시킨 뒤 텍스처를 미러 타일링하며 스크롤 + const sx = isoX(COLS - 1, 0); + const sy = isoY(COLS - 1, 0) + TH / 2; + const ex = isoX(COLS - 1, ROWS - 1); + const ey = isoY(COLS - 1, ROWS - 1) + TH / 2; + const angle = Math.atan2(ey - sy, ex - sx); + const riverLen = Math.hypot(ex - sx, ey - sy); + + const h = 220; // 강 폭 방향 커버 (클리핑되므로 넉넉히) + const w = (water.width / water.height) * h; + const FLOW_SPEED = 22; // px/초 + const offset = ((now / 1000) * FLOW_SPEED) % (2 * w); + + ctx.save(); + ctx.translate(sx, sy); + ctx.rotate(angle); + const copies = Math.ceil((riverLen + TW * 3) / w) + 2; + for (let k = -2; k < copies; k++) { + const xk = k * w - offset; + ctx.save(); + ctx.translate(xk + w / 2, 0); + if (((k % 2) + 2) % 2 === 1) ctx.scale(-1, 1); // 미러 타일링으로 이음매 제거 + ctx.drawImage(water, -w / 2, -h / 2, w, h); + ctx.restore(); + } + ctx.restore(); } else { ctx.fillStyle = "#60a5fa"; ctx.fillRect(0, 0, CANVAS_W, CANVAS_H);