為拯救童年回憶,開(kāi)發(fā)者決定采用古法編程:用Flash高清重制了一款游戲
兩年多前,Adobe 發(fā)布了一則引人關(guān)注的公告 —— 將在 2020 年 12 月 31 日終止支持 Flash,宣告了一個(gè)時(shí)代的結(jié)束。
一晃兩年過(guò)去了,Adobe 早已從官方網(wǎng)站中刪除了 Flash Player 早期版本的所有存檔,并阻止基于 Flash 的內(nèi)容運(yùn)行。微軟也已經(jīng)終止對(duì) Adobe Flash Player 的支持,并禁止其在任何 Microsoft 瀏覽器上運(yùn)行。Adobe Flash Player 組件于 2021 年 7 月通過(guò) Windows 更新永久刪除。
當(dāng) Flash 下架之后,在世界的某個(gè)角落,這位「老同志」卻仍在發(fā)揮余熱。
Hapland 是 2005 年推出的一款 Flash 解謎游戲,也是很多人的童年回憶。在游戲中,玩家需要通過(guò)爭(zhēng)取這個(gè)世界中的人們的幫助,找到打開(kāi)關(guān)卡的方法,同時(shí)不要讓他們被怪物吃掉或被地雷炸死。
這款游戲的圖形要在 Flash 中繪制,代碼要在 Flash 中編寫(xiě),所有動(dòng)畫(huà)都在 Flash 時(shí)間軸中完成。可以這么理解:這款游戲的「骨子里都帶著 Flash」。
作為游戲開(kāi)發(fā)行業(yè)的一員,Robin Allen 發(fā)現(xiàn),人們似乎特別喜歡 Hapland 游戲,所以他想對(duì)這款基于 Flash 的游戲的 Steam 版本進(jìn)行一些修復(fù),包括繪制更好的圖形、將幀速率提高到 60FPS,并添加一些額外的「秘密」等等。
這時(shí)候該怎么做?作者詳細(xì)講述了試驗(yàn)過(guò)程。
一些失敗的經(jīng)驗(yàn)
失敗的嘗試 1:
我嘗試的第一件事是讓 Flash 將游戲?qū)С鰹榭蓤?zhí)行文件,但失敗了,因?yàn)樗男阅芘c 2005 年一樣糟糕。我想制作一個(gè)以當(dāng)代幀速率運(yùn)行的東西。我想擺脫 Flash Player。
失敗的嘗試 2:
其次,我花了太多時(shí)間擺弄 Adobe AIR(Flash 桌面 runtime)和 Starling(一個(gè)在 GPU 上繪制 Flash 場(chǎng)景的庫(kù))。
最后我放棄了這個(gè),部分原因是 AIR 有很多問(wèn)題而且很糟糕,也是因?yàn)槲也幌朐谝磺薪Y(jié)束時(shí)得到一個(gè)奇怪的 Adobe 結(jié)果;我想擁有自己的東西,可以做我想做的事。例如,如果我想遷移到 Linux 怎么辦?
前進(jìn)的道路是顯然的:我必須制作自己的 Flash 播放器。
計(jì)劃
以下是 Hapland 的運(yùn)作方式。這里有一棵精靈樹(shù),在 Flash 中,動(dòng)畫(huà)精靈可以將代碼附加到某些幀,當(dāng)播放箭頭到達(dá)那里時(shí)運(yùn)行。Hapland 經(jīng)常使用這一方式。游戲角色的行進(jìn)路徑都是很長(zhǎng)的時(shí)間軸動(dòng)畫(huà),角色經(jīng)常有幀動(dòng)作,比如門(mén)關(guān)了就打開(kāi),比如到了地雷區(qū),如果還沒(méi)爆炸就會(huì)觸發(fā)。
時(shí)間軸中的小 “a” 是幀動(dòng)作。
幸運(yùn)的是,.fla 文件只是 XML。我只需要解析它,將相關(guān)數(shù)據(jù)導(dǎo)出為簡(jiǎn)單的自定義格式并編寫(xiě)一個(gè)播放器來(lái)讀取它、繪制場(chǎng)景、處理輸入并運(yùn)行動(dòng)畫(huà)。
Hapland 仍然是一個(gè) Flash 項(xiàng)目,在 Flash 編輯器中編寫(xiě)和維護(hù);只有 Flash Player 會(huì)被替換。
光柵化矢量
Flash 確實(shí)支持光柵圖,但實(shí)際上是為矢量圖設(shè)計(jì)的。這就是 Flash 影片即使在撥號(hào)連接的情況下也能快速加載的原因。
所有 Hapland 圖形都是矢量圖。而 GPU 不太喜歡繪制矢量圖形,卻喜歡大批量的紋理三角形。所以,我需要將這些矢量光柵化。
我決定離線(xiàn)光柵化它們并將光柵文件打包到游戲中。在游戲運(yùn)行時(shí)將它們光柵化并成為這個(gè)微小的可執(zhí)行文件會(huì)很有趣,但我不想擁有那些額外的移動(dòng)部件。我喜歡讓盡可能多的代碼在自己的開(kāi)發(fā)機(jī)器上運(yùn)行,這樣我就可以隨時(shí)關(guān)注到它。
Flash 以 XML 格式存儲(chǔ)矢量圖。你可能會(huì)說(shuō), XML 不是圖形數(shù)據(jù)的一種糟糕選擇,但你畢竟不是 Macromedia 的產(chǎn)品經(jīng)理??纯催@個(gè):
在 .fla 文件中看到的矢量數(shù)據(jù)。
我不是在抱怨,這讓我的工作更輕松了。
盡管我無(wú)法訪(fǎng)問(wèn) spec,但光柵化這并不是一個(gè)難題。自 PostScript 以來(lái),矢量圖形的貝茲曲線(xiàn)模型無(wú)處不在。所有這些 API 的工作方式都相同。經(jīng)過(guò)反復(fù)試驗(yàn),我編寫(xiě)了一個(gè)程序來(lái)解析這些形狀定義,并使用 Mac 的 CoreGraphics 庫(kù)將它們呈現(xiàn)為 PNG。
CoreGraphics 是一個(gè)值得懷疑的選擇。我選擇它是因?yàn)槲沂褂?Mac 工作,依賴(lài)性很強(qiáng)。但這確實(shí)成功了,所以我總是不得不在 Mac 上光柵化圖形,即使是 Windows 版本也是如此。如果再一次做這件事,我可能會(huì)選擇一個(gè)跨平臺(tái)的庫(kù)。
渲染這些 PNG 后,導(dǎo)出器會(huì)將它們組裝成地圖集?并沒(méi)有,它只是按高度對(duì)所有內(nèi)容進(jìn)行排序,然后像文檔中的文本一樣逐行排列。這遠(yuǎn)非最佳,但已經(jīng)足夠了。
為簡(jiǎn)單起見(jiàn),圖集為 2048×2048 像素,這是 OpenGL 3.2 實(shí)現(xiàn)必須支持的最小紋理尺寸。
來(lái)自 Hapland 3 的圖例集。
光柵化形狀非常慢,所以為了保持合理的構(gòu)建時(shí)間,我需要跳過(guò)渲染沒(méi)有改變的東西。Flash 使用的壓縮 XML 格式確實(shí)有每個(gè)文件的最后修改字段,但 Flash 似乎沒(méi)有正確使用它們,因此您不能依賴(lài)它們。
相反,我只是對(duì)每個(gè)形狀的 XML 進(jìn)行哈希處理,并且只有在它發(fā)生變化時(shí)才進(jìn)行重建。即使這樣也失敗了,因?yàn)?Flash 有時(shí)喜歡重新排列未更改的對(duì)象中的 XML 標(biāo)記,但同樣,這已經(jīng)足夠了。
用匯編程序編寫(xiě)二進(jìn)制文件
導(dǎo)出器將動(dòng)畫(huà)數(shù)據(jù)寫(xiě)入自定義二進(jìn)制格式。它只是逐幀通過(guò)時(shí)間軸,并寫(xiě)出每一幀的所有更改。
我在這里想到了寫(xiě)入?yún)R編列表而不是直接寫(xiě)入二進(jìn)制文件,我很喜歡這一點(diǎn)。沒(méi)有 CPU 指令,只有數(shù)據(jù),這讓調(diào)試更容易,因?yàn)槲铱梢圆榭磪R編文件以查看生成的內(nèi)容,而不是在十六進(jìn)制編輯器中瀏覽字節(jié)。
輸出.bin
輸出.asm
你更愿意調(diào)試哪個(gè)?
我本可以讓導(dǎo)出器將字節(jié)寫(xiě)入一個(gè)文件,同時(shí)將單獨(dú)的文本列表寫(xiě)入另一個(gè)文件,而不使用匯編程序,但我沒(méi)有這樣做,因?yàn)椋?/span>
1) 匯編程序已經(jīng)存在;
2) 我不是必須調(diào)試它們;
3) 它們支持標(biāo)簽。
導(dǎo)出器的其余部分大多不夠有趣;它只是 walk the tree 并將變換矩陣、顏色效果等事物,然后繼續(xù)游戲程序本身。我選擇用 C++ 編寫(xiě)這個(gè),因?yàn)槲乙呀?jīng)知道它,并且新事物讓我害怕。
場(chǎng)景圖
Hapland 非常適合場(chǎng)景圖。這是 Flash 使用的模型,Hapland 就是圍繞它設(shè)計(jì)的,因此嘗試使用不同的模型是沒(méi)有意義的。
我將場(chǎng)景存儲(chǔ)在內(nèi)存中,作為一棵節(jié)點(diǎn)樹(shù),每個(gè)節(jié)點(diǎn)都有一個(gè)變換,可以自行繪制并接受鼠標(biāo)點(diǎn)擊。每個(gè)具有自己行為的游戲?qū)ο蠖际瞧渥约侯?lèi)的實(shí)例,派生自 Node.js?!该嫦?qū)ο蟆鼓壳霸谟螒蜷_(kāi)發(fā)圈子里并不流行,但我使用的是 Flash,所以顯然不關(guān)心這個(gè)問(wèn)題。
Hapland 使用的 Flash 功能,如顏色變換和遮罩,都是存在的。不過(guò)我沒(méi)有像 Flash 那樣實(shí)現(xiàn)任意遮罩,只是實(shí)現(xiàn)了矩形剪輯并編輯了我所有的圖形,所以所有的遮罩都是矩形。
框架腳本
幾乎所有的 Hapland 邏輯都包含在附加到時(shí)間軸幀的 ActionScript 中。要如何導(dǎo)出所有這些東西?我可不想在我的游戲中包含 ActionScript 解釋器。
一個(gè)簡(jiǎn)單的幀動(dòng)作。
最后,我們使用了一些技巧,我的導(dǎo)出器從每一幀讀取 ActionScript 并應(yīng)用大量正則表達(dá)式以嘗試將其轉(zhuǎn)換為 C++。例如,crate.lid.play () 可能會(huì)變成 crate ()→lid ()→play ();。這兩種語(yǔ)言在句法上非常相似,這對(duì)于許多更簡(jiǎn)單的框架動(dòng)作來(lái)說(shuō)效果很好,但它仍然留下了相當(dāng)多的錯(cuò)誤代碼,除了手動(dòng)重寫(xiě)所有剩余的框架動(dòng)作之外別無(wú)他法。
對(duì)于 C++ 中的所有框架腳本,它們?cè)跇?gòu)建時(shí)被提取并成為每個(gè)符號(hào)的 Node 子類(lèi)上的方法。還會(huì)生成一個(gè)調(diào)度方法以在正確的時(shí)間調(diào)用,看起來(lái)像這樣:
需要指出的最后一件事是腳本系統(tǒng)最終是某種靜態(tài)類(lèi)型的,這有點(diǎn)難受。游戲輸出的最終游戲?qū)ο笕缦滤荆?/span>
因此,即使一切仍然是大量的自動(dòng)字符串名稱(chēng)查找,類(lèi)型安全的單板會(huì)阻止你在錯(cuò)誤的對(duì)象上調(diào)用錯(cuò)誤的函數(shù),從而使你免于在動(dòng)態(tài)語(yǔ)言中遇到的那類(lèi)煩人的 bug。
縱橫比
HD 重置版游戲都會(huì)遇到畫(huà)面拉伸的問(wèn)題,最初的 Flash 游戲很多是頁(yè)游,甚至沒(méi)有全屏運(yùn)行的能力,所以它們只是使用設(shè)計(jì)者喜歡的寬高比,大多是 3:2 左右。
如今最常見(jiàn)的縱橫比似乎是 16:9,16:10 在筆記本電腦上也很流行。我希望游戲在其中任何一個(gè)方面看起來(lái)都不錯(cuò),沒(méi)有任何黑條或拉伸。要做到這一點(diǎn)的唯一方法是從原件上切掉一些部分,或者在上面添加一些部分。
所以,我為游戲畫(huà)面畫(huà)了兩個(gè)矩形,一個(gè)比例為 16:9,另一個(gè)比例為 16:10。然后游戲根據(jù)屏幕的寬高比在它們之間進(jìn)行插值,并使用插值矩形作為視圖邊界。只要所有重要的游戲元素都在這些矩形的交叉點(diǎn)內(nèi),并且它們的公共邊界矩形不超出場(chǎng)景邊緣,就可以很好地工作。
Hapland 2 的 16:10 和 16:9 框,與原來(lái)的 3:2 不同。
色彩空間的問(wèn)題
經(jīng)過(guò)一些測(cè)試后,我發(fā)現(xiàn) Flash 在感知空間而不是線(xiàn)性空間中進(jìn)行 alpha 混合和顏色變換。這在數(shù)學(xué)上是可疑的,但另一方面我們也該知道,很多繪圖程序都是這樣工作的,你希望你的消費(fèi)級(jí)工具按照人們期望的方式工作,雖然這對(duì)于數(shù)學(xué)家來(lái)說(shuō)是一種冒犯。但是從根本上來(lái)看,這是錯(cuò)誤的!它會(huì)導(dǎo)致諸如抗鋸齒之類(lèi)的問(wèn)題。
當(dāng)你光柵化矢量圖形并要求抗鋸齒輸出時(shí),光柵器將輸出 alpha 值,即所謂的「覆蓋值」。這意味著如果給定像素被矢量形狀半覆蓋,則該像素將以 alpha = 0.5 輸出。
但在 Flash 中,當(dāng)某些東西的 alpha 為 0.5 時(shí),這意味著它在感知上處于前景色和背景色之間的中間位置。
這完全不是一回事!
在不透明黑色像素之上繪制的半覆蓋白色像素不應(yīng)是感知的 50% 灰色。這不是光的工作原理,也不是矢量光柵化的工作原理。光柵器不能在不知道背景顏色的情況下說(shuō)「這個(gè)像素應(yīng)該在背景和前景顏色之間感知 xx%」。
在感知 (sRGB) 空間中完成的混合。頂部:黑色透明白色;中間:白底透明黑色;底部:灰色在線(xiàn)性(物理上準(zhǔn)確)空間中完成的相同混合。請(qǐng)注意,50% 的覆蓋率看起來(lái)與 50% 的灰色不同。
因此,我們的抗鋸齒光柵化形狀使用一種 alpha 定義,而我們的 Flash 導(dǎo)出的 alpha 透明度、漸變和顏色變換使用另一種定義。但是我們的渲染管道中只有一個(gè) alpha 通道。那么渲染器應(yīng)該如何解釋 alpha 值呢?如果它將它們解釋為感知混合因素,則半透明對(duì)象看起來(lái)是正確的,但一切的抗鋸齒邊緣看起來(lái)都是錯(cuò)誤的。如果它將它們解釋為覆蓋率值,則反之亦然。有些東西總是看起來(lái)不對(duì)勁!
在此,我認(rèn)為只有兩個(gè)嚴(yán)謹(jǐn)?shù)慕鉀Q方案:1) 設(shè)定兩個(gè) alpha 通道,一個(gè)用于覆蓋,一個(gè)用于感知混合;2) 在沒(méi)有 AA 的情況下光柵化所有形狀,將所有內(nèi)容繪制到一個(gè)非常大的幀緩沖區(qū),然后通過(guò)過(guò)濾將其縮小。
我必須承認(rèn),這些設(shè)想都沒(méi)有獲得實(shí)踐。這些半透明的東西在 Flash 和游戲中看起來(lái)不對(duì)勁,我只是逐漸調(diào)整圖形直到游戲看起來(lái)沒(méi)問(wèn)題。在 Flash 中的透明對(duì)象永遠(yuǎn)不會(huì)完全符合我設(shè)計(jì)他們的初衷,但它們并不多,這也不是什么大問(wèn)題。
為了確保其他一切都正確,我制作了一個(gè)「顏色測(cè)試」圖形,其中包含一堆不同強(qiáng)度的顏色、色調(diào)旋轉(zhuǎn)效果 10 等等,讓游戲顯示它,并確保它在 Flash 中運(yùn)行正確。
變成了比較顏色的問(wèn)題。
幀率
原始的 Flash 游戲標(biāo)稱(chēng)幀率是 24FPS,但實(shí)際上它們以 Flash Player 想要的任何幀速率運(yùn)行。使用 Flash,你可能要求 24FPS 并得到 15FPS,或者要求 30FPS 突然得到 24FPS,這看起來(lái)一點(diǎn)也不嚴(yán)謹(jǐn)。
我想要把游戲重制成 60FPS,這意味著要在 Hapland 創(chuàng)作時(shí)期望以大約 24FPS 的速度播放這一事實(shí)動(dòng)些手腳。Flash 的動(dòng)畫(huà)工具基于離散的幀,而不是連續(xù)的時(shí)間。
我首先讓導(dǎo)出器將所有幀加倍,對(duì)于每個(gè)時(shí)間軸幀導(dǎo)出兩個(gè)幀,這就直接地把 24FPS 提高到了 48FPS,但仍然不是 60,需要的動(dòng)畫(huà)仍然要快 25%。解決方法是老式的手工活:完整遍歷游戲,然后手動(dòng)將額外的幀添加到現(xiàn)在看起來(lái)太快的動(dòng)畫(huà)中。
至此,我們已對(duì) Hapland 游戲進(jìn)行了相當(dāng)不錯(cuò)的 C++ 轉(zhuǎn)換,肯定可以在現(xiàn)代計(jì)算機(jī)上運(yùn)行至少再過(guò)一兩年。但我就是無(wú)法擺脫應(yīng)該嘗試提供一些額外價(jià)值的感覺(jué),所以加新活在所難免。除了重新繪制大量舊圖形和動(dòng)畫(huà)外,我還進(jìn)行了一些重大更改。
及時(shí)保存
我認(rèn)為需要讓 Hapland 3 不那么讓人不知所措。這個(gè)游戲的關(guān)卡很長(zhǎng),有很多地方死掉了又得重新再來(lái),也許這在 2006 年很有趣,但我們現(xiàn)在是成年人了,我們沒(méi)有時(shí)間這樣做。
保存狀態(tài)是模擬器該有的功能,如果你按下「保存狀態(tài)」,它會(huì)通過(guò)將控制臺(tái)的內(nèi)存轉(zhuǎn)儲(chǔ)到文件中來(lái)記錄當(dāng)前游戲的整個(gè)狀態(tài)。然后,如果你搞砸了,按下「加載狀態(tài)」,你就會(huì)回到要重試的地方附近。
在原始 Flash 游戲中實(shí)現(xiàn)保存狀態(tài)是不可行的,因?yàn)?Flash 不讓程序員訪(fǎng)問(wèn)其整個(gè)狀態(tài)。但由于這次我使用的都是自己的代碼,所以這是可能的。
我有一個(gè)叫做 Zone 的東西,它只是一個(gè)分配器,將其所有內(nèi)存分配到一個(gè)固定大小的塊中。所有場(chǎng)景節(jié)點(diǎn)都分配在當(dāng)前區(qū)域內(nèi)。為了實(shí)現(xiàn)保存和恢復(fù),我只需要兩個(gè)區(qū)域,活動(dòng)區(qū)域和一個(gè)單獨(dú)的「保存狀態(tài)區(qū)域」。為了保存狀態(tài),我將活動(dòng)區(qū)域 memcpy 到保存狀態(tài)區(qū)域。要加載狀態(tài),我會(huì)以另一種方式返回 memcpy。
重復(fù)關(guān)卡
Hapland 的游戲時(shí)間并不是特別長(zhǎng),雖然一共有三個(gè),但我們總是希望再想多給玩家?guī)讉€(gè)小時(shí)的游戲時(shí)間。因此我決定給每個(gè)游戲一個(gè)「Second Quest」—— 原關(guān)卡修改版,布局和謎題略有不同。制作這樣一個(gè) Second Quest 比制作一個(gè)全新的游戲要省力,但仍能帶來(lái)一些額外的價(jià)值。
創(chuàng)建 Second Quest 意味著我需要在大約 15 年來(lái)第一次重新開(kāi)始 Flash 解謎游戲開(kāi)發(fā),老實(shí)說(shuō),這感覺(jué)不錯(cuò)。復(fù)古的 Flash 用戶(hù)界面很棒,按鈕都有邊緣,圖標(biāo)是實(shí)物風(fēng)格,空間也得到了充分的利用。
使用舊時(shí)代的 UI 讓我感覺(jué)自己就像一位考古學(xué)家,正在發(fā)現(xiàn)某種被遺忘的羅馬技術(shù)。失落的 UI 設(shè)計(jì)藝術(shù),很整潔。
這是什么魔法?
盡管 Flash 的 bug 很多,速度也慢,還缺少一些極其基本的功能,但我基本上不討厭使用它,當(dāng)然使用現(xiàn)代應(yīng)用程序是更順手的。
為了防止第二個(gè)任務(wù)看起來(lái)與第一個(gè)任務(wù)太相似,它們需要有新的背景,整個(gè)場(chǎng)景也被水平翻轉(zhuǎn)了。
Hapland 3。
Hapland 3 的 Second Quest。
音樂(lè)
在 BGM 方面,我使用自己硬盤(pán)里的內(nèi)容,并額外制作了一些音樂(lè),為每款游戲制作了快速的環(huán)境配樂(lè)。有一次在日本度假時(shí),我無(wú)緣無(wú)故地在山頂上進(jìn)行了一次野外錄音,能夠?qū)⑵溆糜谀承┦虑檎媸翘昧?。我從互?lián)網(wǎng)上找到了一位音樂(lè)家來(lái)做標(biāo)題屏幕音樂(lè),并自己錄制了一些吉他和弦作為片尾字幕,它們淹沒(méi)在效果中,所以你不能說(shuō)我吉他學(xué)得不好。
在工具上,我根據(jù)音樂(lè)使用 Logic 或 Live。我發(fā)現(xiàn) Logic 更適合錄音,而 Live 更適合聲音設(shè)計(jì)。
成就系統(tǒng)
在 Steam 上,玩家總喜歡看成就,這一點(diǎn)不太好辦,成就的設(shè)置取決于游戲設(shè)計(jì)師的思路,但其實(shí)也沒(méi)什么大不了的。
把成就系統(tǒng)上傳到 Steam 是一件痛苦的事情,你不能只定義一個(gè)列表并將其提供給他們的命令行工具,而是必須費(fèi)力地點(diǎn)擊 Steam 合作伙伴網(wǎng)站緩慢、令人困惑的 PHP 框架,然后將它們一個(gè)一個(gè)添加進(jìn)去。
看起來(lái),如果你是一家重要的大型游戲工作室,你就不必忍受這一點(diǎn),他們?yōu)槟闾峁┝艘粋€(gè)批量上傳工具,但我顯然不是其中之一。所以我查看了它構(gòu)建的 HTTP 調(diào)用,保存了我的登陸 cookie,并編寫(xiě)了我自己的文件。
幾次修改之后,我選擇了一組適度的成就:一個(gè)用于完成每個(gè) Hapland 游戲,一個(gè)用于每個(gè) Second Quest,還有兩個(gè)是解鎖更大的秘密。任何沒(méi)人能發(fā)現(xiàn)的愚蠢、晦澀的秘密都沒(méi)有成就,你一定要對(duì)發(fā)生的事情感到滿(mǎn)意。
Steamworks UI 下的成就系統(tǒng)。
Notarization 的問(wèn)題
雖然我主要是在自己的 Mac 上開(kāi)發(fā)游戲,但在開(kāi)發(fā)的過(guò)程中蘋(píng)果發(fā)明了「Notarization」,如果你在新版本的 MacOS 上運(yùn)行任何應(yīng)用程序,它會(huì)向蘋(píng)果發(fā)出網(wǎng)絡(luò)請(qǐng)求,詢(xún)問(wèn)應(yīng)用程序的開(kāi)發(fā)者是否向蘋(píng)果支付年費(fèi)。如果開(kāi)發(fā)者不支付年費(fèi),MacOS 會(huì)彈出一個(gè)對(duì)話(huà)框,強(qiáng)烈暗示該應(yīng)用程序是壞的并拒絕啟動(dòng)。
因此,Windows 將是該游戲的第一個(gè),也許是唯一的發(fā)布平臺(tái)。
使用的庫(kù)
對(duì)于最終交付給最終用戶(hù)的軟件,我們通常希望將依賴(lài)性保持在最低限度,但使用一些高質(zhì)量的軟件也是必要的。除了 OpenGL 和標(biāo)準(zhǔn)操作系統(tǒng)之外,這是 Hapland Trilogy 可執(zhí)行文件最終鏈接到的完整庫(kù)列表:
- Steam SDK
- cute_sound
- stb_vorbis
- stb_image
結(jié)語(yǔ)
就是這樣,如果你把技術(shù)做對(duì)了,人們?cè)诖蛴螒驎r(shí)根本不會(huì)注意到背后是什么,所以有時(shí)候這會(huì)讓你想說(shuō):嘿,看看我做到了什么!