當前位置: 華文問答 > 遊戲

為什麽有32個關卡的遊戲【超級馬里奧兄弟】只要40KB?

2021-04-08遊戲

早期紅白機的經典遊戲容量出乎意料的小。

這個問題曾經在知乎上引起過熱烈的討論,B站、微信上都有相關的熱門影片。相關資料我會整理到答案的末尾,以供參考。

經過一段時間的廣泛討論,這一問題逐漸變得更加清楚了。感謝Anjie的邀請,再將這個問題整理一遍做出回答,對一些有價值的資訊做個總結 :)

1、核心壓縮方法——Tile(瓦片)

首先,實際上初代【超級馬力歐兄弟】只有40KB。

我們先別急著驚訝,先問一個問題:無論40KB還是400KB,它一定有一種基本的壓縮方法,這個壓縮方法與我們今天保存圖片的方式肯定從根本上就有區別。

紅白機的基本影像單元為「Tile瓦片」,每個瓦片為8x8像素大小。與現代遊戲直接繪制像素的思路不同,紅白機上的遊戲必須先準備好一系列瓦片,再把瓦片拼在一起形成畫面。

為什麽要這麽做呢?透過簡單的數學運算可以知道,先做一些瓦片再拼接瓦片,記憶體占用量要遠遠低於直接繪制每一個像素。

例如:一張128*128像素的圖片,每個像素可以選2^8=256種顏色,那麽每個像素需要記錄8bit=1Byte資訊,共占用空間16KB。(128*128*1 Byte)

而如果換成8x8的瓦片去鋪滿圖片,則只需要 16 * 16 = 256個瓦片就夠了,如果總共只有256種不同樣式的瓦片,那麽只需要256B 即可表示這張圖片。

簡單來說: 用重復出現的模式拼成一幅畫面,可以極大壓縮圖片占用的空間

但這裏留下了一個問題:256種瓦片本身也要占用空間,瓦片本身如何儲存?

2、FC如何保存色彩數據

FC雖然畫質簡陋,但色彩還是相當鮮艷的。在當時的技術條件下,FC理論上可以表示50多種顏色,一個像素的顏色可以用6bit表示。而一個瓦片有8x8 = 256個像素,那麽就需要 8x8x6 bit = 48 Byte 來表示一個瓦片。

FC色板

這麽算起來就出問題了~~ 256種瓦片,每個瓦片 48 Byte,瓦片容量等於256*48 B = 16384 B。好家夥,什麽都沒幹,光瓦片就存了16KB,顯然太多了。

解決這一矛盾的核心,是另一個問題: FC如何保存顏色數據?

透過 @文禮 大神的回答可以知道(文禮 的回答),每個瓦片只能繫結一個調色盤,而每個調色盤只有4種顏色,所以 每個瓦片的容量占用僅有 8x8x2bit = 16Byte,比上述估算的少4倍

而且,調色盤帶來另一個有趣的功能,考慮下面幾個圖片:

外觀完全一樣有沒有?

上圖中不同的圖片僅僅是顏色不同,並不需要建立新的瓦片,只需要給同一個瓦片替換不同的「調色盤」即可。這樣可以巧妙利用調色盤,建立出不同皮膚的物體,而容量幾乎沒有增加。

3、FC如何保存音樂數據

現代音樂格式往往直接保存聲道的波形,這種做法保真度高、通用性強,但很顯然占用空間多,一首曲子的容量以兆字節計算。

而八位芯片時代的音訊解決方案,關鍵是一顆專用芯片,例如FC用的理光2A03:

下:理光2A03

音訊芯片可以產生合成音效,能提供的音色可以在一定程度上配置,但非常有限。聽聽FC遊戲的音樂可以體會到常用的音色幾乎一樣。我覺得這個音訊芯片最厲害的地方是可以同時播放幾個音軌(但不能是和弦那種「同時」),【魂鬥羅】、【沙羅曼蛇】、【忍者龍劍傳】的殿堂級音樂,主要是靠多個音軌的交替配合實作的。

每個音符只要記錄音色、頻率和音高就足夠了,音訊芯片會辨識出來。把音符按時間排列好就是「樂譜」了,可以簡單理解為「簡譜」。這種簡譜需要的數據量十分有限,而且大部份遊戲音樂都是迴圈播放,數據量更是小的可憐。

當時的芯片擅長產生的波形包括方波、三角波、正弦波等等,其中三角波用來做Bass效果很好。而【超級馬力歐兄弟】裏面的「鼓」是用「噪波」實作的,也是當年的常用做法。

FC的音訊芯片還支持短時間的采樣音樂,後期的【忍者龍劍傳3】BGM裏面的鼓聲采用了8Bit采樣聲音, 效果超棒。

【忍者龍劍傳3——黃泉的方舟】容量達到了256KB,畫質和音質也有極大提升

4、FC的程式程式碼容量

有趣的是,現在絕大多數人都忽略了程式程式碼本身所占用的空間。但在那個記憶體容量極其有限的年代,程式碼的體積不可小覷。

FC時代的遊戲雖然邏輯不可謂不豐富,但確實整體程式碼不大。為什麽呢?

因為FC時代的遊戲,沒有所謂的「引擎層」,FC的硬件本身就是一個非常簡陋的遊戲引擎。任天堂的主機完全是為遊戲而設計的,瓦片、調色盤、音樂、音效等基本功能已經預先考慮到了,使用特定的方式就能直接呼叫,這樣一來就節約了大量底層程式碼。

程式設計師要仔細研究文件,在硬件框架下思考問題,比如如何顯示圖片、如何卷動螢幕等等;而且還要非常熟悉硬件底層和組譯,不要浪費程式碼空間。

一來二去,程式碼也能寫的非常小。

5、其它最佳化機制

為了極限壓榨容量,當年的程式設計師和美術也動了不少腦筋,比如幾個經典案例:

對稱反轉,形成走路動畫
雲彩和草地完全一樣,只是換了調色盤
火柱,只不過是火球連成串

這些細節的最佳化,也對壓縮大小起到了一定作用。但總的來說,並不是讓容量變小的主力~~~

總結

以上分5個部份,詳細介紹了FC遊戲容量小的原因,特別是背後的本質原理。

以上內容參考了很多內容,包括不限於wiki、知乎、B站等渠道。有錯誤的地方不吝賜教~~

參考資料:

  1. 知乎問題:為什麽魂鬥羅只有128KB卻可以實作那麽長的劇情?
  2. B站:【差評君】為什麽有32個關卡的超級馬里奧兄弟只要40KB?_嗶哩嗶哩 (゜-゜)つロ 幹杯~-bilibili
  3. wiki:https:// en.wikipedia.org/wiki/S uper_Mario_Bros .

還有其它很多參考,不好一一列舉,向這些作者表示感謝。