<ruby id="9ue20"></ruby>

  1. 
    

      国产午夜福利免费入口,国产日韩综合av在线,精品久久人人妻人人做精品,蜜臀av一区二区三区精品,亚洲欧美中文日韩在线v日本,人妻av中文字幕无码专区 ,亚洲精品国产av一区二区,久久精品国产清自在天天线
      網易首頁 > 網易號 > 正文 申請入駐

      Kenta Cho小游戲開發教程

      0
      分享至


      字數 24601,閱讀大約需 124 分鐘

      小游戲開發之樂
      原文:Joys of Small Game Development[1] by ABA Games 許可協議:CC BY 4.0[2]
      引言

      游戲開發是一片展現創造力的沃土。尤其是小游戲,制作簡單、即玩即樂,讓人能夠迅速沉浸于其中。本文旨在深入探討制作小游戲的樂趣。

      在《制作小游戲本身就是一種樂趣》一節中,將探討什么是小游戲以及為什么制作它們令人愉快。開發小游戲不僅僅是通往更大項目的練兵場,它本身就具有獨特的魅力。

      當你著手制作一款小游戲時,選擇使用哪種編程語言或游戲引擎是第一道門檻。在《目標設備與開發環境》一節中,我匯總了相關的信息。

      構思核心創意是小游戲創作中的關鍵。《如何為小游戲想點子》一節提供了頭腦風暴的技巧。此外,在《約束:激發創意與完成游戲的催化劑》中,討論了通過對游戲輸入方式或分辨率施加約束來催生更好創意的方法。

      在小游戲中,隨著游戲推進逐漸提升難度是常見做法。《小游戲中什么才是合適的難度》探討了如何設置讓玩家感到適度挑戰的難度水平。

      沒有調味料的游戲是索然無味的。在《讓游戲"多汁"》中,圍繞"juicy"(多汁)這一概念,介紹了通過添加效果和音效來豐富游戲的方法。

      在《打造自己的游戲開發工具》中,敘述延伸到在制作游戲的同時創建自定義庫或游戲引擎。雖然為游戲打造工具非常有趣,但這也是一把雙刃劍——陷得太深可能會阻礙游戲的完成。

      為了快速制作小游戲,有一種自動生成圖形和聲音的方法。《通過自動化提升開發效率》介紹了讓計算機生成像素畫、背景音樂、音效和關卡的方式。

      如果計算機能夠創作游戲,將進一步減輕人類的負擔。《小游戲能否自我生成?》探討了計算機從零開始開發游戲的可能性,重點關注 AI 聊天機器人的應用。

      我在本文中編織了關于小游戲開發的諸多話題。通過這些敘述,希望讀者能感受到小游戲開發的魅力,也希望這能成為更多人拿起挑戰創造之筆的契機。

      • ? 許可協議:CC BY 4.0[2]
      • ? 倉庫:joys-of-small-game-development-en[3]
      • ? 本文首頁:Introduction - Joys of Small Game Development[1]
      • ? 作者主頁:ABA Games[4]
      制作小游戲本身就是一種樂趣

      制作小游戲本身就是一件令人愉悅的事情。那么,什么是小游戲呢?根據"小游戲宣言"(Small Games Manifesto)[^1],它指的是在 10 分鐘內即可完成、并且可以在瀏覽器中輕松游玩的游戲。

      按照這個定義,我已經創作了超過 350 款小游戲。[^2] 其中有一年我制作了 139 款小游戲,[^3] 可見我對小游戲的熱愛毋庸置疑。

      舉個例子,一款讓你把紅色棍子切成等份的簡單游戲,就是小游戲的典型代表(點擊下圖可直接在瀏覽器中游玩)。


      TIMBER TEST [5]

      另一個例子是一款通過點擊來剪斷繩子的游戲,需要確保繩子不碰到屏幕底部——這也是一款小游戲,在智能手機等觸屏設備上游玩體驗極佳。


      C NODES [6]

      小游戲吸引人的魅力在于它們所需的開發時間極短。一款游戲大約可以在 2 小時內快速完成,即使遇到困難,10 小時左右也差不多了。不過,一旦開始深入美術資源的制作,時間投入就可能變得沒有盡頭。本文所討論的小游戲,是在"一周一游戲"(Game A Week)[^4] 等活動框架下制作的游戲,開發者的目標是每周制作一款新游戲。這些游戲從開發者的角度來看也是"小型"的,因為它們的開發時間非常有限。

      開發時間短意味著你可以輕松地嘗試各種創意。我很享受構思和測試那些不落俗套的游戲。

      關于小游戲的普遍說法是,制作它們是開發更大、更精致游戲的重要準備步驟。許多文章極力建議初學者從小游戲開始。

      一篇題為"Make and release lots of small games before making a big one"(先做很多小游戲再做大的)[^5] 的博客文章強調了在進行大型項目之前這種實踐的重要性。

      之所以這樣說,是因為直接跳到大型游戲作為你的"第一個"游戲,恰恰是讓你喪失動力、永遠無法完成它的原因,或者最終得到的成果吞噬了你好幾年的生命,而你甚至無法忍受再看到它。

      但故事并沒有到此為止。小游戲擁有它們獨有的、無法被替代的魅力。這是我深信不疑的。

      有一篇題為"How To Make Good Small Games"(如何制作優秀的小游戲)[^6] 的博客文章,闡述了優秀的小游戲確實存在,并詳細說明了如何制作它們。

      這份類似宣言的文檔"How To Make Good Small Games"(如何制作優秀的小游戲),試圖與這種觀點尋求一個折中。它分為十二條思考,主要由一些深邃的創作理論組成(為什么我喜歡小游戲?為什么我喜歡制作小游戲?),同時也希望提供一些切實可行的建議。我可以告訴你"把范圍縮小 uwu",但如果你根本不相信小游戲也能做到優秀,那你聽到的只不過是在制作你真正在意的游戲之前不得不完成的作業。

      這 12 條思考涵蓋以下內容:

      1. 1. 游戲的品質與其規模無關。小游戲不僅容易制作,也容易做好。游戲越大,需要關注的方面就越多,失敗的概率也越高。
      2. 2. 游戲的品質與其情感范圍無關。正如短篇小說與長篇小說或史詩的功能不同,構成"成功"的條件在小規模游戲中也各不相同。
      3. 3. 游戲定義了自身成功的標準。接受它們本來的樣子,再評判它是好是壞。
      4. 4. 游戲在兌現承諾時就是成功的。引入新角色或新機制就是一種承諾。與其引入一個有趣的創意然后迅速拋棄,不如確保它不斷進化,并為游戲的整體進程做出貢獻。
      5. 5. 游戲做出更小的承諾,就更容易成功。減少機制、敵人、資源、角色和關卡。引入 3 個創意并將它們發展到令人滿意的高潮,比同時應對 10 個或 100 個創意要容易得多。
      6. 6. 以有趣且令人愉悅的方式兌現承諾。什么能讓你微笑?這就是你的個人風格在制作一款真正屬于"你"的游戲時閃耀的地方。
      7. 7. 不要過度兌現你的承諾。游戲應該在恰當的時刻結束,而不是不必要地拖長。
      8. 8. 形式也是游戲承諾的一部分。盡量減少向玩家呈現的信息,確保玩家在游戲啟動后就能立即開始游玩,從而改變玩家的預期。
      9. 9. 在發布前完成你的游戲。在以"Demo"(演示版)的標簽發布或添加"Prologue"(序章)副標題之前,先問問自己為什么要在完成之前發布它。
      10. 10. 系列化不是捷徑。將游戲分成兩集或更多,在較長時間內陸續發布,幾乎總是一個壞主意。
      11. 11. 不要擔心能不能爆紅。在游戲中追求小而具體的目標,吸引的也是小而特定的受眾。
      12. 12. 夠好就是好。一旦你能持續創作出令自己滿意、感覺確實不錯的游戲,你就已經領先于許許多多的游戲開發者了。

      此外,該文章還提出了第 13 條思考:"Have fun :)"(享受其中)。構思新的機制,并以體現你個人風格的方式將其融入游戲。我認為這個過程本身就是令人愉悅的,如果能有一定數量的人體驗并享受我創作的成果,那就更令人欣慰了。

      制作小游戲通常在磨練游戲開發技能的語境下被討論。然而,頭腦風暴各種游戲創意、不斷實驗、在興奮與沮喪間坐過山車、偶爾向他人展示你的作品——這個過程本身就很快樂,這也是一段寶貴的體驗。

      小游戲應在 10 分鐘或更短時間內完成,最好能在網絡瀏覽器中游玩。
      目標設備與開發環境

      當你考慮制作一款小游戲時,首先需要思考的問題之一就是游戲將運行在什么設備上——PC、智能手機還是游戲主機。

      如果你沒有特別的偏好,推薦為 PC 網頁瀏覽器制作游戲。現代瀏覽器已經成熟為能夠運行在各種開發環境下開發的游戲的平臺。而且讓別人游玩你的游戲也很方便——只需發布一個 URL 就能實現無縫的游戲體驗。

      對于享受游戲制作過程的人來說,開發環境、編程語言和游戲引擎的選擇可以源于個人喜好。這與游戲的規模并沒有太大關系,選擇你喜歡的就好。不過,如果你的目標是小型 2D 游戲,像 Unreal Engine [^7] 這樣的引擎可能有些大材小用了。

      為瀏覽器制作游戲時,有各種開發選項可供選擇:

      • JavaScript

      在瀏覽器中運行的游戲是用 JavaScript 編寫的,這使得它成為游戲開發的自然之選。利用 p5.js [^8] 或 Phaser [^9] 等庫可以簡化渲染等繁瑣任務。使用 p5.js,初學者可以立即通過學習內容 [^10] 或參考文檔 [^11],在網頁編輯器 [^12] 中跟著操作。

      • 幻想主機(Fantasy Consoles)

      幻想主機是輕量級游戲引擎,集成了游戲執行和開發環境,包括角色、關卡和聲音編輯器。代表性的有 PICO-8、[^13] Pyxel、[^14] 和 TIC-80。[^15] 這些一體化環境有意限制了功能,非常適合小游戲項目。它們支持不同的編程語言,找到適合你偏好的即可。如果你想嘗試 PICO-8,可以參考手冊 [^16] 或 API 參考 [^17],同時使用教育版。[^18]

      • 游戲引擎

      許多游戲引擎如 Unity、[^19] GameMaker、[^20] 和 Godot [^21] 支持將游戲導出為瀏覽器(HTML5)格式,使在瀏覽器上游玩所創建的游戲變得輕而易舉。它們提供全面的資源管理功能,并且不僅能將游戲發布在瀏覽器上,還可以發布在 PC 和移動平臺上,這是顯著的優勢。

      • 制作工具(Maker Tools)

      如果你想制作 RPG 或視覺小說,有專門的類型化工具可用。例如 RPG Maker MV [^22] 在這個類別中一直很受歡迎,這類工具傳統上被稱為"Maker"(制作工具)。除了 RPG Maker 之外,還有用于 RPG 的 WOLF RPG Editor [^23] 以及用于視覺小說的 TyranoBuilder Visual Novel Studio。[^24] 許多近年的制作工具都包含了瀏覽器導出功能。

      • 可視化編程語言

      對于不習慣基于文本編程的人,可以使用 Scratch [^25] 或 MakeCode [^26] 等可視化編程語言。雖然制作復雜游戲可能有些困難,但它們內置了預制好的圖形和聲音,適合小型項目。

      • 其他編程語言

      現代瀏覽器可以通過 WebAssembly [^27] 等技術運行 JavaScript 以外的語言。不過編譯過程可能比較復雜,所以如果可以的話,利用幻想主機或游戲引擎會更方便。例如,用 Pyxel 來寫 Python,或用 Unity 來寫 C#。

      為瀏覽器制作游戲時,確保你的游戲支持觸摸操作(或 PC 上的鼠標操作),這樣就能兼容移動設備。如果你想觸達更廣泛的受眾,這一點值得考慮。

      從游戲制作體驗本身獲得的樂趣并不一定需要面向瀏覽器的方法。為 PC 或移動設備制作應用,或者使用 SmileBASIC 4 [^28] 在 Switch 上創作游戲,也是不錯的選擇。用 MakeCode 制作的游戲可以在你喜歡的掌機上玩,[^29] 有些人甚至在上面運行 PICO-8 游戲。[^30]

      創作的動力不必僅僅來源于"讓更多人方便游玩"的愿望——對某個特定設備的興趣本身也可以成為動力。讓我們自由地創作吧。

      如何為小游戲想點子

      為小游戲構思創意既是有趣的,也是充滿挑戰的。現在我準備好制作一款小游戲了,但問題是:我應該做什么類型的游戲?

      構思階段令人興奮,但也需要付出相當的努力。一個好的創意能推動制作順利前進,而一個平庸的創意則可能讓道路坎坷不平。不過,對于小游戲來說,如果一個想法行不通,直接丟掉就好了。

      網上有許多關于游戲創意生成的文章,粗略搜索一下,找到一種適合你的方法即可。例如,我在 Reddit 的 r/gamedev 上一個題為"How do you guys come up with ideas for your games?"(你們怎么想出游戲點子的?)[^31] 的帖子中找到了一種很有說服力的方法。

      1. 1. 從你最喜歡的現有游戲中汲取靈感。
      2. 2. 將看似不搭的元素組合在一起,比如卡牌游戲 + 釣魚、塔防 + Minecraft,或者 Pac-Man 變成 FPS。
      3. 3. 分析其他游戲,思考它們的開發過程。如果是你,你會怎么做得不同?
      4. 4. 將你的創意縮小到一個切實可行的子集。聚焦在"你想做的"和"你能做的"的交集上。
      5. 5. 擁抱限制。從你的創意中剝離各種復雜性,在過程中創造新的東西。

      組合、提煉和增強現有游戲的元素來創造新事物——這個經過驗證的過程對于小游戲尤其有用,它通過將元素極致簡化來幫助打造具有引人入勝核心機制的游戲。

      GameMaker 網站上一篇題為"14 WAYS TO GENERATE S-TIER VIDEO GAME IDEAS"(14 種產生頂級游戲創意的方法)[^32] 的文章也提供了有見地的建議。提取與小游戲相關的要點如下:

      • ? 游玩過去的傳奇游戲。例如,當你玩 Super Mario Brothers 時,你正在體驗一款為所有未來 2D 平臺游戲奠定基礎的游戲。你會如何為新玩家擴展和現代化這個基礎?
      • ? 從零開始憑空構想一個游戲概念是困難的。先選擇一個類型,圍繞它構建你的創意。
      • ? 如果執著于某個類型很困難,就聚焦于一個角色。利用角色的特征來展開圍繞他們的世界。
      • ? 使用思維導圖記錄創意。從游戲的核心方面(如類型或主角)出發,記下相關的關鍵詞和想法,探索玩法機制、功能、故事主題和美術風格。
      • ? 靈感可能在意想不到的時刻閃現。手邊備一個記事本,全天隨時記錄涌現的想法。
      • ? 對現有游戲運用 SCAMPER 方法,思考哪些方面可以替換、組合、添加、修改、消除或重新排列,或者某個方面能否用于其他用途或反轉。
      • ? 將目光轉向其他媒體。電視、電影、音樂、書籍、傳統藝術——它們都能點燃游戲創意。
      • ? 從現實世界中汲取靈感。現實世界充滿了值得用于游戲開發的驚人概念。
      • ? 利用你自己的經歷。你以一種獨特的方式看到了這個世界——無論正面還是負面——這些經歷可以成為絕佳游戲創意的基礎,展開只有你才能講述的故事。
      • ? 使用隨機顯示游戲類型、規則和主題的游戲創意生成器。
      • ? 參加有主題的游戲 Jam。它們是有設定主題和嚴格截止日期的短期游戲開發比賽,能磨練你的專注力并激發創造力。
      • ? 深入游戲社區,直接詢問玩家。瀏覽帖子、提出問題,了解玩家想要什么、喜歡什么、不喜歡什么。

      這是一份涵蓋了激發創意的技巧和日常習慣的全面清單。雖然小游戲可能不需要如此大量的努力,但在構思時記住這些方法會有所幫助。

      讓我分享一些我個人在創意生成方面采用的方法。

      在我大量制作小游戲的那段時期,我在博客上寫了一些方法,取材自受歡迎游戲的特點和我在構思方面的經驗。這些方法包括:

      • ? 高效地從現有游戲中借鑒主題和規則,不僅限于電子游戲,還可以考慮傳統體育運動。
      • ? 從復古游戲中獲取靈感,將復古游戲的一部分重新打造成獨立的游戲。
      • ? 融入連鎖反應和重力等經典機制。
      • ? 以收集和擊敗對象所獲得的高分作為享受游戲的基礎。
      • ? 將自然現象或幾何學中的有趣行為進行轉譯。
      • ? 將物理行為與控制聯系起來以產生樂趣。
      • ? 在視覺上標示成功的操作,以增強成就感。
      • ? 基于限制(如單按鈕控制)設計互動方式。
      • ? 始終考慮風險與回報之間的平衡。
      • ? 風險驅動的開發:從向玩家呈現的風險角度來思考新的機制。
      • ? 平衡爽快感與緊張感。
      • ? 尋找提升游戲節奏的規則。
      • ? 呈現游戲設定或背景故事,將游戲與敘事聯系起來。
      • ? 通過去除讓玩家困惑的新奇元素來使游戲更易上手。

      我創造了一個類似老虎機的工具術語,用于隨機輸出游戲創作的主題——游戲創意生成器。[^33] 雖然它是獲取構思起點的不錯工具,但對于小游戲來說,它的建議往往過于模糊。因此,我制作了一個專門針對小型動作游戲的游戲創意生成器。[^34] 它會輸出諸如"deflect missiles"(偏轉導彈)、"roofs fighting"(屋頂戰斗)或"enlarge electricity"(放大電力)等天馬行空的創意,當這些創意被開發成游戲時,可能會產生創新性的成果。

      頭腦風暴游戲創意有各種技巧,利用前人的智慧可以加速這個過程。然而,最好的方法是創造性地思考和大量地創作。幸運的是,對于小游戲來說,構思和實現創意都可以迅速完成。如果一個想法失敗了,直接丟掉就好。以這種輕松的心態,何不試一試呢?

      解構與組裝游戲機制

      構思游戲創意的一種方式是理解先前創作的游戲背后的機制。分析這些機制如何為玩家提供樂趣和挑戰,可以提供一種系統化的方法。通過組合這些機制,可以創造出新的游戲。

      例如,我對迄今為止制作的游戲進行了解構。我整理了每款游戲由玩家角色、武器、障礙物、場地、規則和控制組成的方式,并用標簽進行了分類 [^35](點擊圖片進入首頁)。


      action-mini-game mechanic tags [7]

      按下每個標簽的"Detail"(詳情)按鈕后,可以查看該標簽的說明以及帶有該標簽的游戲列表。

      標簽對應各種機制,例如:

      • ? 玩家角色旋轉 [^36]:配合旋轉時機進行操作。
      • ? 武器沿拋物線飛行 [^37]:投擲方式、投擲物和落地效果各有變化。
      • ? 混入帶有懲罰的物品 [^38]:不能盲目持續攻擊,需要仔細觀察屏幕狀況來把握攻擊時機。
      • ? 一維場地 [^39]:游戲畫面可以用一個維度來表示,角色只能左右(或上下)移動。
      • ? 鄰近獎勵 [^40]:通過在障礙物附近放置獎勵分數,實現風險與回報的基本形式。
      • ? 按鈕按下時屬性反轉 [^41]:通過設計屬性可以實現各種特殊行為。

      這些頁面的使用方式如下:

      • ? 查看標簽列表頁面,了解可以整合到動作小游戲中的機制。
      • ? 查看標簽詳情頁面,考慮使用該機制的其他游戲。
      • ? 任意組合多個標簽,構思使用這些機制的游戲概念。

      這類游戲機制通常被稱為游戲機制(game mechanics)。[^42] 游戲機制指的是玩家在游戲中可以執行的有序動作,以及這些動作所觸發的事件。游戲機制被用來分析游戲的設計方式,或在構思新游戲時作為輔助。玩法通常被描述為游戲機制之間的流轉,[^43] 基于這些機制,可以通過思考如何挑戰玩家來塑造游戲體驗。

      識別游戲機制的粒度水平似乎沒有特定的標準。雖然回合制、資源管理和風險與回報等抽象元素可以列為機制,但更精細的游戲內動作——如跳躍、格擋、旋轉和強化——也可以列為機制。

      這一次,為了輔助構思新的動作小游戲,整理工作聚焦于更精細的游戲內動作。重點是查看每個機制的實際示例,了解它們如何與其他機制組合,以及識別向玩家提供的風險(挑戰)和獎勵。展示了這些機制的游戲已可查看和游玩。

      通過使用自制游戲作為整理的示例,內容不可否認地偏向于動作小游戲,尤其是單按鈕游戲,但這種展示方式為頭腦風暴游戲創意提供了一個范例。

      約束:創造力與游戲完成的催化劑

      產生創意的一種方法是事先對自己施加某些約束。通過思考如何在這些約束下使游戲變得有趣,可以預期產生與以往不同的創意。此外,思考如何利用這些約束還能增強創意的獨特性。

      可以設想什么樣的約束呢?例如 Game Jam 等游戲開發比賽中的格式、規則和主題。在許多 Game Jam 中,會對可提交的游戲設置一些約束,鼓勵參與者在這些約束下集中精力創作游戲。

      在視頻"Different Game Jam Formats"[^44] 中,列舉了以下類型的約束:

      • 工具:指定可使用的游戲引擎。
      • 素材:預先提供可在游戲中使用的圖片等素材。
      • 畫面:限制分辨率和顏色數量。
      • 目標:定義游戲的目標,例如"收集更多物品"。
      • 交互:限制玩家與游戲交互的方式,例如"只能使用兩個按鈕"。
      • 類型:指定類型,如"平臺跳躍"或"Roguelike"。
      • 時間限制:在規定時間內完成游戲。

      為了激發創意,關于交互、畫面和目標的約束可能較為有益。

      關于交互,常見的約束包括限制可用按鈕數量、僅使用鼠標、使用整個鍵盤或雙搖桿輸入。當可用按鈕數量受限時,需要仔細考慮為每個按鈕分配什么操作。例如,將使用傳統方向鍵加兩個按鈕的游戲轉換為單按鈕游戲,就面臨一個棘手的難題,而在構思強制解決方案的過程中,有可能催生全新的創意。

      畫面約束主要只影響外觀,不影響游戲規則。然而,在極端約束的情況下,例如極低的 16x16 像素數,或本質上只允許一條垂直線的一維空間,就需要創造性的方案來克服這些約束。過去甚至有只允許 1x1 像素、兩色顯示作為輸出的 Game Jam。[^45]

      關于目標,僅僅設置平凡的目標并不能引導創意探索。通過設計具有不尋常目標的游戲,如"摧毀自身"、"做出犧牲"或"利用敵人獲勝",可以構想出全新的游戲體驗。有趣的是,這些獨特的目標正是由 Game Jam Theme Generator 生成的。[^46] 該生成器不僅限于目標,還能輸出各種 Game Jam 主題,可用作輔助頭腦風暴的創意生成器。

      工具、素材、類型和時間限制更多是關于在有限時間內完成游戲,而非創意生成。通過不花時間選擇工具和素材,專注于在時間限制內創作指定類型的游戲,這種標準化方法有助于快速完成游戲創作。

      如果你有志于創作大量游戲,為創作過程建立自己的一套規則和規范是明智的策略。標準化創作內容和創作方式,以最大限度地減少開發中的工作量。[^47]

      在游戲開發中施加一些約束可以幫助產生新創意或快速完成游戲。過于嚴格的約束會使克服它們變得困難,因此建議找到并有效利用適合自己感覺的約束。

      單按鈕游戲的可能性

      在 Game Jam 中,有一種將交互限制為僅一個按鈕的設置,即創建所謂的單按鈕游戲。

      不同于除了一個按鈕外還有搖桿用于移動的情況,這里的"單按鈕游戲"指的是所有游戲交互都僅使用一個按鈕。

      單按鈕游戲的優勢在于操作簡單,在觸摸設備上容易操作。本質上,按下按鈕即可執行玩家的所有可用操作,幾乎不需要操作說明。此外,在觸摸設備上,只需在屏幕任意位置點擊或長按即可進行控制,避免了其他游戲中虛擬方向鍵不靈敏的常見問題。

      缺點自然是難以引入操作變化。即使是用搖桿就能輕松實現的簡單橫向移動,也需要采用非常規的操作方式,例如每次按下按鈕時反轉方向。

      因此,開發單按鈕游戲時的關鍵問題是:如何僅用一個按鈕在游戲交互中引入變化。在這方面,我想根據獨特的機制對我迄今為止創建的一些單按鈕游戲進行分類。

      融入獨特操作

      通常,在單按鈕游戲中,玩家按下按鈕后執行以下操作:

      • ? 反轉移動方向,或旋轉 90 度。
      • ? 跳躍或扇翅。
      • ? 射擊。

      例如,在我制作的游戲 THUNDER 中(點擊圖片可玩),即使只有兩個方向的移動,也可以通過巧妙利用障礙物和獎勵物品來制作單按鈕游戲。但它缺乏單按鈕游戲獨有的特色。


      THUNDER [8]

      如果按下按鈕觸發的操作在傳統游戲中很少見,就能強烈地給玩家留下單按鈕操控方案的獨特印象。

      瞬移CYWALL [9]

      屏幕上預設若干點,按下按鈕后瞬移到最近的點。這一機制使僅用一個按鈕即可實現快速移動。

      分裂DIVARR [10]

      每次按下按鈕使導彈分裂。持續按住按鈕可增強攻擊力,但需要設置約束,例如引入不應被擊中的目標,以防止無腦瘋狂按鍵。

      選擇JUMP ON [11]

      在某些節點,玩家選擇轉向或跳到另一個平臺等操作。關鍵是讓玩家清楚地理解選擇的時機及其后果,這需要精心設計游戲場地的布局和呈現方式。

      屬性反轉NS CLIMB [12]

      每次按下按鈕,磁極等屬性就會切換。游戲設計的關鍵在于決定使用哪些屬性以及它們如何與環境交互。

      其他特殊機制LADDER DROP [13]

      適時投放移動平臺和梯子,類似于單按鈕的方塊下落游戲。


      NUMBER LINE [14]

      將流動的數字相加,這是一個相當奇特的例子,說明分配給按鈕的操作可以非常多樣。

      利用按住按鈕的操作

      單按鈕游戲通常在按下按鈕時觸發操作,但也可以在按住按鈕期間持續產生操作。

      調整角度或距離NUMBER BALL [15]

      在高爾夫游戲中很常見,按住按鈕時角度逐漸增加,玩家必須在恰當時機松開按鈕擊球。在這個游戲中,當球上的數字與地板上的數字匹配時地板會消失,這是一個與傳統高爾夫不同的奇特規則。


      FROOOOG [16]

      青蛙的跳躍距離取決于按住按鈕的時長;這是解決如何用一個按鈕將玩家從一個位置移動到多個位置的方案。

      伸展PIN CLIMB [17]

      按住按鈕時棍子伸展,松開時收縮。伸展的棍子可以鉤住物體,配合特定地形特征幫助推進。


      SQUARE BAR [18]

      與幾何形狀結合時,即使僅僅是伸展也能產生復雜的運動。


      TAPE J [19]

      伸展越長得分越高,但風險也越大,創造了平衡的風險-回報情境。

      防御 / 閃避EMBATTLED [20]

      按住按鈕時,玩家對子彈無敵。但如果一直不動會被坦克碾壓,所以需要引誘坦克靠近,松開按鈕縱向閃避,觀看坦克互相戰斗。


      REFLECTOR [21]

      防御墻始終在下方提供保護,反射敵人火力,但按住按鈕可以發動強力反擊,代價是防御墻縮小。


      BAMBOO [22]

      按下按鈕可以讓玩家穿過竹子,并通過在竹子之間彈跳快速切割竹子。

      其他特殊機制CHARGE BEAM [23]

      蓄力能量,管理蓄力量對游戲體驗至關重要。


      LASER FORTRESS [24]

      掃射,射擊的超級強化版。混合敵我單位確保過于強大的攻擊可能適得其反。


      SHINY [25]

      晴天或雨天,雨天加速人類移動,使其更快地撤離到右端。這種奇特的機制似乎不容易移植到其他游戲中。

      組合多種操作

      組合上述操作是經典的方法。


      SCRAMBIRD [26]

      扇翅 + 射擊,


      TILTED [27]

      多次跳躍 + 反轉方向,


      UP SHOT [28]

      射擊 + 停止。

      此外,一個操作可以在游戲中產生多種效果。


      BOMB UP [29]

      例如,用按鈕投放/引爆炸彈,爆炸同時將玩家彈射出去。通過調整爆炸和玩家的位置可以控制玩家移動。這種方法可以用一個按鈕實現相當復雜的操作,但過于復雜會導致操作困難,因此適度是關鍵。

      結合旋轉運動

      類似于角度調整,但這里玩家或炮臺始終在旋轉,把握跳躍或射擊的時機至關重要。


      ORBIT MAN [30]

      跳躍方向不斷旋轉,玩家必須精確把握朝向星星跳躍的時機。


      ARCFIRE [31]

      炮臺旋轉時,玩家必須精確把握面向敵人時的射擊時機。這款游戲允許通過按住按鈕調整射程和攻擊范圍,以及射擊方向的微小提前量,實現一個按鈕的多種操作。

      利用地形

      如果輸入變化難以實現,根據玩家所在的地形改變玩家操作是一個可行的解決方案。


      TURBULENT [32]

      即使是跳躍這樣簡單的操作,將跳躍地形變為波濤洶涌的海面,就能根據時機改變跳躍方向。


      SUB JUMP [33]

      將屏幕分為水下和水上,按下按鈕在水下時上升,在水上時跳躍,根據地形賦予按鈕多種功能。

      利用道具

      除了地形,利用道具是另一種方法。拾取道具會改變某種模式,選擇拾取或忽略道具替代了輸入的多樣性。


      MIRROR FLOOR [34]

      金幣切換重力方向;玩家必須觀察下一個平臺的位置來決定是否收集金幣,這會影響跳上下一個平臺的能力。


      LIFT UP [35]

      收集道具改變移動方向。需要在收集金幣的同時巧妙收集反轉道具,避免碰到左右兩邊的尖刺。


      REBIRTH [36]

      被卡車撞到會將玩家傳送到反轉世界。卡車是否算作道具可以商榷,但玩家需要根據下一個鉆石的位置決定是否要被撞。


      R WHEEL [37]

      收集道具向下發射激光,摧毀尖刺障礙。這款游戲在跳躍時也會向下發射激光,尖刺會回旋到玩家身邊,跳躍時出現道具。跳躍動作在這款游戲中觸發了多個事件。

      結論

      與認為單按鈕游戲無法提供太多操作變化的假設相反,這里列舉的例子證明可以創建種類繁多的游戲類型。通過發揮單按鈕游戲的潛力,我期待在未來開發更多樣的游戲。

      雖然單按鈕游戲的簡潔性是優勢,但也帶來了意想不到的陷阱。例如,游戲可能無意中演變成重復的瘋狂按鍵或持續按住按鈕的模式,玩家可以獲得無限分數。因此,必須測試這些重復游玩模式,以確保游戲體驗平衡且引人入勝。

      最后,重要的是要記住,作為單按鈕游戲和作為有趣的游戲是兩回事。因此,確保游戲有趣、有暢快感和緊張感、風險與回報平衡等愉快游戲體驗的各方面至關重要。然后再考慮如何將那種樂趣融入單按鈕游戲的格式中。

      在有限大小約束下創作游戲

      Game Jam 經常對游戲二進制文件或源代碼的大小施加約束。著名的例子包括 js13kGames[^48],它挑戰參與者在 13 千字節內創建瀏覽器游戲。

      使用短代碼實現多樣化表達的嘗試跨越許多領域,不僅限于游戲。例如,使用 ggplot2[^49],可以在 280 個字符內創建精美的幾何圖案。[^50] 此外,在 140 個字符[^51]內使用 SuperCollider[^52] 和在 Dwitter[^53] 等平臺上使用 JavaScript 創建的音樂和生成藝術合集。

      緊湊編碼作品的精髓在于密集打包信息的美感。它們體現了用最少組件實現最大效果的巧思。

      在 Dwitter 上,用戶不僅分享圖形和音樂,還分享游戲。例如,游戲 Crossy Tortoise[^54] 涉及引導烏龜穿越馬路,展示了在 140 個字符內實現的單按鈕游戲。但它缺少計分系統,一旦完成穿越游戲就結束了。

      要稱得上是游戲,以下要素是理想的:

      • ? 具有計分系統。
      • ? 有游戲結束條件。
      • ? 難度遞增。
      • ? 最好有音效。

      考慮到包含這些要素,我們來思考短代碼的合理規則:

      • ? 編寫每幀更新的 JavaScript 函數,最大長度 256 個字符。
      • ? 引入 p5.js[^55]、Tone.js[^56] 和 lodash.range[^57] 等庫,提供適合游戲的便捷函數。
      • ? 為p5.mouseIsPressedp5.mouseXp5.mouseYp5.random()Tone.synth.triggerAttackRelease()_.range()分別賦予MXYRNA等單字符別名,以便在更少的字符內調用函數。
      • ? 變量S代表分數,顯示在頂部;變量T代表游戲開始以來的幀計數,用于難度調整。

      按照這些規則創建了幾個示例游戲[^58](點擊圖片可玩)。


      springcar [38]

      其中一個游戲 springcar,涉及一輛點擊后跳躍的汽車。代碼如下:


      clear(),
      T || ((s = A(9).map((i) => [10 * i])), (y = v = 0)),
      (d = 1 + T / 999),
      s.map((u) => text("", (u[0] = u[0] < 99 ? u[0] + d : -R(30)), 80)),
      (y += v += (M ? 0.1 : 0.2) * d),
      get(74, y)[3] + get(82, y)[3] > 0 && ((v = -1), (y = 72), S++, N(333, 0.1)),
      y > 70 && v < 1 && M && ((v = -3), N(444, 0.2)),
      y > 95 && ((S = y = T = 0), N(222, 0.5)),
      text("", 75, y);

      按照這些規則,創建一個游戲仍然是可行的。還有在更嚴格的規則下創建的 Pong,例如不允許添加庫,整個 HTML 包含在 226 字節內。[^59] 你可以在 codegolf JS[^60] 中看到更多類似的優秀代碼。

      按照這些規則,大約一小時內制作一個基本游戲是可行的。然而,256 個字符的約束很嚴格,嘗試實現復雜的動作很快就會超出字符限制。當你精心制作了一個約 270 個字符的游戲時,盡管使用了巧妙的技巧,但為了滿足限制而縮減就必須要縮小游戲系統,這令人沮喪。然而,沒有 256 個字符的約束,就有無限添加效果和調整游戲平衡的可能。因此,即使令人沮喪,放棄這些額外的部分也是挑戰的一部分。

      有限大小游戲開發能夠快速產出的特性很有趣。在如此有限的大小內就能制作游戲這一事實,意味著規則和機制被極大地精簡。這樣的約束能產生有趣的游戲,是優秀創意的寶庫。

      然而,自我施加的大小約束往往更多是束縛而非有助于提前完成,因此建議只有那些覺得克服大小約束有趣的人才去嘗試。存在大量用于大小壓縮的庫和技術。[^61] 你可以參考這些來判斷自己是否有興趣,根據你是否覺得這個概念有趣來確認自己的天賦。

      小游戲中什么構成適當的難度

      太難的游戲會令人沮喪,太簡單的游戲則令人無聊。適當的難度是好游戲不可或缺的要素;然而達到正確的平衡可能頗具挑戰。所需的難度水平因游戲類型而異——從 Soul-like 游戲中無情的挑戰和反復重試,到輕松易通的三消益智游戲。游戲類型極大地影響了所需的難度水平。

      正如 Mihaly Csikszentmihalyi 的心流模型中所提到的,提供與個人技能水平相對應的挑戰可以提高參與度和沉浸感。[^62]

      在 Mihaly Csikszentmihalyi 的心流模型中,實現技能與挑戰之間的平衡是關鍵。小游戲中維持這種平衡的常用方法是隨著時間推移逐步提高難度。難度水平,即挑戰水平,持續上升直到匹配玩家的技能水平,一旦超越該水平,任何失誤都會導致"游戲結束"。

      如果提高難度的方法和節奏得當,這種方法可以很好地創造有趣的游戲。什么被認為是正確的方法呢?當難度增加且玩家犯錯時,如果玩家認為是由于自己技能不足,那么難度水平就被認為是適當的。相反,如果游戲變得不公平地困難,例如玩家面臨不可避免的攻擊,那么難度水平就被認為是不適當的。

      調整難度常用的參數是游戲速度。隨著游戲進行,游戲速度加快,玩家和敵人的速度都增加。這要求玩家更快速地反應,任何誤操作都會導致"游戲結束"。這種自 Game & Watch[^63] 時代——指任天堂早期掌上游戲時期——就使用的傳統難度調整方法至今仍然有效。使用游戲速度調整難度的一個好處是,它最大限度地減少了變得不公平的可能性。當游戲速度變化時,敵人和玩家的速度按比例增加,避免了早期可以躲避的敵人在后期變得無法躲避的情況。

      然而,僅依靠游戲速度來調整難度可能會變得單調。在這種情況下,增加敵人數量或擴大障礙物等方法可以用來提高挑戰。因此,進行調整以確保不會出現諸如障礙物變得大到玩家跳躍能力無法躲避而導致不公平的情況,這是至關重要的。

      通過組合各種難度調整方法,游戲變得更加復雜,玩家也不容易失去興趣。理想情況下,引入要求玩家高級技巧的新元素,如新敵人、武器、地形、道具等,可以增強游戲體驗。然而,在小游戲中實現成本較高,這可能是一項具有挑戰性的任務。

      上升的難度曲線

      適當的難度提升意味著什么,應該以什么節奏進行?這在很大程度上取決于你希望玩家在游戲中投入多長時間。例如,假設一款游戲應持續 3 分鐘,你將難度設計為在從初始翻倍時大多數玩家淘汰,可以考慮以下公式來計算難度:


      [難度] = sqrt([已過幀數] * 0.0001) + 1

      這里,"幀"是時間單位,代表游戲中 1/60 秒。已過幀數每秒 60,每分鐘 3600。sqrt指平方根。不使難度與幀數線性成正比,而是使用sqrt函數確保在經過一定時間后難度上升更為平緩。將 3 分鐘的幀數 10800 代入上述公式,得到的難度為 2.04,與初始假設一致。

      然而,這個難度設置可能并不適合所有小游戲。在某些情況下,更快地提升難度可以創造更緊張、更引人入勝的體驗。

      不將難度提升應用到游戲中并觀察結果,很難判斷什么樣的難度提升是適當的。因此,我將難度隨時間上升的情況可視化為曲線,準備了調整該曲線的 UI,并將其反映到示例游戲中(點擊圖片前往演示頁面)。


      diff-tween [39]

      在 diff-tween 頁面中,在右側 UI 上調整難度曲線,然后點擊左側游戲畫面即可開始一款躲避落石的游戲。初始曲線設置旨在讓人清楚理解難度提升,30 秒內難度翻倍。

      每條難度曲線由其公式(sqrt、linear、pow)和提升速率(climb)定義,并可以調整為鋸齒波(saw),即以固定間隔降低難度。鋸齒波是引入難度變化的好方法,這一技術也用于 Game & Watch。此外,還可以調整多個參數,如落石速度和大小。

      當有多個參數受難度影響時,調優變得更加困難。玩過游戲后會發現,雖然玩家可以通過技能應對更快的落石,但一旦石頭達到一定大小就無法應對了。更快的落石也許還能設法躲避,但更大的石頭給人一種不可避免、不公平的印象。

      因此,可以使用 sqrt 函數來提升石頭大小以減輕不公平感,同時使用線性增加來從游戲開始就維持落石速度的緊張感,偶爾用鋸齒波來緩和節奏。

      此外,這種調整確實有缺點——初始難度可能讓人覺得太簡單、太無聊。在這種情況下,引入諸如靠近石頭通過時獲得獎勵分數等機制,鼓勵玩家冒著風險換取獎勵,從游戲早期階段就提供緊張感。

      基于關卡的難度設定

      到目前為止,討論主要圍繞沒有關卡(舞臺、回合)概念的游戲展開。但是,當考慮由多個關卡組成、每個關卡各有難度設定的游戲時,可以有哪些難度配置方式呢?

      隨著關卡推進,游戲必須逐漸變得更具挑戰性,否則就會缺乏緊張感。然而,僅僅是線性增加難度可能導致缺乏變化。如何設計一種隨著關卡推進越來越難、同時又有足夠波動的關卡設計呢?下面以使用以下圖表的方法為例進行說明。


      level-difficulty-curve

      橫軸表示從random函數獲取的 0 到 1 之間的隨機值。縱軸表示難度,0 為最簡單,1 為最具挑戰性。在開始一個關卡之前,從random函數獲取一個值作為橫軸值,對應的難度即作為該關卡的難度等級。

      該圖表中的難度通過以下公式計算:


      pow(random(), 100 / ([current level number] + 1))

      在早期關卡中,關卡數較低時,難度傾向于停留在低端,隨著關卡數增加,難度向上擴展。因此,更高的關卡傾向于擁有更高的難度設定,盡管偶爾由于random函數的返回值,某個關卡可能會明顯比其關卡號所暗示的更容易或更難。

      這種難度也可以應用于多個參數,例如:

      • ? 敵人數量
      • ? 敵人射擊頻率
      • ? 子彈速度

      通過對上述公式分別設定每個參數的難度并使用隨機函數,可以實現更復雜的變化組合。在某些關卡中可能有很多敵人但它們不常射擊,或者可能只有一個敵人但它射出極快的子彈,等等。

      在游戲的后期關卡中,所有參數都趨向于難度 1,導致一系列普遍高難度的關卡。但由于難度本身被限制在 1,與單純線性增加難度相比,這種設定可以實現某種約束。

      這種方法也有缺點。最終所有參數都會固定在難度 1,無法創造無限增加難度的關卡。在難度封頂為 1 的狀態下設定合適的難度是一項挑戰。

      即使采用其他方法,確保難度增加不單調也是至關重要的。通過改變玩家所體驗的緊張感,可以實現更令人愉快的游戲進程。

      讓游戲變得"多汁"

      僅僅依靠核心規則、最少的視覺效果和沒有聲音就能令人滿意的游戲,是極為罕見的共識。除了基本規則之外,游戲還需要對玩家感官的刺激,如視覺和聽覺效果,以及增強體驗的演出效果。

      游戲開發者將這些元素被恰當運用的游戲稱為"多汁"(juicy)游戲。通過讓一個簡單的打磚塊游戲變得"多汁",很容易看出同樣的規則如何讓游戲變得更加有趣。這一概念在一些視頻中有很好的說明,它們展示了如何通過添加"汁液"來讓游戲變得多汁,[^64] 或者通過演示來展示多汁游戲帶來的差異。[^65]

      文章《研究:制作一款"多汁"的游戲》[^66] 包含了上述視頻的內容,并介紹了讓游戲多汁化的方法。其中提出的方法包括:

      • ? 添加色彩。
      • ? 利用緩動(tweening)和緩動曲線(easing)實現平滑動畫。
      • ? 根據事件改變或彈跳對象大小。
      • ? 加入音效和音樂。
      • ? 用大量粒子顯示煙霧、破壞效果或拖尾。
      • ? 震動畫面以傳達沖擊感。
      • ? 為對象添加眼睛和微笑,讓它們對環境做出反應。眼睛跟蹤物體并眨眼,嘴巴表達情感。
      • ? 讓環境跟隨音樂節奏做出反應。
      • ? 在攻擊時添加命中停頓或擊退等動畫。

      有效運用這些方法的游戲被稱為"多汁"游戲。然而,"多汁"這個術語有些模糊。

      文章《"多汁":一個有用的游戲設計術語?》[^67] 探討了"多汁"所代表的含義,但并未得出一個明確的定義。其中提到了 PopCap[^68] 等公司的休閑多汁游戲,尤其是 Peggle[^69],因其各種贊美玩家的演出效果而備受稱贊。簡單來說,Peggle 是一款玩家從屏幕頂部發射球并觀看球擊中釘子的游戲。但每次連擊時,一只名叫 Jimmy Lightning 的海貍會用"太酷了!"或"太創新了!"等話語歡呼,保持高昂的氛圍。其他演出效果還包括在擊中最后一個釘子之前的鼓點和放大特寫,成功后會播放貝多芬第九交響曲——真是一款多汁的游戲。

      在游戲中加入這樣生動的演出效果,即使在簡單的游戲中也能大大提升玩家的樂趣。雖然在短開發周期內添加豐富的演出效果可能有挑戰,但也有更簡單而有效的方法,比如粒子效果或響應式音效來增加多汁感。

      雖然與"多汁感"略有不同,但改善游戲的"手感"(feel)[^70] 同樣至關重要。通過寬容玩家的小失誤并使正確操作更容易執行,可以提供更舒適的游戲體驗。

      關注核心機制之外的方面,游戲可以進化為對玩家來說更加有趣的體驗。

      創造你自己的游戲開發工具

      讓游戲創作更有樂趣的一種方式是開發自己的工具來簡化和加速這個過程。這里的"工具"指的是面向游戲的庫、像素畫繪制工具、音樂作曲工具等等。如果有足夠的熱情,開發者可以創造各種各樣的基礎游戲開發工具,包括幻想主機(fantasy consoles)、游戲引擎,甚至編程語言。

      盡管已有大量現有工具,創造自己的工具有何意義?一個原因是獲得高度熟悉、內部運作完全理解的工具。既然是你自己創建的,自然清楚如何操控它們以獲得期望的結果。此外,你還可以自由添加自己喜歡的功能。應用程序編程接口(API)和用戶界面(UI)的設計可以根據你的偏好量身定制,從而營造舒適的的開發環境。

      此外,工具創建過程本身就帶來樂趣。與游戲開發不同——在創作過程中探索最終形態——這些工具有相對明確的目的,在游戲創作過程中可以作為很好的調劑。看到你需要的功能逐步擴展,是很有成就感的。

      問題在于這個過程可能變得過于令人愉快。游戲開發者中有一句俗語很好地概括了這個問題:"不要造游戲引擎,去造游戲。"這是對沉迷于創建外圍工具、從而忽視游戲本身導致游戲永遠完不成的警示。

      保持適當的平衡,工具創造可以為游戲開發帶來新一層的樂趣。

      為小型瀏覽器游戲創建庫

      游戲庫或游戲引擎應該包含哪些功能?一篇題為《如何制作自己的游戲引擎(以及為什么)》[^71] 的文章列出了以下功能:

      • ? 基本功能:
        • ? 系統初始化:準備窗口、啟動渲染和音頻系統。
        • ? 幀時序控制:以 1/60 秒間隔定期調用的更新處理。
        • ? 輸入:處理按鈕輸入等。
        • ? 渲染:繪制 2D 或 3D 紋理、模型等。
        • ? 算術工具:向量運算和其他游戲所需的函數。
      • ? 高級功能:
        • ? 游戲對象與場景管理:管理多個對象以及在多個場景之間切換。
        • ? 音頻:使用音頻框架播放音頻。
        • ? 文件管理:管理文件和資源。
        • ? 網絡:多人游戲的通信功能。

      此外還提到了碰撞檢測、物理計算、序列化、動畫、UI 等,但并非必需。現有的游戲引擎提供了經多年經驗支撐的功能集,了解它們的功能在創建自己的游戲庫或引擎時會非常有幫助。

      該文章還概述了創建自定義游戲引擎時應有的心態:

      • ? 同時構建引擎和游戲:引擎應該擁有的功能是由你想創建的游戲的需求所支撐的。
      • ? 不要在需要之前創建功能:避免過度工程化你的游戲不需要的功能。
      • ? 使用你熟悉的編程語言:構建引擎是一項具有挑戰性的任務,不應在學習新編程語言的同時進行。
      • ? 不要從一開始就尋求正確答案:經過多次構建引擎的經驗之后,你最終會創建出一個可用的引擎。

      那么,面向小型瀏覽器游戲的游戲庫應該具備哪些功能呢?上面提到的基本功能是必需的,但高級功能可以有限度地實現。此外,如果目標是快速將創意變為現實,專注于實現游戲所需的機制會更好。

      基于這些考慮,我創建了一個名為 crisp-game-lib[^72] 的游戲庫。該庫具有以下特點:

      • ? 標題、游戲中、游戲結束等場景在庫內標準化,無需為每個游戲單獨開發。
      • ? 提供小型游戲特別需要的功能,如高分管理和回放。
      • ? 對分辨率、顏色和聲音施加約束,減少耗時制作豐富表現的需要。
      • ? 讓游戲變得"多汁"變得容易。具體來說,可以輕松添加各種視覺和音效。

      在 crisp-game-lib 中,只需編寫一個 JavaScript 文件,[^73] 包含游戲的titledescription和每秒調用 60 次的update函數,就可以創建在 PC 和移動端都能運行的瀏覽器游戲。

      一個在其他庫中找不到的獨特功能是,渲染盒子、線條、弧線、文本和角色時,集成了碰撞檢測。


      ref_collision screenshot [40]

      當使用函數繪制一個元素時,返回值會告訴你該元素是否與屏幕上已有的其他形狀、文本或角色重疊。只需檢查這個值,即使對線條和弧線等復雜形狀也能檢測碰撞,無需特定的碰撞檢測處理。

      此外,該庫還具有以下讓游戲多汁化的功能:

      • ? 只需選擇所需聲音名稱即可播放的音效。[^74]
      • ? 將選項 [^75]isPlayingBgm設為 true 即可自動生成 BGM。
      • ? 將isReplayEnabled設為 true 即可啟用回放功能。
      • ? 外觀改變功能,如復古 CRT 風格或像素畫風格,可通過定義theme來設定。
      • ? 像素畫可通過characters數組輕松定義。

      創建自己的游戲庫,根據自身需求裁剪功能,可以是一種愉快的、更高效開發游戲的方式。思考什么樣的功能在你符合你游戲開發風格的庫中是理想的,然后嘗試創建你自己的原創庫。

      為 DIY 手持設備開發游戲

      最近出現了一種趨勢:以 Arduino [^76] 等單板微控制器為核心,加上顯示屏和按鈕,來創建 DIY 手持游戲機。優點是可以根據自己的喜好創建游戲機。缺點是各種設備層出不窮,沒有一款是很多人共同擁有的通用設備。

      這些設備的游戲通常用 C 語言編寫。因此,配套的庫也需要用 C 語言實現。

      這次,我將最初為瀏覽器用 JavaScript(TypeScript)實現的自定義庫移植到了 C 語言。我將其命名為 crisp-game-lib-portable。[^77]



      PyBadge crisp-game-lib-portable screenshot

      用 crisp-game-lib-portable 創建的游戲兼容 M5StickC PLUS [^78] 和 Adafruit PyBadge [^79] 等設備。此外,通過利用 Emscripten,[^80] 現在也可以在瀏覽器上運行。

      庫核心 [^81] 和游戲代碼 [^82] 被設計為包括瀏覽器在內的所有設備通用,目標是只需要最少量的設備特定代碼。

      需要在設備特定代碼中編寫的處理包括:

      • ? 設備初始化(如 Arduino 中的setup()),并從中調用initGame()
      • ? 幀更新處理(如 Arduino 中的loop()),通過調用setButtonState()通知按鈕狀態,并調用updateFrame()
      • ? 在machineDependent.h中定義的繪圖和聲音相關處理。[^83]

      通過這種方式,通用設備所需的設備特定實現大約為 250 行。

      在 PyBadge 等設備上適配這些函數可能有些麻煩,因為只能使用analogWrite()調節蜂鳴器音量,需要手動管理聲音時序和生成方波。

      顯示像素畫的md_drawCharacter(unsigned char grid[CHARACTER_HEIGHT][CHARACTER_WIDTH][3], float x, float y, int hash)函數也需要一些功夫。最后一個哈希值用于緩存像素畫的圖案定義,而不是每次都解析并繪制。如果你使用 LovyanGFX 庫 [^84] 進行繪圖,應該將 LGFX_Sprite 和哈希值作為一對保存,然后取出并執行pushSprite()

      在考慮這種可移植性的同時編寫代碼是一種有趣的體驗,這也是不以庫為目標面向各種設備就無法做到的事情。創建獨特的游戲庫,同時利用 Arduino IDE 等通用開發環境和 Adafruit Arcada [^85] 或 LovyanGFX 等多設備兼容庫,提供了獨特的體驗。與各種微控制器板打交道,相比面向 PC 或智能手機開發庫,呈現出另一種不同的樂趣。如果感興趣,不妨一試。

      制作幻想主機

      幻想主機 [^86] 體現了開發者一種異想天開的想法:"如果真有這樣一臺游戲主機就好了。"想象一下不存在的 Game Boy 或 Famicom 版本,在 PC 上實現它們,然后享受成果——這就是幻想主機。

      幻想主機的典型代表無疑是 PICO-8。[^87] 128x128 像素的屏幕、四個音軌同時播放、256 個 8x8 像素的精靈圖,以及包含 Lua 開發環境、像素畫編輯器、音樂編輯器和地圖編輯器的豐富內置工具——這是一款極具創新性的技術產品。

      雖然名字叫"主機",[^88] 但許多幻想主機在內部集成了完整的開發環境。它們更像 MSX 或 Family BASIC 那樣的微型計算機。

      制作一臺 PICO-8 水平的幻想主機是相當有挑戰性的。然而,親手打造自己幻想主機的愿望確實令人心動。要做到這一點,就必須刻意限制規格。以擁有極小屏幕、簡單聲音輸出和基本輸入方式的幻想主機為目標,我創作了 PEEKPOKE。[^89]

      PEEKPOKE 可以在 PC 和智能手機瀏覽器上游玩(點擊屏幕即可操作)。



      BOMB SNAKE [41]

      這是一款貪吃蛇游戲,用方向鍵(上下左右)或 WASD 鍵操控蛇去收集紅色炸彈。在智能手機上,通過屏幕底部的虛擬方向鍵來操控。


      PEEKPOKE 內存映射

      在 PEEKPOKE 中,機器的控制完全通過 peek 和 poke 命令來讀寫內存實現。它采用內存映射 I/O [^90] 來操作有限的功能集:32x30 像素 8 色屏幕、8x5 文本屏幕、七個按鍵輸入和一個單音蜂鳴器。沒有內置開發環境;游戲可以用 JavaScript 編寫腳本。[^91]

      通過將所有主機特有功能委托給內存,并將開發環境交給 JavaScript,構建過程大大簡化了。能制作的游戲相當基礎,但勉強可以稱之為一臺幻想主機。在啟動時添加一個啟動畫面,就能增添幾分幻想主機的韻味。

      沒有開發環境,制作幻想主機的工作量大幅減少。幻想一臺擁有有趣規格的主機并輕松地制作出來,是一件非常愉快的事情。這次制作的主機架構相當簡單。不過,考慮設計具有更奇特功能的主機,或者致敬 Cassette Vision、ATARI 2600 等現有主機的設計,也會很有趣。

      通過自動化提升開發效率

      當想要以更少的精力進行游戲開發時,程序化生成 [^92] ——即通過編程來生成像素畫、音效、背景音樂和關卡——是一個強大的工具。雖然生成質量可能不及手工制作的素材,但通過反復迭代生成過程直到獲得滿意的結果,就能以最小的精力獲取必要的游戲素材。此外,通過使用隨機關卡生成算法,玩家每次都能享受獨特的游戲體驗,從而提升游戲的重復游玩價值。

      在這里,讓我們探討自動生成角色像素畫、背景音樂、音效和益智游戲關卡等元素的方法。

      自動像素畫生成

      被稱為自動像素畫生成器的工具有多種類型,常見的方法是將大量預設部件進行組合并改變其顏色來創建新的像素畫。[^93] 這種方法常用于游戲頭像創建,能夠生成大量風格一致的角色及其動畫。然而,這種方法只能創建特定角色的變體。如果沒有與所需角色匹配的生成器,就無法獲得想要的像素畫。

      一種稍微更靈活的方法是在基礎像素畫上添加隨機開關的點,通過這些變化來創建各種圖案。[^94] 使用這種方法,通過修改基礎像素畫,可以適應各種角色的生成。

      我也按照隨機點變化的方法制作了一個像素畫創建庫。[^95] 例如,使用這個庫創建各種形狀的宇宙飛船,結果如下(點擊圖片可跳轉到演示頁面)。


      pixel-art-gen [42]

      這種方法生成的產物隨機性很高,擅長創建像宇宙飛船這樣自由形態的角色。然而,對于有約束的角色,比如側面視角下有明確眼睛、手臂和腿的怪物,就顯得力不從心了。因此,像素畫生成器本身就有固有的優勢和劣勢,不存在萬能的解決方案。

      近年來,生成式 AI 已經能夠根據提示詞創建圖像,將此應用于像素畫的方法也已出現。[^96] 然而,生成式 AI 擅長創建較大的圖像,并不適合創建 16x16 像素這樣的小圖像。

      不過,隨著技術的進步,未來也許能夠生成像像素畫這樣的小圖像及其動畫。例如,向搭載 DALL-E 3 模型的 Bing Image Creator [^97] 提供以下提示詞,可以獲得可用于射擊游戲的宇宙飛船像素畫:

      創建一張展示一系列復古視頻游戲風格宇宙飛船的圖像,俯視視角。每艘宇宙飛船應在 32x32 像素網格內設計,使用 16 色調色板。將這些像素化宇宙飛船以視覺上美觀的方式排列。

      按照提示詞在 32x32 像素網格內創建圖像的指令尚未被準確執行。不過,這類問題預計會隨著未來生成模型的發展而逐步解決。

      背景音樂和音效的自動生成

      什么樣的背景音樂(BGM)適合小游戲?首先想到的是老式街機游戲中的 BGM。所謂"老",指的是 20 世紀 80 年代初期的《Xevious》或《Dig Dug》之類的游戲。那個時代的復古街機游戲通常使用大約 4 到 8 小節的短樂句作為 BGM,不斷循環播放。

      自動生成此類 BGM 的技術有多種。其中之一是 WolframTones。[^98] 看起來很方便。不過它似乎有一個限制:無法重現老游戲中常見的樂句,比如貝斯線以十六分音符在純五度間交替。

      在最新技術中,有 OpenAI 的 Jukebox;[^99] 但它生成的是音樂波形而非樂譜,因此不適合復古游戲。類似的技術 MusicLM [^100] 有一個 8 位采樣,似乎能夠創建類似芯片音樂的音軌,但仍然顯得過于豐富。

      這就引出了 Magenta,[^101] 這是 Google 的一個研究項目,將機器學習應用于音樂和藝術。Magenta.js [^102] 是其在瀏覽器中運行的實現版本。

      Magenta.js 在給定一段樂譜后,利用 MusicRNN [^103] 自動生成后續樂句。如果給它一段復古游戲的短樂譜,它就能產生具有類似風格的另一首曲子。我創建了一個簡單的演示程序來測試這一點(點擊圖片跳轉到演示頁面)。[^104]


      Short VGM generator [43]

      點擊屏幕中央的"Generate"按鈕后,會基于左側的樂句生成新的樂句并顯示出來,在右側播放。它生成僅包含旋律和貝斯音軌的簡單樂句,但能產生相當有復古游戲音樂韻味的曲調。對于多個音軌,每個樂句分別創建,如果貝斯與旋律不和諧(確保頻率比約為 1:4),會進行調整。取消選中中間下方復選框可禁用此調整,從而生成更自由的樂句。

      至于音效的自動生成,針對旋律的 MusicRNN 似乎難以勝任。相反,有許多基于波形的解決方案,其中很多基于 sfxr。[^105] 這些工具可以用來為動作游戲添加簡單的音效。

      益智游戲關卡自動生成

      本節將探討關卡自動生成,換言之就是益智游戲謎面的自動生成。雖然像 Game & Watch 這樣的游戲在單一畫面上游玩,但許多游戲有多個關卡或隨滾動出現的地形,因此需要生成關卡。

      關卡制作的質量直接影響游戲體驗,尤其是在益智游戲中。特別是在像《推箱子》[^106] 這樣的非動作益智游戲中,創建令人享受解謎過程的關卡至關重要。

      目前已經存在多種《推箱子》關卡生成器。典型的創建方法包括:

      1. 1. 創建一個沒有放置箱子的空房間。
      2. 2. 將箱子放置在正確的目標位置。
      3. 3. 反向模擬游戲來分散箱子。

      第三步本質上確保了如果玩家"拉"并移動箱子,箱子確實可以被移動到正確的位置。

      一種基于上述方法的生成器實現,[^107] 在玩家卡住時會回溯搜索其他排列方式。關于生成方法的論文 [^108] 引入了諸如玩家沿直線推箱子的次數或去推另一個箱子的次數等指標,旨在創建箱子盡可能遠離正確位置的關卡,從而增加玩家需要執行的操作。

      還有一篇論文旨在使用被稱為 PuzzleScript [^110] 的通用益智游戲創建語言,為任何益智游戲生成關卡。[^109] 通過將 PuzzleScript 規則分析器中的游戲對象特性傳遞給關卡生成器和評估器來創建關卡。這種方法由評估器判斷生成的關卡是否可解、是否有趣,與前述的反向模擬方法不同。

      雖然現有方法多種多樣,讓我們嘗試為自己定制的益智游戲進行關卡生成。

      我嘗試創建了一款名為 slickslack [^111] 的益智游戲,類似于《推箱子》和《Pengo》[^112] 的混合體。游戲目標是將顯示為藍色方塊的箱子彈到正確的黃色位置(點擊圖片游玩)。


      slickslack_screenshot [44]

      采用的關卡自動生成方法與其他《推箱子》生成器類似,從正確答案反向模擬游戲。不過,并非先創建空房間,而是創建一個全是墻壁的房間,在反向滑箱子的同時挖掘墻壁。


      slickslack_screenshot_generating

      1. 1. 創建一個任意大小的、全部由墻壁組成的房間(或由可以是墻壁或空地的格子組成)。
      2. 2. 將箱子放置在正確的目標位置。
      3. 3. 沿任意方向滑動箱子任意距離。
      4. 4. 在滑動方向的起始位置的對面放置墻壁,確保箱子在那里停下。
      5. 5. 將滑動過的區域確認為空地(挖掘墻壁)。

      執行上述滑動操作任意次數來創建關卡。然而,這樣不加考慮地創建關卡并不能保證關卡有趣,所以需要進行一些調整。

      由于這個益智游戲沒有玩家角色,箱子可以相當自由地滑動。因此,為了營造益智感,需要考慮滑動箱子的順序、如何通過撞擊其他箱子讓箱子停在正確位置,以及箱子之間的交互。此外,過多的墻壁會減少游戲約束,降低益智感。考慮到這些,做了以下調整:

      • ? 優先選擇能讓箱子被現有墻壁或其他箱子擋住的滑動方向,避免創建新墻壁。
      • ? 旨在使箱子滑動后與其他箱子相鄰。

      我還創建了另一款自動生成關卡的益智游戲 HAKOSAN。[^113] 目標是使用方向鍵同時滑動三個角色到達紅色終點(點擊圖片游玩)。


      HAKOSAN [45]

      同樣,關卡是通過從終點反向滑動角色來生成的。

      因此,這種從正確答案反向操作謎題來自動生成問題的方法,在許多場景中都適用。如果加入像 PuzzleScript 論文中提到的評估器,來判斷生成關卡的趣味性并進行篩選,可以進一步提升此方法。該論文使用各種指標評估關卡:箱子與正確位置之間的距離、玩家的移動次數、應用規則的次數等。雖然不能確定這些指標是否準確反映了解謎的樂趣,但它們對于過濾掉明顯無趣的關卡似乎很有用。在資源充足的情況下,融入此類改進可以實現更好的關卡生成。

      小游戲能否自動生成?

      我渴望擁有一臺能自動生成小游戲的機器。開發者只需游玩這臺機器生成的游戲,保留有趣的、丟棄無趣的,僅憑這一過程就能創造出游戲。這簡直是一臺夢想機器。

      前提是人類之后會進行審查和篩選,因此大多數產出不有趣也沒關系。更關鍵的是確保游戲在生成時擁有足夠豐富的機制變化。

      讓 AI 創造游戲的努力已經持續了數年。ANGELINA 項目 [^114] 提出了一種通過隨機組合機制來生成新游戲的方法——比如在按下按鈕時,將玩家的位置或重力等變量進行翻倍、減半或正負號切換。[^115] 按下按鈕后切換變量狀態的機制被稱為"可切換游戲機制"(Toggleable Game Mechanics, TGM),該研究將其應用于從始至終的跳躍解謎游戲中,旨在探索各種 TGM 的應用方式。

      研究采用遺傳算法從隨機組合中篩選出合適的 TGM 組合。選擇的適應度取決于玩家在到達終點前在關卡中移動的范圍有多廣。

      然而,通過這種方法創造的游戲變化范圍仍然有限,能否稱之為"新游戲"仍是一個模糊地帶。發明新游戲對人類來說都很困難,對計算機來說更是巨大的挑戰。

      最近,有潛力突破這些限制的技術出現了。以 ChatGPT 為代表,這些技術體現在搭載了大型語言模型(LLM)的 AI 聊天機器人中。

      用 AI 聊天機器人創造解謎游戲

      文章《ChatGPT 發明了自己的解謎游戲》[^116] 討論了一個場景:讓 ChatGPT 設計一種新的邏輯謎題,結果它提出了一個名為 Sumplete 的游戲。在這個游戲中,數字被放置在二維網格上,每行和每列的數字之和分別標注在網格的右側和底邊。玩家通過劃掉網格上的數字來匹配給定的總和。


      Sumplete

      然而,這款游戲實際上早已存在,名為 Summer,[^117] 是為智能手機設計的。無論人類還是 AI 都不可能了解所有已存在的游戲,因此創造出已經存在的游戲是常有的事。保證游戲的全新性是一件困難的事。

      盡管如此,讓 ChatGPT 參與頭腦風暴新的邏輯謎題仍然是一項有趣的嘗試。例如,當給出以下任務時,ChatGPT 能夠提出多種謎題:

      我希望你扮演一名邏輯謎題游戲設計師。設計 5 種全新的邏輯謎題。創建的規則要與現有的邏輯謎題(如數獨)不同。謎題應由二維網格構成。部分網格可以被墻壁分隔。單元格的初始狀態既包含含有數字或符號的格子,也包含空格子。玩家需要填入空白格并努力找到正確答案。

      提示詞要求提供五種基于二維網格的邏輯謎題,部分格子含有數字或符號,其余為空。網格可能被墻壁分隔。預計會出現類似 Heyawake [^118] 的謎題建議。

      其中一個提案是名為"Magnet Blocks"(磁鐵方塊)的謎題:

      在這個謎題中,網格包含極性相反的磁鐵(北極和南極)。玩家必須在網格中填入正極和負極的方塊,使每個方塊根據極性吸引或排斥相鄰的磁鐵。只有當方塊與周圍磁鐵兼容時才能放置,且相同極性的方塊不能相鄰接觸。

      以磁鐵為主題的 Magnet Blocks 提出的規則有些模糊。不過,將其解讀為"N 與 N、S 與 S 不能相鄰接觸"的磁鐵游戲后,成功實現了可玩的版本(點擊圖片即可游玩)。


      Magnet Blocks [46]

      具體規則如下:

      • ? 網格初始包含條形磁鐵和墻壁。
      • ? 條形磁鐵必須放入空格中,使 N 與 N、S 與 S 不相鄰接觸。條形磁鐵的長度為 3 格或以上。
      • ? 當所有空格都放有條形磁鐵時,謎題通關。

      盡管關卡生成邏輯不夠出色,導致謎題缺乏深度,但它仍然算得上是一個謎題。

      這個謎題真的是全新的嗎?存在一款名為 Magnets [^119] 的類似游戲,雖然同樣以磁鐵為主題,但規則有很大不同:

      • ? 條形磁鐵的放置位置和方向是預先確定的,固定長度為 2。
      • ? 網格邊緣給出了每行和每列中 + 和 - 出現次數的約束條件。
      • ? 不需要填滿所有空格。

      到目前為止,尚未發現具有完全相同規則的謎題。然而,不能排除在非磁鐵主題的謎題中存在類似規則集的可能性。

      邏輯謎題通常有固定的風格范式,是 ChatGPT 圍繞其頭腦風暴新規則的不錯主題。然而,正因為這些固定風格,被認為是"新的"想法很可能與已有游戲不謀而合。

      此外,讓 ChatGPT 生成足夠精確以構成可玩謎題的規則并不容易;這需要人類介入,將模糊的提案精煉為具體的規則。將這些規則轉化為可玩的程序代碼仍然是一項困難的任務。

      判斷所創造的謎題是否有趣又是另一個挑戰,因為這不僅取決于規則,還取決于關卡生成背后的邏輯。

      通過用其他方法、程序或插件來補充 ChatGPT 不擅長的任務(如創建精確規則),AI 聊天機器人的應用范圍有望進一步擴大。

      教 AI 理解游戲機制

      在上一節中,我將動作小游戲的機制以標簽的形式列出。[^120] 我們展示了通過隨機組合多個標簽,可以構思出利用這些機制的游戲。如果把這項任務交給 ChatGPT,或許能夠想出新的游戲創意。

      我們向 ChatGPT 提供了以下提示詞,讓它扮演游戲設計師的角色:

      我希望你扮演一名游戲設計師。請記住以下與游戲機制相關的標簽。標簽以"類別: 名稱, "描述""的格式書寫,每個標簽占一行。隨機組合這些標簽,構思一個僅包含對應游戲機制的新游戲。將該游戲設計為僅需單個按鍵的動作小游戲。最多可組合 5 個標簽。描述這是什么樣的游戲以及所選的標簽。盡量不重復使用相同的游戲機制標簽,嘗試構思 5 款不同的游戲。 player: rotate, "玩家角色旋轉。" player: reciprocate, "玩家角色水平或垂直往復運動。" player: reflect, "玩家角色在碰到墻壁或物體時反彈。" ...

      標簽列表及其說明在標簽列表文件 [^121] 中繼續,完整的提示詞包含所有這些標簽。[^122]

      游戲 1:Scaffold Jump(腳手架跳躍) 所選標簽:player: scaffold, on pressed: jump 描述:在這款游戲中,玩家控制一個沿腳手架移動的角色。角色持續向前移動,玩家可以通過按下按鈕讓角色跳躍。目標是在收集硬幣或道具的同時避免從腳手架墜落或撞到障礙物。隨著玩家前進,游戲逐漸加速,難度也隨之增加。 游戲 2:Pinball Panic(彈球恐慌) 所選標簽:player: circle, weapon: bounce, field: pins, on pressed: shoot 描述:在這款游戲中,玩家控制一個在彈球臺式場地中彈跳的圓形角色。按下按鈕可以發射彈丸,彈丸會在釘子間彈射并消滅敵人。目標是盡可能長時間存活,同時通過消滅敵人和收集道具來獲取高分。 游戲 3:Springy Strings(彈力繩) 所選標簽:player: string, player: bounce, field: gravity, on pressed: jump 描述:在這款游戲中,玩家控制一個在零重力場中彈跳的彈簧角色。按下按鈕可以讓角色跳躍,彈得更高。目標是在收集道具和到達關卡終點的同時躲避障礙物和敵人。 游戲 4:Wipeout Warriors(沖刷戰士) 所選標簽:player: bar, field: water, obstacle: chase, weapon: wipe, on pressed: jump 描述:在這款游戲中,玩家控制一個在水上賽道中競速的條形角色,賽道上充滿了障礙物和敵人。角色自動向前移動,玩家可以通過按下按鈕讓角色跳躍。角色還可以使用沖刷武器來清除前方的障礙物和敵人。目標是以最短時間到達賽道終點。 游戲 5:Color Conundrum(色彩謎題) 所選標簽:rule: match, rule: time limit, field: roughness, on pressed: turn 描述:在這款游戲中,玩家控制一個在崎嶇地形中導航的角色,同時需要匹配顏色。角色自動向前移動,玩家可以通過按下按鈕來左右轉向。目標是在時間耗盡前盡可能多地匹配顏色,同時避開路上的障礙物和敵人。

      有了游戲名稱、所選標簽和游戲描述,就可以挑選有趣的游戲并將其作為游戲創意。

      以游戲 2 "Pinball Panic" 為例。在布滿釘子和敵人的彈球臺式場地中,玩家按下按鈕發射彈丸,彈丸在釘子間彈射來消滅敵人。巧妙控制彈射球擊中敵人可能很有趣,也許可以加入彈球翻板來發射球。

      游戲 3 "Springy Strings" 如何?在無重力空間中,彈簧角色通過彈射障礙物和敵人來導航,或許是通過踢擊或揮臂推進。

      游戲 5 "Color Conundrum" 設想了一款俯視游戲,玩家角色在崎嶇地形中導航,通過按下按鈕左右轉向來匹配顏色,同時收集同色道具,并避開障礙物和敵人。

      如果 ChatGPT 還能實現游戲代碼就太方便了,但目前這顯然還不可行。雖然當提示"用 p5.js 實現游戲 1"時,它確實會輸出一些代碼,但無法準確反映游戲機制。

      將游戲機制標簽教給 ChatGPT 并讓其進行組合,可以作為頭腦風暴游戲創意基礎的一個好方法。ChatGPT 似乎很適合這類頭腦風暴應用。

      AI 聊天機器人能創造新游戲嗎?

      搭載大型語言模型(LLM)的 AI 聊天機器人能夠生成游戲創意并實現代碼。然而,它們的能力仍在發展中,尚不能在沒有人類干預的情況下創建平衡性良好的游戲。不過,最近 LLM 性能的提升使它們已經能夠處理小游戲開發的許多方面。

      GPT-3.5 時代

      GPT-4 于 2023 年 3 月 14 日在 ChatGPT 上線,在此之前使用的是 GPT-3.5。雖然 GPT-3.5 在發布時是一款開創性的 LLM,但不可否認,與更新的高性能 LLM 相比,其輸出質量有所不足。

      使用 GPT-3.5 進行游戲開發面臨以下挑戰:

      • ? 難以構思出足夠詳細、可在算法層面實現的新游戲創意
      • ? 無法有效實現新算法的源代碼

      當被要求生成小游戲創意時,GPT-3.5 只會返回模糊的、泛泛的概念,缺乏實現所需的具體性。而且,即使給出了具體的創意,如果需要新算法,它也很難產出合適的代碼。因此,將 LLM 作為小游戲生成器來使用面臨很大挑戰。

      Claude 3.5 Sonnet 時代

      OpenAI 逐步將 ChatGPT 的模型從 GPT-3.5 更新到 GPT-4 和 GPT-4o,顯著提升了性能。OpenAI 的競爭對手 Anthropic 也更新了其 Claude LLM,于 2024 年 6 月 21 日發布了 Claude 3.5 Sonnet。[^123]

      伴隨 LLM 性能提升的還有將大型參考文檔附加到提示詞的能力,使 LLM 能夠處理各種前置知識。這些在 LLM 性能和功能上的改進在一定程度上幫助克服了上述問題。

      LLM 在生成新創意方面越來越強

      LLM 性能的提升是否直接關聯到創意生成能力的增強尚不清楚。但似乎確實有明顯的改善。此外,通過參考文檔向 LLM 提供關于創意構思方法和期望創意示例的前置知識也變得更加容易。

      當使用 LLM 自動生成一鍵動作小游戲時,此語境下的"創意"指的是新穎有趣的游戲規則。為此,我向 LLM 提供了以下知識:

      • ? 生成游戲創意的頭腦風暴方法 [^124]
      • ? 可分配給單個按鈕的動作描述 [^125]
      • ? 現有自創游戲的規則 [^126]

      結果,結合 Claude 3.5 Sonnet 的高性能,我們成功提高了生成獨特游戲規則的概率。

      LLM 可以通過逐步流程實現新算法

      如上所述,LLM 已經能夠生成合適的游戲規則。下一個挑戰是將這些規則轉化為正確的代碼。

      即使對于最新的高性能 LLM,將游戲規則直接轉化為代碼仍然困難。當從游戲規則開始逐步細化實現方法時,獲得正確代碼的可能性會提高。因此,我在提示詞中指示 LLM 按以下步驟實現游戲:

      1. 1. 從游戲環境、核心機制、玩家交互和挑戰等方面整理游戲規則。
      2. 2. 詳細描述實現所整理游戲規則的游戲對象行為,考慮屬性、初始狀態、形狀、顏色、運動方式和一鍵操控。
      3. 3. 給出實現游戲規則和對象的 JavaScript 骨架代碼。
      4. 4. 使用庫將骨架代碼完善為可玩的游戲。

      我還在提示詞中提供了使用這些步驟實現自創游戲的示例。這種方法有助于向 LLM 傳達我們的期望,進一步改善其輸出質量。

      LLM 難以調整游戲平衡

      高性能 LLM 現在能夠以一定的質量創建游戲主題、規則和相應的源代碼。但它們仍然難以評估所創建游戲的質量并改進其不足之處。

      這里的游戲質量指以下方面:

      • ? 它能作為一個游戲正常運行嗎?是否存在不合理的游戲結束條件或無限循環模式?
      • ? 它有適當的風險與回報嗎?分數和游戲時長是否隨著玩家技能提升而增長?
      • ? 它有趣嗎?游戲玩法是否直觀并能帶來暢快感?

      針對這些問題的改進示例可能包括:

      • ? 規則優化:修改游戲結束條件或得分系統
      • ? 參數調整:改變速度或玩家角色和敵人出現的頻率
      • ? 操控方式改進:修改操控使其更直觀、對玩家壓力更小

      僅靠 LLM 似乎難以處理這些任務。要評判所創建游戲的質量,計算機需要親自游玩實現的游戲并分析結果。雖然超出 LLM 范疇的能夠玩游戲的 AI 已經存在,但計算機能在多大程度上理解人類諸如"暢快感"這類感受還不得而知。

      讓計算機改進游戲的弱點似乎非常具有挑戰性。如果 AI 能夠評判游戲質量,也許可以利用類似強化學習的方式將其作為獎勵。然而,AI 能否適當地改進規則和操控方式,或調整游戲中各種各樣的參數來提升游戲質量,仍然存疑。

      因此,LLM 在小游戲創作中的使用范圍似乎最好限制在 LLM 目前擅長做的方面。也就是說,LLM 僅被期望創建游戲創意和生成實現代碼。生成的代碼和游戲仍然不完美,因此以下任務需要手動完成:

      • ? 修復代碼 bug 和不符合預期的規則
      • ? 改進規則和代碼使游戲可玩
      • ? 添加考慮風險與回報的游戲結束條件和得分系統
      • ? 調整規則和參數使游戲更有趣
      • ? 實現難度遞進并調整難度曲線

      考慮到這一點,使用 LLM 似乎并沒有顯著減少工作量。然而,LLM 實現的代碼偶爾會產生有趣的行為。因此,它仍然可以作為創建游戲創意基礎的"玩具"來使用。

      使用 LLM 的"生成重擲游戲開發"

      通過這種方式使用 LLM,可以反復生成游戲,直到創建出符合你偏好的游戲,然后手動完善它。讓我們將這個過程稱為"生成重擲游戲開發"(Generative Reroll Game Development)。

      以下是生成重擲游戲開發的一個例子。我們使用 Claude 3.5 Sonnet 作為 LLM,提示詞和前置知識存儲在倉庫中。[^127]

      當給定主題"脆弱的柱子"時,提示詞建議了以下游戲:

      Pillar Paraglider(柱間滑翔):控制一個在脆弱柱子間飛行的滑翔翼。滑翔翼持續下降。按下按鈕可以上升,但每次按壓也會發出可能損壞附近柱子的沖擊波。核心機制:在上升與保護柱子之間取得平衡。

      在細化和實現這個創意后,我們創建了游戲。[^128] 這是 Claude 的直接輸出。

      按下按鈕后,紅色玩家角色上升,同時發出圓形沖擊波。沖擊波會摧毀柱子。雖然看起來深受 Flappy Bird 的影響,但實現的行為相當有趣。

      然而,這個游戲有幾個明顯的問題:

      • ? 太簡單了。反復按下按鈕可以用沖擊波清除柱子。即使玩家角色到達屏幕頂部或底部也不會游戲結束。
      • ? 得分系統過于簡單。分數僅基于飛行距離,因此冒險行為不會帶來更高的分數。
      • ? 沒有實現最初的核心機制。本意是在上升與保護柱子之間取得平衡,但沒有這樣實現。而且,忠實實現這一機制可能會導致沖擊波碰撞檢測范圍過大的壓力型游戲。

      在生成重擲游戲開發中,關鍵過程是如何將這些具有有趣行為的游戲改進為真正有趣的游戲。

      對于這個游戲,我做了以下改動:

      • ? 影響所有方向的圓形沖擊波太過強大,因此我為玩家角色添加了方向性,將沖擊波限制在其前方的一個窄角度內。此外,沖擊波現在只摧毀直接命中的柱子部分,而不是整根柱子。我還實現了玩家角色觸碰屏幕頂部或底部時的游戲結束條件。
      • ? 為摧毀柱子的每個部分給予分數。還實現了連續摧毀的分數倍增器,激勵玩家冒險飛向柱子以獲取更高分數。
      • ? 我放棄了原來的核心機制。一般來說,關于"破壞"的游戲比關于"避免破壞"的游戲更有趣。

      改進后的游戲可以在 [^129] 中看到。


      WAVY BIRD 截圖

      游戲演變為用沖擊波在柱子上打洞來前進。雖然可能稍顯困難,但它比初始版本實現了更好的風險與回報平衡,成為了一款更完整的游戲。

      改進版本與原始代碼之間的差異詳見 [^130]。雖然看起來原始代碼所剩無幾,但原始框架為修改提供了有用的參考,比從零開始要輕松得多。

      添加了音效和標題的完成版本可在 [^131] 中體驗。倉庫 [^127] 中包含大量通過類似流程開發的游戲,供參考。

      這就是目前使用 LLM 的生成重擲游戲開發的現狀。這個過程是否比人類自己構思創意并傳統方式實現更容易,還有待討論。然而,選擇 LLM 建議的游戲并想方設法使其變得有趣的開發過程,與傳統開發過程相比提供了不同類型的樂趣。在生成重擲游戲開發中,同時享受游戲開發和用于生成的提示詞開發/改進的并行過程也很重要。

      未來,我們或許只需告訴 LLM "創建一個有趣的游戲",它就能返回一個實現完善的好的游戲。目前,通常需要數十次"重擲"才能獲得一個具有有趣行為的游戲,成功率相當低。然而,用以前的 LLM 幾乎不可能獲得任何有趣的產出,泛泛的、缺乏靈感的游戲是常態。得益于過去一年左右 LLM 的進化,我們現在能夠生成至少感覺上有些新意的東西,這是一個積極的信號。

      如果 LLM 繼續以這種速度進化,創意的質量將會提高,它們也將能更準確地將這些創意實現為代碼。而且,當我們指出上述問題時,LLM 也許能夠相應地修改代碼。這可能導致通過更少的重擲和更簡單的改進就能獲得可玩的游戲。然而,未來的 LLM 是否會穩步提升性能以達到這些能力,目前尚不確定。截至 2024 年,LLM 性能提升的速率似乎正在放緩。

      利用 AI 聊天機器人的游戲開發未來

      利用 AI 聊天機器人的游戲開發尚未成為完全自動化的過程,但它蘊含著新的可能性。目前,AI 聊天機器人有能力生成具有有趣行為的"玩具",有效的流程是由人類將這些"玩具"精煉為完整的游戲。

      未來,如果 LLM 性能持續提升,有望生成更高質量的游戲創意和代碼。然而,游戲平衡調整和趣味性評估等方面——這些創意性工作——在可預見的未來可能仍需人類介入。

      "生成重擲游戲開發"提供了一種全新的、與眾不同的游戲開發樂趣。基于 LLM 生成的創意和代碼來構建游戲,結合人類的創造力,帶來了新的發現和驚喜。

      隨著 LLM 的進化,我們可以期待這些開發方法進一步發展。對于小游戲開發者而言,AI 聊天機器人有望開啟創造力的大門。

      結語

      我們圍繞小游戲開發探討了各種話題,從它帶來的樂趣、創作方法,到利用 AI 進行自動生成的潛力。

      創建和游玩小游戲都很簡單。近年來,隨著幻想主機(fantasy console)和游戲引擎的出現,游戲創作的環境變得越來越豐富。面向初學者的教程和文檔也非常充足,入門之簡單令人驚訝。

      游戲創作完成后,將其發布到網上觀察反應也是一種樂趣。參加 Game Jam 也很有意思。在這些場合中,分享自己創作的游戲并獲取反饋,能夠進一步提升你的游戲開發技能。

      如果這篇文章激發了哪怕一絲興趣,我鼓勵你跟隨突然閃現的靈感,試著做一款簡單的游戲。新的發現和樂趣一定在等著你。

      引用鏈接

      [1]Joys of Small Game Development: https://abagames.github.io/joys-of-small-game-development-en/

      [2]CC BY 4.0: https://creativecommons.org/licenses/by/4.0/deed.en

      [3]joys-of-small-game-development-en: https://github.com/abagames/joys-of-small-game-development-en

      [4]ABA Games: http://www.asahi-net.or.jp/~cs8k-cyu/

      [5]![TIMBER TEST](https://github.com/abagames/crisp-game-lib-11-games/raw/main/docs/timbertest/screenshot.gif): https://abagames.github.io/crisp-game-lib-11-games/?timbertest

      [6]![C NODES](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/cnodes/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?cnodes

      [7]![action-mini-game mechanic tags](https://abagames.github.io/action-mini-game-mechanic-tags/twitter_card_image.png): https://abagames.github.io/action-mini-game-mechanic-tags/index.html

      [8]![THUNDER](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/thunder/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?thunder

      [9]![CYWALL](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/cywall/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?cywall

      [10]![DIVARR](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/divarr/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?divarr

      [11]![JUMP ON](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/jumpon/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?jumpon

      [12]![NS CLIMB](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/nsclimb/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?nsclimb

      [13]![LADDER DROP](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/ladderdrop/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?ladderdrop

      [14]![NUMBER LINE](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/numberline/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?numberline

      [15]![NUMBER BALL](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/numberball/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?numberball

      [16]![FROOOOG](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/froooog/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?froooog

      [17]![PIN CLIMB](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/pinclimb/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?pinclimb

      [18]![SQUARE BAR](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/squarebar/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?squarebar

      [19]![TAPE J](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/tapej/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?tapej

      [20]![EMBATTLED](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/embattled/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?embattled

      [21]![REFLECTOR](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/reflector/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?reflector

      [22]![BAMBOO](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/bamboo/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?bamboo

      [23]![CHARGE BEAM](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/chargebeam/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?chargebeam

      [24]![LASER FORTRESS](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/laserfortress/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?laserfortress

      [25]![SHINY](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/shiny/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?shiny

      [26]![SCRAMBIRD](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/scrambird/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?scrambird

      [27]![TILTED](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/tilted/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?tilted

      [28]![UP SHOT](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/upshot/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?upshot

      [29]![BOMB UP](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/bombup/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?bombup

      [30]![ORBIT MAN](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/orbitman/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?orbitman

      [31]![ARCFIRE](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/arcfire/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?arcfire

      [32]![TURBULENT](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/turbulent/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?turbulent

      [33]![SUB JUMP](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/subjump/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?subjump

      [34]![MIRROR FLOOR](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/mirrorfloor/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?mirrorfloor

      [35]![LIFT UP](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/liftup/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?liftup

      [36]![REBIRTH](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/rebirth/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?rebirth

      [37]![R WHEEL](https://github.com/abagames/crisp-game-lib-games/raw/main/docs/rwheel/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?rwheel

      [38]![springcar](https://raw.githubusercontent.com/abagames/jsgame256/master/docs/springcar.png): https://abagames.github.io/jsgame256/springcar.html

      [39]![diff-tween](https://abagames.github.io/diffi-tween/screenshot.png): https://abagames.github.io/diffi-tween/

      [40]![ref_collision screenshot](https://abagames.github.io/crisp-game-lib-games/ref_collision/screenshot.gif): https://abagames.github.io/crisp-game-lib-games/?ref_collision

      [41]![BOMB SNAKE](https://raw.githubusercontent.com/abagames/peekpoke/main/docs/screenshot.gif): https://abagames.github.io/peekpoke/bombsnake/

      [42]![pixel-art-gen](https://abagames.github.io/joys-of-small-game-development-en/images/ships.gif): https://abagames.github.io/pixel-art-gen/index.html?ships

      [43]![Short VGM generator](https://raw.githubusercontent.com/abagames/short-vgm-generator/main/docs/screenshot.png): https://abagames.github.io/short-vgm-generator/build/

      [44]![slickslack_screenshot](https://abagames.github.io/slickslack/screenshot.gif): https://abagames.github.io/slickslack/index.html

      [45]![HAKOSAN](https://raw.githubusercontent.com/abagames/hakosan/main/docs/screenshot.gif): https://abagames.github.io/hakosan/build/

      [46]![Magnet Blocks](https://raw.githubusercontent.com/abagames/crisp-game-lib-11-games/main/docs/magnetblocks/screenshot.gif): https://abagames.github.io/crisp-game-lib-11-games/?magnetblocks

      特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。

      Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

      相關推薦
      熱點推薦
      “砦”不讀chái,也不讀cǐ,我出過丑,從那不再犯錯了!

      “砦”不讀chái,也不讀cǐ,我出過丑,從那不再犯錯了!

      未央看點
      2026-05-02 19:51:04
      4個去中國化最徹底的國家,一個已全盤西化,一個正試圖恢復漢字

      4個去中國化最徹底的國家,一個已全盤西化,一個正試圖恢復漢字

      你是我心中最美星空
      2026-04-26 07:15:09
      快滅國了卻執意和中國斷交,“抱大腿”無望又求援,中方:不慣著

      快滅國了卻執意和中國斷交,“抱大腿”無望又求援,中方:不慣著

      黑翼天使
      2026-03-30 13:23:53
      世上最失敗4大工程:損失慘重,中國占倆!卻說有意料之外效果?

      世上最失敗4大工程:損失慘重,中國占倆!卻說有意料之外效果?

      三毛看世界
      2026-04-17 16:43:17
      夏洛特公主11歲生日照曝光:棕發及腰酷似父親威廉

      夏洛特公主11歲生日照曝光:棕發及腰酷似父親威廉

      吃青菜長高
      2026-05-02 21:57:27
      iPhone 18 Pro將迎系列史上最大相機硬件升級,可變光圈僅是“冰山一角”

      iPhone 18 Pro將迎系列史上最大相機硬件升級,可變光圈僅是“冰山一角”

      環球網資訊
      2026-04-30 13:43:04
      爆冷!CBA前二熱身對決,上海4分惜敗,懷特塞德復出成關鍵?

      爆冷!CBA前二熱身對決,上海4分惜敗,懷特塞德復出成關鍵?

      生活新鮮市
      2026-05-02 17:20:09
      斬殺中年男性的三件套:陽痿、失業和心梗!

      斬殺中年男性的三件套:陽痿、失業和心梗!

      燈錦年
      2026-04-30 10:04:05
      朱溫被殺前夜,叫兒媳王氏前來服侍,兒媳告誡:小心你父親要殺你

      朱溫被殺前夜,叫兒媳王氏前來服侍,兒媳告誡:小心你父親要殺你

      銘記歷史呀
      2026-05-02 00:11:01
      橄欖油質量大抽檢:只有兩款拿到 “非常好”,多款產品被評為不合格

      橄欖油質量大抽檢:只有兩款拿到 “非常好”,多款產品被評為不合格

      新浪財經
      2026-05-01 11:41:24
      回首才發現,原來馬斯克早就在中國埋下“重磅炸彈”,且效果顯著

      回首才發現,原來馬斯克早就在中國埋下“重磅炸彈”,且效果顯著

      青煙小先生
      2026-04-04 10:18:44
      她才是董宇輝背后的女人,一臉旺夫相,手握大權,卻從不主動露臉

      她才是董宇輝背后的女人,一臉旺夫相,手握大權,卻從不主動露臉

      以茶帶書
      2026-03-09 16:18:07
      伊朗給全球上了一課,世界軍事排名,將更新!

      伊朗給全球上了一課,世界軍事排名,將更新!

      深度報
      2026-04-30 22:47:56
      俄烏戰爭主動權易手!烏軍無人機炸穿俄本土,俄被逼到全民防空

      俄烏戰爭主動權易手!烏軍無人機炸穿俄本土,俄被逼到全民防空

      知兵
      2026-05-02 16:12:36
      湖媒曬圖打臉15位專家!整整1085天啊,湖人終于贏下系列賽

      湖媒曬圖打臉15位專家!整整1085天啊,湖人終于贏下系列賽

      球童無忌
      2026-05-02 14:32:42
      羅杰斯:利雅得勝利不只是C羅,我們的目標是擊敗他們

      羅杰斯:利雅得勝利不只是C羅,我們的目標是擊敗他們

      懂球帝
      2026-05-02 16:13:35
      做完手術人就廢了,這5種手術不需要做,別讓無知害了自己

      做完手術人就廢了,這5種手術不需要做,別讓無知害了自己

      醫學科普匯
      2026-01-29 06:25:03
      2026娛樂圈男明星咖位大洗牌:歐豪難進前5,肖戰第2,第1沒爭議

      2026娛樂圈男明星咖位大洗牌:歐豪難進前5,肖戰第2,第1沒爭議

      不似少年游
      2026-04-17 19:35:14
      菲戈也來看“蘇超”了,現身南京奧體中心體育場,向球迷比心

      菲戈也來看“蘇超”了,現身南京奧體中心體育場,向球迷比心

      揚子晚報
      2026-05-02 21:15:27
      蘿莉島大雷出現!比想象中炸裂,牽扯多國總統,難怪愛潑斯坦必死

      蘿莉島大雷出現!比想象中炸裂,牽扯多國總統,難怪愛潑斯坦必死

      離離言幾許
      2026-02-02 21:16:35
      2026-05-02 22:36:49
      教你畫像素畫 incentive-icons
      教你畫像素畫
      像素畫教程
      2462文章數 12217關注度
      往期回顧 全部

      游戲要聞

      超燃!崩鐵玩家全員集結對抗吼姆王,幻月新游戲見證團隊的力量

      頭條要聞

      香港兩名6旬男女碼頭長凳上做不雅行為 被人拍下傳網上

      頭條要聞

      香港兩名6旬男女碼頭長凳上做不雅行為 被人拍下傳網上

      體育要聞

      休賽期總冠軍,輪到休斯頓火箭

      娛樂要聞

      高圓圓趙又廷游三亞 牽手逛街好甜蜜

      財經要聞

      雷軍很努力 小米還是跌破了30港元大關

      科技要聞

      AI熱潮耗盡庫存,Mac Mini起售調高200美元

      汽車要聞

      新紀錄!零跑汽車4月交付達71387臺

      態度原創

      家居
      房產
      本地
      公開課
      軍事航空

      家居要聞

      靈動實用 生活藝術場

      房產要聞

      五一樓市徹底明牌!塔尖人群都在重倉凱旋新世界

      本地新聞

      用青花瓷的方式,打開西溪濕地

      公開課

      李玫瑾:為什么性格比能力更重要?

      軍事要聞

      特朗普:對伊戰事結束 無限期延長停火

      無障礙瀏覽 進入關懷版 主站蜘蛛池模板: 一区二区三区鲁丝不卡| 久久99国产一区二区三区| 久久婷婷五月综合色欧美| 日本无遮挡真人祼交视频| 国产成人精品亚洲日本对白优播| 九九热视频精选在线播放| 最新亚洲av女人的天堂| 夜夜嗨av一区二区| 亚洲色成人777777无码| 欧美最猛性xxxxx大叫| 亚洲第一狼人天堂网伊人| 亚州国产成人无码人妻爽爽| 国产亚洲精品精华液| 欧美日韩视频综合一区无弹窗| 亚洲小视频| 四虎影库成人精品| 91啪啪| 亚洲国产成人精品女人久| 亚洲AV激情无码专区在线播放| 国产成人啪视频一区二区三区| 久久精品不卡一区二区| 熟女av在线| 曾医生mp4| 日韩人妻无码精品久久| 91麻豆视频国产一区二区| 国产欧美日韩久久va| 国产精品久久久久久99人妻精品| 亚洲永久精品ww47永久入口| av中文天堂| 国内成人综合| 亚洲一区成人在线视频| 男女猛烈无遮挡免费视频| 开心婷婷五月激情综合社区 | 亚洲色涩| 全部无卡免费的毛片在线看| 国产一区二区精品自拍| 国产免费视频一区二区 | 999精品免费视频| 精品无码一区在线观看| 91视频入口| 亚洲第一香蕉视频|