Balatro:撲克 Roguelike 中令人愉悅的回饋

Balatro 如何憑藉 CRT 掃描線、卡牌物理效果、分數動畫以及讓撲克數學在螢幕上充滿張力的回饋循環,榮獲 2025 年 Apple Design Award。

6 分鐘閱讀 156 字
Balatro:撲克 Roguelike 中令人愉悅的回饋 screenshot

每次互動都應該令人感到有所回饋。當玩家重複數千手牌局時,回饋循環本身就成為了遊戲。— Balatro 背後的設計哲學

Balatro 是一款以撲克為主題的 roguelike 牌組構築遊戲,繼 2024 年獲得多項重要獎項肯定後,於 2025 年榮獲 Apple Design Award。這款遊戲由 LocalThunk(以化名工作的獨立開發者)創作,將枯燥的撲克牌型評估數學,轉化為一場震撼螢幕、扣人心弦的體驗。這款遊戲證明了視覺回饋設計並非裝飾,而是產品的核心。每一個累積的籌碼、每一次觸發的倍率、每一個發現的 Joker 協同效應,都透過層次分明的動畫、粒子效果與音效傳達,讓算術運算彷彿煙火般絢爛奪目。

對設計師而言,Balatro 之所以令人驚艷,在於其底層系統不過就是數學運算。撲克牌型有對應的點數,Joker 會增加倍率,玩家要做的就是達到分數門檻。從「試算表」到「多巴胺機器」之間的整段體驗鴻溝,全靠回饋設計來填補。


為何 Balatro 值得關注

一位獨立開發者打造出 2024 年最受矚目的獨立遊戲之一,其視覺風格正是在限制中誕生。CRT 美學源自侷限,而非龐大的美術製作流程。

主要成就: - Apple Design Award 2025 得主 - 多項 2024 年重要獎項與年度遊戲提名 - 上市六個月內銷售突破 200 萬份 - 由 LocalThunk 獨力打造,Apple 形容他是一位以化名工作的獨立開發者 - 雖刻意採用低畫質視覺,仍獲最佳美術指導提名


重點摘要

  1. 回饋就是產品本身,而非錦上添花 — 抽掉 Balatro 的動畫與音效,剩下的不過是一台計算機;那股「juice」就是遊戲本體,而非堆疊在上的一層裝飾
  2. 限制孕育出獨特風格 — CRT 掃描線美學誕生於獨立開發者的種種限制之中,最終成為獨立遊戲圈最具辨識度的視覺識別
  3. 協同效果視覺化建立精通感 — 明確顯示哪些牌觸發了哪些加成,將晦澀的數學轉化為可學習的系統
  4. 層疊回饋創造立體感知 — 畫面震動+粒子爆發+數字動畫+音效=同一瞬間呈現出三維般的厚度
  5. 復古美學透過一致性贏得信任 — 每個元素都全心投入 CRT 的虛構世界 — 選單、卡牌、背景,甚至連暫停畫面都像映像管螢幕一樣扭曲

核心設計原則

1. The Juice Stack

Balatro 在每次得分事件上層疊多重回饋通道。沒有任何單一通道能獨自撐起整體體驗 — 它們以乘法方式堆疊,正如遊戲的計分機制一樣。

SCORING A FLUSH (5 cards, base 175 chips)

LAYER 1: Card Animation
  Cards slide from hand  scoring area
  Each card flips with a spring bounce
  Slight rotation randomness (±3deg) for organic feel

LAYER 2: Chip Counter
  Numbers don't just appear  they ROLL
  Each digit spins like a slot machine reel
  Blue chip count rolls up, then red multiplier kicks in

LAYER 3: Screen Effects
  Screen shake intensity scales with score magnitude
  CRT scanlines intensify momentarily
  Background color pulses toward the hand's color

LAYER 4: Particle System
  Chips burst from scored cards
  Trail particles follow the score as it flies to the total
  Color matches the poker hand type

LAYER 5: Audio
  Each card plays a rising pitch note (C, D, E, F, G for 5 cards)
  Multiplier trigger has a distinct "ka-ching" layer
  Score threshold reached = bass drop + screen flash

CSS 分數滾動效果實作:

.score-digit {
  display: inline-block;
  overflow: hidden;
  height: 1.2em;
}

.score-digit-inner {
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Each digit rolls independently with staggered timing */
.score-digit:nth-child(1) .score-digit-inner { transition-delay: 0ms; }
.score-digit:nth-child(2) .score-digit-inner { transition-delay: 50ms; }
.score-digit:nth-child(3) .score-digit-inner { transition-delay: 100ms; }
.score-digit:nth-child(4) .score-digit-inner { transition-delay: 150ms; }

/* The roll: translate Y to show the target digit */
.score-digit-inner[data-value="7"] {
  transform: translateY(-840%); /* 7 * 120% per digit height */
}

2. CRT 掃描線美學作為品牌識別

Balatro 的整體視覺語言建立在 CRT 螢幕的虛構之上。這並非套用在表層的濾鏡,而是其他所有視覺選擇皆由此延伸的根本設計決策。

/* Balatro-style CRT overlay */
.crt-container {
  position: relative;
  background: #1a1a2e;
  border-radius: 12px;
  overflow: hidden;
}

/* Scanline overlay */
.crt-container::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0px,
    transparent 2px,
    rgba(0, 0, 0, 0.15) 2px,
    rgba(0, 0, 0, 0.15) 4px
  );
  pointer-events: none;
  z-index: 10;
}

/* Subtle screen curvature via vignette */
.crt-container::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse at center,
    transparent 60%,
    rgba(0, 0, 0, 0.4) 100%
  );
  pointer-events: none;
  z-index: 11;
}

/* Phosphor glow on text/elements */
.crt-text {
  color: #e8e8e8;
  text-shadow:
    0 0 2px rgba(255, 255, 255, 0.5),
    0 0 8px rgba(100, 200, 255, 0.15);
}

這如何成為識別而非噱頭: - 掃描線始終存在,無法切換——它們就是這個世界本身,而非濾鏡 - 弧面暈影效果足夠細微,不會干擾遊玩 - 卡牌美術是為掃描線而設計的——像素藝術採用適當的解析度以乾淨地走樣 - 選單畫面、商店畫面與暫停畫面皆維持 CRT 的虛構感 - 就連遊戲的標誌也彷彿顯示在曲面映像管上般扭曲

3. 協同視覺化作為教學工具

Balatro 最重要的設計創新,在於它向玩家展示分數「為何」如此產生。當一手牌打出時,每個計分元素會依序啟動,並搭配視覺提示。

HAND PLAYED: 4 Kings

Step 1: Base hand evaluated
  "Four of a Kind" label appears
  Base: 60 chips × 7 mult

Step 2: Each Joker triggers in order (left to right)
  ┌─────────┐  ┌─────────┐  ┌─────────┐
  │ Joker 1 │→ │ Joker 2 │→ │ Joker 3 │
  │ +4 mult │  │ ×1.5    │  │ +30chips│
  │ (pulse) │  │ (pulse) │  │ (pulse) │
  └─────────┘  └─────────┘  └─────────┘
  Each Joker physically bounces when it activates
  Running total updates after each trigger

Step 3: Final score animation
  90 chips × 15.0 mult = 1,350
  Score flies to the chip total with trail particles

THE CRITICAL INSIGHT:
  By showing each Joker trigger individually,
  players learn which combinations matter.
  This replaces a 10-page tutorial with
  300ms of sequential animation.

值得借鑑的設計模式

螢幕震動作為資訊設計

Balatro將螢幕震動不僅用於「手感」,更作為一條資料通道。震動強度在數字出現之前就已傳達分數的大小。玩家僅憑震動就能本能地感受到「那是一手大牌」。

/* Score-proportional screen shake */
@keyframes shake-small {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-2px, 1px); }
  50% { transform: translate(1px, -2px); }
  75% { transform: translate(-1px, 2px); }
}

@keyframes shake-medium {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-4px, 3px); }
  40% { transform: translate(3px, -4px); }
  60% { transform: translate(-3px, 2px); }
  80% { transform: translate(4px, -3px); }
}

@keyframes shake-large {
  0%, 100% { transform: translate(0, 0); }
  10% { transform: translate(-8px, 6px) rotate(-1deg); }
  30% { transform: translate(6px, -8px) rotate(0.5deg); }
  50% { transform: translate(-6px, 4px) rotate(-0.5deg); }
  70% { transform: translate(8px, -6px) rotate(1deg); }
  90% { transform: translate(-4px, 8px) rotate(-0.5deg); }
}

/* Apply based on score magnitude */
.game-container.shake-small { animation: shake-small 0.2s ease-out; }
.game-container.shake-medium { animation: shake-medium 0.3s ease-out; }
.game-container.shake-large { animation: shake-large 0.5s ease-out; }
function triggerScoreShake(score) {
  const container = document.querySelector('.game-container');
  let shakeClass;

  if (score > 10000) shakeClass = 'shake-large';
  else if (score > 1000) shakeClass = 'shake-medium';
  else shakeClass = 'shake-small';

  container.classList.add(shakeClass);
  container.addEventListener('animationend', () => {
    container.classList.remove(shakeClass);
  }, { once: true });
}

傳達狀態的卡牌物理效果

Balatro中的卡牌從不靜止。它們會懸浮、隨游標傾斜,箔面圖層上還帶有細膩的視差效果。這種持續的微動讓手牌彷彿有了生命,卡牌也宛如實體物件。

/* Card hover with parallax tilt */
.card {
  transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
  transform-style: preserve-3d;
  cursor: pointer;
}

.card:hover {
  transform: translateY(-12px) scale(1.05);
  box-shadow:
    0 12px 24px rgba(0, 0, 0, 0.4),
    0 0 20px rgba(100, 150, 255, 0.15);
}

/* Selected card lifts higher */
.card.selected {
  transform: translateY(-24px) scale(1.08);
  box-shadow:
    0 20px 40px rgba(0, 0, 0, 0.5),
    0 0 30px rgba(255, 200, 50, 0.3);
}

/* Foil/holographic shimmer on special cards */
.card.foil::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    135deg,
    transparent 20%,
    rgba(255, 255, 255, 0.1) 40%,
    rgba(200, 220, 255, 0.2) 50%,
    rgba(255, 255, 255, 0.1) 60%,
    transparent 80%
  );
  background-size: 200% 200%;
  animation: foil-shimmer 3s ease-in-out infinite;
  border-radius: inherit;
  pointer-events: none;
}

@keyframes foil-shimmer {
  0% { background-position: 200% 200%; }
  50% { background-position: 0% 0%; }
  100% { background-position: 200% 200%; }
}

將顏色當作計分語言

Balatro為籌碼(藍色)與倍率(紅色)指定了截然不同的顏色。這套雙色系統讓玩家無須閱讀標籤,就能瞬間解讀任何計分畫面。

BALATRO'S SCORING COLOR SYSTEM

  Blue (#009dff)  = Chips (base value)
  Red  (#fe5f55)  = Multiplier
  Gold (#f0c040)  = Money/economy
  Green (#50c878) = Hand remaining
  Purple (#9b59b6)= Planet cards (hand upgrades)

Every number in the game uses this palette.
No labels neededcolor IS the label.

最終評斷

Balatro是回饋設計領域最具代表性的案例研究。它證明了「遊戲手感」並非主觀的潤飾,而是一套可設計、可層疊的系統。Balatro中的每一次互動,都會穿越所謂的juice stack:動畫、粒子、畫面特效、音效與觸覺回饋。抽掉其中任何一層,遊戲仍然可以運作;但若全部抽離,剩下的就只是一張試算表。這兩種體驗之間的落差,正是整套價值主張的全部,而這一切來自一位深知「事物給人的感受,就是它本身」的創作者。

最適合學習的面向: 層疊式回饋系統、分數視覺化、由限制驅動的美學識別,以及如何透過動畫時序與畫面特效,讓數學感覺像魔法。


常見問題

Balatro的視覺回饋與其他遊戲相比有何不同?

大多數遊戲會將回饋當作開發末期的潤飾來處理。Balatro的回饋本身就是設計——Joker的依序觸發、分數滾動與畫面震動都與計分系統一同打造,而不是事後疊加上去的。每個回饋通道(視覺、音效、觸覺、動態)都承載獨立的資訊,因此能以乘法方式堆疊,而非冗餘重複。

為何CRT美學能成功,而復古濾鏡通常顯得做作?

Balatro徹底投入CRT的世界觀。掃描線不是開關或濾鏡——它們就是這個世界本身。卡牌美術以像素精雕細琢,能與掃描線解析度乾淨地疊合。選單、商店,甚至暫停畫面都維持著弧度與磷光暈染。當一種美學是根基而非表面塗裝時,呈現出來的便是身分認同,而非懷舊的取巧。

Balatro如何在沒有教學關卡的情況下教會玩家其複雜的計分系統?

關鍵在於Joker的依序觸發。當一手牌計分時,每個Joker會依序(從左到右)視覺性脈動,並顯示其貢獻。玩家會看到累計總分在每次觸發後更新。這段300ms的動畫,透過直接展示因果關係取代了大量說明文件。玩過幾手後,玩家便能憑直覺理解哪些Joker彼此協同,根本不必閱讀提示文字。

網頁設計師能從Balatro的做法中學到什麼?

分數數字滾動、將畫面震動作為資料通道,以及以顏色作為標籤的系統,全都能直接套用於網頁介面。儀表板上滾動到目標值的數字、錯誤狀態下容器的細微震動,以及為資料類型設計的一致配色,都是Balatro執行得淋漓盡致的模式。核心心得是:回饋應與意義的份量成正比。

一位獨立開發者是如何達成獲獎等級的美術指導?

靠的是限制。LocalThunk之所以選擇CRT美學,部分原因在於低解析度的像素美術對一個人來說是可行的。掃描線疊加、暗角與磷光暈染能在不需要高解析度素材的情況下,增添畫面感知上的精緻度。給小型團隊的啟示是:選擇一種你的限制能成就的美學,然後全心投入。


資源