在產品設計中,最困難的往往不是吸引使用者下載,而是讓使用者願意持續使用。
尤其是習慣養成、心情紀錄這類工具,剛開始使用時可能會感到新鮮,但隨著時間經過,熱情容易逐漸降低。當每天的操作變得重複,使用者也可能慢慢失去持續紀錄的動力。
因此,今天我為《喵語日誌》加入了遊戲化機制,希望將原本較為單調的心情紀錄,轉化成一場溫柔又療癒的徽章收集遊戲。
這次的實作重點包括:
成就系統
成就進度追蹤
徽章牆 UI
已解鎖與未解鎖狀態
底部導覽列整合
透過解鎖徽章的正向回饋,讓使用者在持續記錄的過程中,感受到累積與成長。
在規劃《喵語日誌》的成就系統時,我參考了遊戲化設計中常見的三個核心元素。
使用者需要清楚知道完成什麼事情可以解鎖成就。
例如:
第一次傳送訊息
連續紀錄心情 3 天
紀錄過所有 5 種心情
上傳第一張美食照片
分享 5 張生活照片
在晚上 11 點後紀錄心情
有了明確的目標,使用者才能知道下一步該努力完成什麼。
除了文字提示之外,也需要透過視覺元素呈現目前的完成狀態。
這次使用了以下設計:
已解鎖徽章使用明亮的粉紅色背景
未解鎖徽章使用灰階與半透明效果
未解鎖徽章顯示鎖頭圖示
使用進度條呈現目前進度
在頁面頂部顯示整體完成度
使用者可以透過畫面快速理解目前的收藏狀態,以及距離下一個成就還有多遠。
當成就完成時,徽章會從灰階狀態轉為亮色狀態,並顯示已解鎖標籤。
雖然這些徽章沒有實際的功能獎勵,但可愛的貓咪主題圖示與收集設計,仍然能為日常紀錄增加一點期待感與成就感。
首先,我在 src/data/achievements.ts 中建立 Achievement TypeScript 型態,統一管理每個成就所需要的資料。
export type Achievement = {
id: string;
title: string;
description: string;
icon: string;
isUnlocked: boolean;
progress: number;
total: number;
unlockedDate?: string;
};
各欄位用途如下:
id:成就的唯一識別名稱title:成就標題description:成就解鎖條件說明icon:成就使用的 Emoji 圖示isUnlocked:是否已經解鎖progress:目前完成進度total:解鎖所需的總進度unlockedDate:解鎖日期,可選欄位接著建立初始成就清單:
export const INITIAL_ACHIEVEMENTS: Achievement[] = [
{
id: "first_message",
title: "初來乍到 🐾",
description: "發送第一條訊息給喵喵",
icon: "🐾",
isUnlocked: true,
progress: 1,
total: 1,
},
{
id: "streak_3",
title: "持之以恆 📅",
description: "連續紀錄心情達 3 天",
icon: "📅",
isUnlocked: false,
progress: 2,
total: 3,
},
{
id: "gourmet",
title: "美食家 🍣",
description: "上傳美味的美食照片",
icon: "🍣",
isUnlocked: true,
progress: 1,
total: 1,
},
{
id: "mood_master",
title: "情緒大師 🌈",
description: "紀錄過所有 5 種心情",
icon: "🌈",
isUnlocked: false,
progress: 3,
total: 5,
},
{
id: "photo_lover",
title: "快門高手 📸",
description: "累計分享 5 張生活照片",
icon: "📸",
isUnlocked: false,
progress: 2,
total: 5,
},
{
id: "night_cat",
title: "夜貓族 🌙",
description: "在深夜 11 點後紀錄心情",
icon: "🌙",
isUnlocked: false,
progress: 0,
total: 1,
},
];
目前一共有 6 個成就,其中 2 個已經解鎖,因此整體完成度為:
接下來建立 AchievementCard.tsx,負責呈現單一成就卡片。
成就卡片需要根據 isUnlocked 顯示不同的視覺狀態。
已解鎖狀態
已解鎖的成就會呈現:
柔和的粉紅色背景
亮色 Emoji 圖示
右上角顯示「已解鎖」
進度條顯示為滿格
未解鎖狀態
尚未解鎖的成就則會呈現:
灰階背景
半透明效果
灰階化的 Emoji 圖示
右上角顯示鎖頭圖示
使用黃色進度條提示目前進度
實作如下:
import { Lock } from "lucide-react";
import type { Achievement } from "@/data/achievements";
type AchievementCardProps = {
data: Achievement;
};
export default function AchievementCard({
data,
}: AchievementCardProps) {
const percent = Math.min(
100,
Math.round((data.progress / data.total) * 100)
);
return (
<div
className={`relative flex flex-col justify-between rounded-2xl border p-3.5 transition-all ${
data.isUnlocked
? "border-rose-200/80 bg-rose-50/40"
: "border-stone-200/80 bg-stone-100/50 opacity-70"
}`}
>
<div className="absolute right-3 top-3">
{data.isUnlocked ? (
<span className="text-[10px] text-rose-400">
已解鎖
</span>
) : (
<Lock className="h-3.5 w-3.5 text-stone-400" />
)}
</div>
<div>
<div
className={`mb-2 flex h-10 w-10 items-center justify-center rounded-xl text-xl ${
data.isUnlocked
? "bg-rose-100/80"
: "bg-stone-200/80 grayscale"
}`}
>
{data.icon}
</div>
<h4 className="text-xs font-bold text-stone-800">
{data.title}
</h4>
<p className="mt-0.5 text-[11px] text-stone-500">
{data.description}
</p>
</div>
<div className="mt-3">
<div className="h-1.5 w-full overflow-hidden rounded-full bg-stone-200">
<div
className={`h-full transition-all ${
data.isUnlocked
? "bg-rose-400"
: "bg-amber-400"
}`}
style={{ width: `${percent}%` }}
/>
</div>
{!data.isUnlocked && (
<p className="mt-1 text-right text-[10px] text-stone-400">
{data.progress} / {data.total}
</p>
)}
</div>
</div>
);
}
其中,進度百分比是透過目前進度除以總進度計算:
const percent = Math.min(
100,
Math.round((data.progress / data.total) * 100)
);
使用 Math.min(100, ...) 可以避免進度超過 100%,讓進度條維持在合理範圍內。
完成卡片元件後,接著在 AwardsView.tsx 中建立成就頁面。
頁面主要分成兩個部分:
頂部統計區塊
成就卡片雙欄網格
統計區塊可以顯示:
已解鎖成就數量
成就總數
整體完成度
完成度進度條
成就卡片則使用 Tailwind CSS 的雙欄網格排版:
<div className="grid grid-cols-2 gap-3">
{achievements.map((achievement) => (
<AchievementCard
key={achievement.id}
data={achievement}
/>
))}
</div>
在手機畫面上使用雙欄配置,可以在不佔用太多垂直空間的情況下,同時展示更多徽章。
使用者也能快速瀏覽目前已收藏與尚未解鎖的成就。
最後,我將 AwardsView 整合到 App.tsx 的底部導覽列中。
目前《喵語日誌》共有三個主要模組:
喵喵對話
情緒分析
成就徽章
使用者可以透過底部導覽列,在不同功能頁面之間切換。
這樣的設計讓成就系統不只是藏在某個功能頁面裡,而是成為 App 中清楚可見的核心模組。當使用者完成一筆紀錄後,也更容易主動前往成就頁面查看自己的收集進度。
完成整合後,點擊底部導覽列最右側的「成就徽章」,即可進入成就收藏牆。
目前畫面中可以看到:
頁面頂部顯示整體完成度 33%
「初來乍到 🐾」已成功解鎖
「美食家 🍣」已成功解鎖
「持之以恆 📅」顯示目前進度為 2 / 3
「情緒大師 🌈」顯示目前進度為 3 / 5
尚未解鎖的徽章會顯示鎖頭與進度條

從實際畫面來看,已解鎖與未解鎖狀態有明顯區別,使用者可以不需要閱讀太多文字,就理解每個成就目前的完成情況。
這次加入成就系統後,我更深刻體會到,軟體開發不只是把功能邏輯寫出來,也需要思考使用者在操作過程中的心理感受。
如果一個 App 只有記錄功能,使用者可能很快就會覺得重複與單調。但透過遊戲化設計,原本平凡的日常紀錄,便能轉化成一個持續累積、逐步解鎖的體驗。
每一次完成紀錄,都可能讓某個進度條前進一點;每一次達成條件,都能點亮一個可愛的貓咪主題徽章。
這些小小的回饋,或許就能成為使用者持續使用的動力。
此外,新增第三個頁籤之後,《喵語日誌》的整體架構也更加完整:
對話功能負責陪伴
情緒分析協助理解自己的狀態
成就徽章鼓勵持續紀錄
三個模組彼此搭配,讓 App 不只是單純的聊天工具,也逐漸形成一個兼具陪伴、紀錄與回饋的生活應用。
今天順利完成了成就系統與徽章牆 UI!明天我們將暫緩新功能的開發,專注於**【UI/UX 介面微調與視覺優化】**。我們將為《喵語日誌》進行一輪精細的介面修飾,包含卡片比例、底部導覽列動態反饋與全站配色一致性優化,讓整體的使用體驗更加療癒與精緻!
明天見,喵~