이모지 전면 이미지화: 건물 4종·자연 소품 9종·아이콘 12종
- build2.png → 고양이 집·햇볕 데크·장터·창고 일러스트 적용 - nature.png → 나무 3종(보드=소나무, 외곽=3종 순환)·데이지·튤립·밀· 버섯·바위·꽃덤불 — 캔버스 나무/장식 이모지 제거 - icons.png → 생선·목재·돌·구이·발바닥 코인·망치·땀·접시·잠·화남·팬·하트 판자 배지(아이콘+숫자), 말풍선(생산·식사·수면·파업·회수), HUD pill 적용 - 캔버스 이모지 렌더링이 브라우저/OS 폰트에 따라 깨지던 문제 해결 - 원본 3장 assets-src 보관, 이모지는 이미지 로드 실패 시 폴백으로 유지 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
이후 너비: | 높이: | 크기: 1.8 MiB |
|
이후 너비: | 높이: | 크기: 1.1 MiB |
|
이후 너비: | 높이: | 크기: 1.3 MiB |
|
이후 너비: | 높이: | 크기: 199 KiB |
|
이후 너비: | 높이: | 크기: 191 KiB |
|
이후 너비: | 높이: | 크기: 178 KiB |
|
이후 너비: | 높이: | 크기: 179 KiB |
|
이후 너비: | 높이: | 크기: 15 KiB |
|
이후 너비: | 높이: | 크기: 19 KiB |
|
이후 너비: | 높이: | 크기: 14 KiB |
|
이후 너비: | 높이: | 크기: 7.0 KiB |
|
이후 너비: | 높이: | 크기: 14 KiB |
|
이후 너비: | 높이: | 크기: 14 KiB |
|
이후 너비: | 높이: | 크기: 16 KiB |
|
이후 너비: | 높이: | 크기: 9.7 KiB |
|
이후 너비: | 높이: | 크기: 11 KiB |
|
이후 너비: | 높이: | 크기: 16 KiB |
|
이후 너비: | 높이: | 크기: 5.9 KiB |
|
이후 너비: | 높이: | 크기: 17 KiB |
|
이후 너비: | 높이: | 크기: 60 KiB |
|
이후 너비: | 높이: | 크기: 38 KiB |
|
이후 너비: | 높이: | 크기: 55 KiB |
|
이후 너비: | 높이: | 크기: 47 KiB |
|
이후 너비: | 높이: | 크기: 44 KiB |
|
이후 너비: | 높이: | 크기: 36 KiB |
|
이후 너비: | 높이: | 크기: 37 KiB |
|
이후 너비: | 높이: | 크기: 28 KiB |
|
이후 너비: | 높이: | 크기: 35 KiB |
@@ -21,6 +21,7 @@ import {
|
|||||||
catSprite,
|
catSprite,
|
||||||
DECO_DEFS,
|
DECO_DEFS,
|
||||||
HALL_LEVELS,
|
HALL_LEVELS,
|
||||||
|
ICON_IMG,
|
||||||
KITCHEN_UPGRADE_COST,
|
KITCHEN_UPGRADE_COST,
|
||||||
MEAL_PRICES,
|
MEAL_PRICES,
|
||||||
mealCap,
|
mealCap,
|
||||||
@@ -263,20 +264,27 @@ export default function Game() {
|
|||||||
</button>
|
</button>
|
||||||
{/* 자원 pill */}
|
{/* 자원 pill */}
|
||||||
<div className="mt-2 flex flex-wrap items-center gap-2">
|
<div className="mt-2 flex flex-wrap items-center gap-2">
|
||||||
{[
|
{(
|
||||||
["🐱", `${state.cats.length}/${state.hall.capacity}`],
|
[
|
||||||
["🐟", Math.floor(state.resources.fish)],
|
["🐱", null, `${state.cats.length}/${state.hall.capacity}`],
|
||||||
["🪵", Math.floor(state.resources.wood)],
|
["🐟", ICON_IMG.fish, Math.floor(state.resources.fish)],
|
||||||
["🪨", Math.floor(state.resources.stone)],
|
["🪵", ICON_IMG.wood, Math.floor(state.resources.wood)],
|
||||||
["🍖", meals],
|
["🪨", ICON_IMG.stone, Math.floor(state.resources.stone)],
|
||||||
["🪙", Math.floor(state.coins ?? 0)],
|
["🍖", ICON_IMG.meal, meals],
|
||||||
].map(([icon, value]) => (
|
["🪙", ICON_IMG.coin, Math.floor(state.coins ?? 0)],
|
||||||
|
] as Array<[string, string | null, string | number]>
|
||||||
|
).map(([emoji, img, value]) => (
|
||||||
<span
|
<span
|
||||||
key={icon as string}
|
key={emoji}
|
||||||
className="wood-pill flex items-center gap-1.5 py-1 pl-1 pr-3"
|
className="wood-pill flex items-center gap-1.5 py-1 pl-1 pr-3"
|
||||||
>
|
>
|
||||||
<span className="wood-pill-icon grid h-6 w-6 place-items-center text-[13px]">
|
<span className="wood-pill-icon grid h-6 w-6 place-items-center text-[13px]">
|
||||||
{icon}
|
{img ? (
|
||||||
|
/* eslint-disable-next-line @next/next/no-img-element */
|
||||||
|
<img src={img} alt="" className="h-4 w-4 object-contain" />
|
||||||
|
) : (
|
||||||
|
emoji
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="font-num text-sm leading-none">{value}</span>
|
<span className="font-num text-sm leading-none">{value}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
BUILDING_IMG,
|
BUILDING_IMG,
|
||||||
catSprite,
|
catSprite,
|
||||||
DECO_DEFS,
|
DECO_DEFS,
|
||||||
|
ICON_IMG,
|
||||||
|
NATURE_IMG,
|
||||||
footprintOf,
|
footprintOf,
|
||||||
HALL_TILE,
|
HALL_TILE,
|
||||||
TOOL_IMG,
|
TOOL_IMG,
|
||||||
@@ -23,6 +25,10 @@ import type {
|
|||||||
} from "@/lib/game/types";
|
} from "@/lib/game/types";
|
||||||
|
|
||||||
const RES_EMOJI: Record<ResourceKey, string> = { fish: "🐟", wood: "🪵", stone: "🪨" };
|
const RES_EMOJI: Record<ResourceKey, string> = { fish: "🐟", wood: "🪵", stone: "🪨" };
|
||||||
|
const RES_ICON: Record<ResourceKey, string> = { fish: "fish", wood: "wood", stone: "stone" };
|
||||||
|
const EMOJI_TO_NATURE: Record<string, string> = {
|
||||||
|
"🌼": "daisy", "🌷": "tulip", "🌾": "wheat", "🍄": "mushroom", "🪨": "rock",
|
||||||
|
};
|
||||||
|
|
||||||
export interface PlacingState {
|
export interface PlacingState {
|
||||||
type?: BuildingType; // 건물 배치·이동
|
type?: BuildingType; // 건물 배치·이동
|
||||||
@@ -100,7 +106,8 @@ interface Bubble {
|
|||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
born: number;
|
born: number;
|
||||||
text: string;
|
text?: string; // 이모지·텍스트
|
||||||
|
icon?: string; // ICON_IMG 키 (있으면 이미지로)
|
||||||
}
|
}
|
||||||
|
|
||||||
const WALK_SPEED = 42; // px/초
|
const WALK_SPEED = 42; // px/초
|
||||||
@@ -260,10 +267,17 @@ export default function VillageView({
|
|||||||
.getPropertyValue("--font-jua")
|
.getPropertyValue("--font-jua")
|
||||||
.trim() || "sans-serif";
|
.trim() || "sans-serif";
|
||||||
|
|
||||||
// 나무 판자 배지 그리기 (자원 카운트)
|
// 나무 판자 배지 그리기 (아이콘 + 텍스트)
|
||||||
const drawPlankBadge = (cx: number, cy: number, label: string) => {
|
const drawPlankBadge = (
|
||||||
|
cx: number,
|
||||||
|
cy: number,
|
||||||
|
label: string,
|
||||||
|
iconKey?: string,
|
||||||
|
) => {
|
||||||
|
const iconImg = iconKey ? getImage(ICON_IMG[iconKey]) : undefined;
|
||||||
|
const iconW = iconImg ? 16 : 0;
|
||||||
ctx.font = `bold 13px ${juaFamily}`;
|
ctx.font = `bold 13px ${juaFamily}`;
|
||||||
const w = ctx.measureText(label).width + 18;
|
const w = ctx.measureText(label).width + 18 + iconW;
|
||||||
const h = 22;
|
const h = 22;
|
||||||
const x0 = cx - w / 2;
|
const x0 = cx - w / 2;
|
||||||
const y0 = cy - h;
|
const y0 = cy - h;
|
||||||
@@ -294,10 +308,15 @@ export default function VillageView({
|
|||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
// 텍스트
|
// 아이콘 + 텍스트
|
||||||
|
if (iconImg) {
|
||||||
|
const ih = 15;
|
||||||
|
const iw = (iconImg.width / iconImg.height) * ih;
|
||||||
|
ctx.drawImage(iconImg, x0 + 8, y0 + (h - ih) / 2, iw, ih);
|
||||||
|
}
|
||||||
ctx.fillStyle = "#fbf1d9";
|
ctx.fillStyle = "#fbf1d9";
|
||||||
ctx.textAlign = "center";
|
ctx.textAlign = "center";
|
||||||
ctx.fillText(label, cx, y0 + 16);
|
ctx.fillText(label, cx + iconW / 2, y0 + 16);
|
||||||
};
|
};
|
||||||
|
|
||||||
const draw = (now: number) => {
|
const draw = (now: number) => {
|
||||||
@@ -327,7 +346,7 @@ export default function VillageView({
|
|||||||
cat.status.fullness > anim.lastFullness + 15
|
cat.status.fullness > anim.lastFullness + 15
|
||||||
) {
|
) {
|
||||||
bubblesRef.current.push({
|
bubblesRef.current.push({
|
||||||
x: anim.x, y: anim.y - 40, born: now, text: "🍽️",
|
x: anim.x, y: anim.y - 40, born: now, icon: "plate",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
anim.lastFullness = cat.status.fullness;
|
anim.lastFullness = cat.status.fullness;
|
||||||
@@ -352,7 +371,7 @@ export default function VillageView({
|
|||||||
anim.workBuildingId = null;
|
anim.workBuildingId = null;
|
||||||
// 💤 버블
|
// 💤 버블
|
||||||
if (Math.random() < dt / 4) {
|
if (Math.random() < dt / 4) {
|
||||||
bubblesRef.current.push({ x: anim.x + 10, y: anim.y - 36, born: now, text: "💤" });
|
bubblesRef.current.push({ x: anim.x + 10, y: anim.y - 36, born: now, icon: "sleep" });
|
||||||
}
|
}
|
||||||
} else if (cat.state === "striking") {
|
} else if (cat.state === "striking") {
|
||||||
anim.workBuildingId = null;
|
anim.workBuildingId = null;
|
||||||
@@ -363,7 +382,7 @@ export default function VillageView({
|
|||||||
anim.ty = t.y;
|
anim.ty = t.y;
|
||||||
}
|
}
|
||||||
if (Math.random() < dt / 5) {
|
if (Math.random() < dt / 5) {
|
||||||
bubblesRef.current.push({ x: anim.x + 10, y: anim.y - 36, born: now, text: "💢" });
|
bubblesRef.current.push({ x: anim.x + 10, y: anim.y - 36, born: now, icon: "anger" });
|
||||||
}
|
}
|
||||||
} else if (cat.assignedTo) {
|
} else if (cat.assignedTo) {
|
||||||
const building = state.buildings.find((b) => b.id === cat.assignedTo);
|
const building = state.buildings.find((b) => b.id === cat.assignedTo);
|
||||||
@@ -407,8 +426,7 @@ export default function VillageView({
|
|||||||
if (b && catRate(cat, b.aptitude) > 0) {
|
if (b && catRate(cat, b.aptitude) > 0) {
|
||||||
bubblesRef.current.push({
|
bubblesRef.current.push({
|
||||||
x: anim.x, y: anim.y - 34, born: now,
|
x: anim.x, y: anim.y - 34, born: now,
|
||||||
text:
|
icon: b.type === "kitchen" ? "pan" : RES_ICON[b.resource ?? "fish"],
|
||||||
b.type === "kitchen" ? "🍳" : RES_EMOJI[b.resource ?? "fish"],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -569,23 +587,73 @@ export default function VillageView({
|
|||||||
for (const t of TREES) {
|
for (const t of TREES) {
|
||||||
const x = isoX(t.i, t.j);
|
const x = isoX(t.i, t.j);
|
||||||
const y = isoY(t.i, t.j) + TH / 2;
|
const y = isoY(t.i, t.j) + TH / 2;
|
||||||
sprites.push({ y, draw: () => { shadow(x, y + 4, 14); drawEmoji("🌲", x, y + 6, 34); } });
|
sprites.push({
|
||||||
|
y,
|
||||||
|
draw: () => {
|
||||||
|
const img = getImage(NATURE_IMG.pine);
|
||||||
|
if (img) {
|
||||||
|
const h = 52;
|
||||||
|
const w = (img.width / img.height) * h;
|
||||||
|
shadow(x, y + 4, 12);
|
||||||
|
ctx.drawImage(img, x - w / 2, y + 8 - h, w, h);
|
||||||
|
} else {
|
||||||
|
shadow(x, y + 4, 14);
|
||||||
|
drawEmoji("🌲", x, y + 6, 34);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
for (const d of DECOR) {
|
for (const d of DECOR) {
|
||||||
const x = isoX(d.i, d.j);
|
const x = isoX(d.i, d.j);
|
||||||
const y = isoY(d.i, d.j) + TH / 2;
|
const y = isoY(d.i, d.j) + TH / 2;
|
||||||
sprites.push({ y: y - 6, draw: () => drawEmoji(d.emoji, x, y + 4, 18) });
|
sprites.push({
|
||||||
|
y: y - 6,
|
||||||
|
draw: () => {
|
||||||
|
const img = getImage(NATURE_IMG[EMOJI_TO_NATURE[d.emoji] ?? ""]);
|
||||||
|
if (img) {
|
||||||
|
const h = 22;
|
||||||
|
const w = (img.width / img.height) * h;
|
||||||
|
ctx.drawImage(img, x - w / 2, y + 6 - h, w, h);
|
||||||
|
} else drawEmoji(d.emoji, x, y + 4, 18);
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// 보드 밖 배경 장식 (마을을 둘러싼 숲)
|
// 보드 밖 배경 장식 (마을을 둘러싼 숲 — 나무 3종 순환)
|
||||||
for (const t of OUTER_TREES) {
|
const OUTER_KINDS = ["pine", "leafy", "pine_small"];
|
||||||
|
OUTER_TREES.forEach((t, idx) => {
|
||||||
const x = isoX(t.i, t.j);
|
const x = isoX(t.i, t.j);
|
||||||
const y = isoY(t.i, t.j) + TH / 2;
|
const y = isoY(t.i, t.j) + TH / 2;
|
||||||
sprites.push({ y, draw: () => { shadow(x, y + 4, 15); drawEmoji("🌲", x, y + 6, 38); } });
|
const kind = OUTER_KINDS[idx % 3];
|
||||||
}
|
sprites.push({
|
||||||
|
y,
|
||||||
|
draw: () => {
|
||||||
|
const img = getImage(NATURE_IMG[kind]);
|
||||||
|
if (img) {
|
||||||
|
const h = kind === "pine_small" ? 42 : 58;
|
||||||
|
const w = (img.width / img.height) * h;
|
||||||
|
shadow(x, y + 4, 13);
|
||||||
|
ctx.drawImage(img, x - w / 2, y + 8 - h, w, h);
|
||||||
|
} else {
|
||||||
|
shadow(x, y + 4, 15);
|
||||||
|
drawEmoji("🌲", x, y + 6, 38);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
for (const d of OUTER_DECOR) {
|
for (const d of OUTER_DECOR) {
|
||||||
const x = isoX(d.i, d.j);
|
const x = isoX(d.i, d.j);
|
||||||
const y = isoY(d.i, d.j) + TH / 2;
|
const y = isoY(d.i, d.j) + TH / 2;
|
||||||
sprites.push({ y: y - 6, draw: () => drawEmoji(d.emoji, x, y + 4, 18) });
|
sprites.push({
|
||||||
|
y: y - 6,
|
||||||
|
draw: () => {
|
||||||
|
const img = getImage(NATURE_IMG[EMOJI_TO_NATURE[d.emoji] ?? "bush"]);
|
||||||
|
if (img) {
|
||||||
|
const h = 24;
|
||||||
|
const w = (img.width / img.height) * h;
|
||||||
|
ctx.drawImage(img, x - w / 2, y + 6 - h, w, h);
|
||||||
|
} else drawEmoji(d.emoji, x, y + 4, 18);
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hitRectsRef.current = [];
|
hitRectsRef.current = [];
|
||||||
@@ -658,7 +726,7 @@ export default function VillageView({
|
|||||||
const remain = Math.max(0, Math.ceil(((b.constructionUntil ?? 0) - Date.now()) / 1000));
|
const remain = Math.max(0, Math.ceil(((b.constructionUntil ?? 0) - Date.now()) / 1000));
|
||||||
const mm = Math.floor(remain / 60);
|
const mm = Math.floor(remain / 60);
|
||||||
const ss = remain % 60;
|
const ss = remain % 60;
|
||||||
drawPlankBadge(x, y - imgW * 0.5, `🔨 ${mm}:${String(ss).padStart(2, "0")}`);
|
drawPlankBadge(x, y - imgW * 0.5, `${mm}:${String(ss).padStart(2, "0")}`, "hammer");
|
||||||
ctx.font = `13px ${juaFamily}`;
|
ctx.font = `13px ${juaFamily}`;
|
||||||
ctx.textAlign = "center";
|
ctx.textAlign = "center";
|
||||||
ctx.strokeStyle = "rgba(255,252,238,0.75)";
|
ctx.strokeStyle = "rgba(255,252,238,0.75)";
|
||||||
@@ -689,8 +757,10 @@ export default function VillageView({
|
|||||||
ctx.fillStyle = "#4a3418";
|
ctx.fillStyle = "#4a3418";
|
||||||
ctx.fillText(b.name, x, baseY + 17);
|
ctx.fillText(b.name, x, baseY + 17);
|
||||||
if (stored > 0) {
|
if (stored > 0) {
|
||||||
const label = `${isKitchen ? "🍖" : RES_EMOJI[b.resource ?? "fish"]} ${stored}`;
|
drawPlankBadge(
|
||||||
drawPlankBadge(x, y - imgW * 0.55, label);
|
x, y - imgW * 0.55, `${stored}`,
|
||||||
|
isKitchen ? "meal" : RES_ICON[b.resource ?? "fish"],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -750,7 +820,13 @@ export default function VillageView({
|
|||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
ctx.fillStyle = "rgba(74,52,24,0.9)";
|
ctx.fillStyle = "rgba(74,52,24,0.9)";
|
||||||
ctx.fillText(cat.name, anim.x, anim.y + 14);
|
ctx.fillText(cat.name, anim.x, anim.y + 14);
|
||||||
if (working && !cat.state) drawEmoji("💦", anim.x + 14, anim.y - 30 + bob, 11);
|
if (working && !cat.state) {
|
||||||
|
const sw = getImage(ICON_IMG.sweat);
|
||||||
|
if (sw) {
|
||||||
|
const ih = 13;
|
||||||
|
ctx.drawImage(sw, anim.x + 10, anim.y - 40 + bob, (sw.width / sw.height) * ih, ih);
|
||||||
|
} else drawEmoji("💦", anim.x + 14, anim.y - 30 + bob, 11);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -863,7 +939,29 @@ export default function VillageView({
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ctx.globalAlpha = 1 - age;
|
ctx.globalAlpha = 1 - age;
|
||||||
drawEmoji(bub.text, bub.x, bub.y - age * 22, 14);
|
const by = bub.y - age * 22;
|
||||||
|
const iconImg = bub.icon ? getImage(ICON_IMG[bub.icon]) : undefined;
|
||||||
|
if (iconImg) {
|
||||||
|
const ih = 16;
|
||||||
|
const iw = (iconImg.width / iconImg.height) * ih;
|
||||||
|
const textW = bub.text
|
||||||
|
? (ctx.font = `bold 12px ${juaFamily}`, ctx.measureText(bub.text).width)
|
||||||
|
: 0;
|
||||||
|
const total = iw + (textW ? textW + 4 : 0);
|
||||||
|
ctx.drawImage(iconImg, bub.x - total / 2, by - ih + 4, iw, ih);
|
||||||
|
if (bub.text) {
|
||||||
|
ctx.fillStyle = "#4a3418";
|
||||||
|
ctx.strokeStyle = "rgba(255,252,238,0.8)";
|
||||||
|
ctx.lineWidth = 3;
|
||||||
|
ctx.textAlign = "left";
|
||||||
|
ctx.strokeText(bub.text, bub.x - total / 2 + iw + 4, by);
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.fillText(bub.text, bub.x - total / 2 + iw + 4, by);
|
||||||
|
ctx.textAlign = "center";
|
||||||
|
}
|
||||||
|
} else if (bub.text) {
|
||||||
|
drawEmoji(bub.text, bub.x, by, 14);
|
||||||
|
}
|
||||||
ctx.globalAlpha = 1;
|
ctx.globalAlpha = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -915,9 +1013,9 @@ export default function VillageView({
|
|||||||
const gained = Math.floor(s.resources[b.resource]) - before;
|
const gained = Math.floor(s.resources[b.resource]) - before;
|
||||||
bubblesRef.current.push({
|
bubblesRef.current.push({
|
||||||
x: r.x + r.w / 2, y: r.y, born: performance.now(),
|
x: r.x + r.w / 2, y: r.y, born: performance.now(),
|
||||||
text: err
|
...(err
|
||||||
? "📦 창고 가득!"
|
? { text: "📦 창고 가득!" }
|
||||||
: `+${gained} ${RES_EMOJI[b.resource]}`,
|
: { icon: RES_ICON[b.resource], text: `+${gained}` }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -31,6 +31,39 @@ export const BUILDING_IMG: Record<string, string> = {
|
|||||||
lumberyard: "/assets/buildings/lumberyard.png",
|
lumberyard: "/assets/buildings/lumberyard.png",
|
||||||
quarry: "/assets/buildings/quarry.png",
|
quarry: "/assets/buildings/quarry.png",
|
||||||
kitchen: "/assets/buildings/kitchen.png",
|
kitchen: "/assets/buildings/kitchen.png",
|
||||||
|
cat_house: "/assets/buildings/cat_house.png",
|
||||||
|
sun_deck: "/assets/buildings/sun_deck.png",
|
||||||
|
market: "/assets/buildings/market.png",
|
||||||
|
warehouse: "/assets/buildings/warehouse.png",
|
||||||
|
};
|
||||||
|
|
||||||
|
// 자연 소품 일러스트 (public/assets/nature/)
|
||||||
|
export const NATURE_IMG: Record<string, string> = {
|
||||||
|
pine: "/assets/nature/pine.png",
|
||||||
|
leafy: "/assets/nature/leafy.png",
|
||||||
|
pine_small: "/assets/nature/pine_small.png",
|
||||||
|
daisy: "/assets/nature/daisy.png",
|
||||||
|
tulip: "/assets/nature/tulip.png",
|
||||||
|
wheat: "/assets/nature/wheat.png",
|
||||||
|
mushroom: "/assets/nature/mushroom.png",
|
||||||
|
rock: "/assets/nature/rock.png",
|
||||||
|
bush: "/assets/nature/bush.png",
|
||||||
|
};
|
||||||
|
|
||||||
|
// 아이콘 일러스트 — 배지·버블·HUD (public/assets/icons/)
|
||||||
|
export const ICON_IMG: Record<string, string> = {
|
||||||
|
fish: "/assets/icons/fish.png",
|
||||||
|
wood: "/assets/icons/wood.png",
|
||||||
|
stone: "/assets/icons/stone.png",
|
||||||
|
meal: "/assets/icons/meal.png",
|
||||||
|
coin: "/assets/icons/coin.png",
|
||||||
|
hammer: "/assets/icons/hammer.png",
|
||||||
|
sweat: "/assets/icons/sweat.png",
|
||||||
|
plate: "/assets/icons/plate.png",
|
||||||
|
sleep: "/assets/icons/sleep.png",
|
||||||
|
anger: "/assets/icons/anger.png",
|
||||||
|
pan: "/assets/icons/pan.png",
|
||||||
|
heart: "/assets/icons/heart.png",
|
||||||
};
|
};
|
||||||
|
|
||||||
// 적성별 도구 일러스트 (public/assets/tools/)
|
// 적성별 도구 일러스트 (public/assets/tools/)
|
||||||
|
|||||||