강물 텍스처 교체: 수면 전용 이미지 + 한 방향 흐름

- 순수 수면 텍스처로 교체 (900px JPEG, 137KB)
- 컨텍스트를 강 방향으로 회전 후 미러 타일링 스크롤 → 이음매 없는 단방향 흐름
- 상류(북동) → 하류(남서) 22px/초

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
이 커밋은 다음에 포함됨:
kjs
2026-08-13 12:34:14 +09:00
co-authored by Claude Fable 5
부모 881673b975
커밋 318c7a36b1
2개의 변경된 파일과 27개의 추가작업 그리고 19개의 파일을 삭제
바이너리 파일은 표시되지 않음.

이전

너비:  |  높이:  |  크기: 228 KiB

이후

너비:  |  높이:  |  크기: 133 KiB

+27 -19
파일 보기
@@ -253,25 +253,33 @@ export default function VillageView() {
const water = waterImgRef.current; const water = waterImgRef.current;
if (water) { if (water) {
// 물 영역 바운딩 박스를 덮도록 cover 배치 + 흐르는 방향으로 느린 드리프트 // 강 줄기 방향(상류→하류, 좌하향)으로 한 방향 흐름:
const left = isoX(COLS - 1, ROWS - 1) - TW / 2; // 컨텍스트를 강 방향으로 회전시킨 뒤 텍스처를 미러 타일링하며 스크롤
const right = isoX(COLS - 1, 0) + TW / 2; const sx = isoX(COLS - 1, 0);
const top = isoY(COLS - 1, 0); const sy = isoY(COLS - 1, 0) + TH / 2;
const bottom = isoY(COLS - 1, ROWS - 1) + TH; const ex = isoX(COLS - 1, ROWS - 1);
const boxW = right - left; const ey = isoY(COLS - 1, ROWS - 1) + TH / 2;
const boxH = bottom - top; const angle = Math.atan2(ey - sy, ex - sx);
const scale = Math.max(boxW / water.width, boxH / water.height) * 1.15; const riverLen = Math.hypot(ex - sx, ey - sy);
const w = water.width * scale;
const h = water.height * scale; const h = 220; // 강 폭 방향 커버 (클리핑되므로 넉넉히)
// 강 줄기 방향(좌하향)으로 왕복 드리프트 const w = (water.width / water.height) * h;
const drift = Math.sin(now / 4000) * 14; const FLOW_SPEED = 22; // px/초
ctx.drawImage( const offset = ((now / 1000) * FLOW_SPEED) % (2 * w);
water,
left + (boxW - w) / 2 - drift, ctx.save();
top + (boxH - h) / 2 + drift / 2, ctx.translate(sx, sy);
w, ctx.rotate(angle);
h, 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 { } else {
ctx.fillStyle = "#60a5fa"; ctx.fillStyle = "#60a5fa";
ctx.fillRect(0, 0, CANVAS_W, CANVAS_H); ctx.fillRect(0, 0, CANVAS_W, CANVAS_H);