在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    程序員用12小時復刻《羊了個羊》,代碼已開源

    編者按:前段時間,超休閑三消游戲《羊了個羊》爆火,不少網友表示游戲第二關難度過高,甚至猜測「根本沒有通關的解法」。而本文作者 @開發(fā)游戲的老王 在嘗試復刻游戲之后,提出了一個猜想:過高的難度,也許源于代碼層面的瑕疵。

    以下為正文:

    昨天有朋友和我說:“最近有個叫《羊了個羊》的游戲爆火,就是太難玩了,你能復刻一個不?”

    話說上次玩休閑游戲還是在幾年前,但是朋友之托必須赴湯蹈火啊,二話不說,開整!然而,沖動是魔鬼,直到此時此刻,老王也沒能親手玩一局原版游戲,不知道是游戲入口設計得太隱蔽還是網絡加載太慢,無論手機端還是PC端,游戲都停留在如下界面。

    所以本次游戲的復刻,完全是基于各視頻網站云觀摩的結果,好在游戲的玩法不是特別難理解。復刻使用的開發(fā)工具是Godot Engine(使用其它工具開發(fā)原理也是相似的),目前項目已經開源到了GitCode:

    Godot版《羊了個羊》:

    https://gitcode.net/hello_tute/SheepASheep

    接下來我將通過臨摹游戲的方式推測一下這個小游戲的實現(xiàn)原理,本文主要面向對游戲開發(fā)有興趣的朋友,歡迎大家多提寶貴意見。

    01 玩法

    第一眼看到《羊了個羊》,老王首先想到當年的《連連看》,不過有網友爆料,該游戲“借鑒”了《3tiles》。瞄了眼《3tiles》,是比較相似。說心里話,這個游戲的玩法并沒有什么過于出眾的地方,算是個中規(guī)中矩的“低卡路里”休閑游戲。

    之所以成為話題作品,主要就是因為它的第2關極其低的通關率,一下子激起了眾多玩家的挑戰(zhàn)欲望。

    而時至今日這個“低通關率”也被網絡上的眾多玩家揭秘,第2關其實大概率上本身就是個死局。是程序員故意挖坑設了死局么?先賣個關子,我們先聊聊游戲的開發(fā),然后您自己就會有答案了。

    02 實現(xiàn)概要

    游戲的整體很簡單,但其中有幾個實現(xiàn)的重點需要注意:

    • 牌堆數據結構的實現(xiàn)
    • 如何檢測和更新可拾取的牌

    先做個小定義,一個牌堆中可被拾取的牌以下將簡稱其為:“窗口牌”。

    01 牌堆的結構

    最初,我還真被這復雜的牌堆結構蒙住了,但仔細研究一番發(fā)現(xiàn),無論多么復雜的牌堆,其實都是由如下三種牌堆模式組合拼湊而成的:

    • 藍圈圈出的牌堆模式A:上面1張牌只擋住下面1張牌;同時下面的牌僅被上面1張牌擋住。只要上面的1張牌被取走,下面的牌就成為窗口牌;
    • 紅圈圈出的牌堆模式C:上面1張牌可以擋住下面4張牌;同時下面的牌可能被上面4張牌擋住,一張牌只有它上面的4張牌都被取走,它自己才成為窗口牌。

    雖然上圖中體現(xiàn)不是很明顯,但不難猜想出,第三種牌堆模式B 的存在,那就是:

    • 上面1張牌可以擋住下面2張牌;同時下面的牌可能被上面2張牌擋住,一張牌只有它上面的2張牌都被取走,它自己才成為窗口牌。

    對于牌堆模式A,有些朋友會迫不及待地用“隊列”或“?!睂崿F(xiàn)它,這樣做有兩個缺點:

    • 邏輯上牌堆模式A的窗口牌也可能是2維的,如果用隊列實現(xiàn)就限制了它的靈活性;
    • 牌堆模式B和C都不好用隊列實現(xiàn),所以想追求數據結構的統(tǒng)一,還要另求他法。

    實際上無論牌堆模式A、B還是C,都不過是3維數組結構,上圖中模式A看起來特殊,無非是它的x,y維度都為1罷了。而三種牌堆的區(qū)別也無非就是當一張窗口牌被取走,檢查牌堆是否出現(xiàn)新的窗口牌的方法罷了。

    • 牌堆模式A
    • 牌堆模式B
    • 牌堆模式C

    02 牌堆的數據結構

    我將其定義為MContainerBase基類

    #MContainerBaseextends Node2Dclass_name MContainerBasefunc _ready:add_to_group(name)add_to_group(“game”)var Mask = FileReader.read(mask_file,null)box.resize(size_x)for i in range(size_x):box[i] = box[i].resize(size_y)for j in range(size_y):box[i][j] = box[i][j].resize(size_z)for k in range(size_z):if Mask == null or Mask[i][j] == 1:box[i][j][k] = add_tile(i,j,k,get_parent.distribute_face)else:box[i][j][k] = nullfor x in range(size_x):for y in range(size_y):for z in range(size_z):check_is_on_top(x,y,z)

    最基礎的牌堆就是一個 x*y*z的三維數組,我們可以使用一切方法構造想要的排隊形狀:柱形、條形、甚至金字塔形。這都不會影響后面程序的實現(xiàn)。

    項目中為了增加這個“大方塊”的多樣性,我還給它設置了如下的“遮罩”,這就是游戲中CSDN文字的由來。當然我們還可以通過“遮罩”來自由定義窗口牌,這部分就請大家自由發(fā)揮了。

    # S形遮罩[[0,0,0,0,0],[0,0,0,0,0],[1,1,1,0,1],[1,0,1,0,1],[1,0,1,1,1],]

    03 如何檢測和更新可拾取的牌

    三種牌堆模式分別派生自MContainerBase,并對應著如下三種檢測方式:

    • 牌堆模式A:僅檢測自己正上方是否有牌

    #1 Cover 1extends MContainerBasefunc check_is_on_top(x,y,z):if has_tile(x,y,z):if not has_tile(x,y,z + 1) :(box[x][y][z] as MTile).set_is_on_top(true)

    • 牌堆模式B:檢測自己上方兩方位是否有牌

    #1 Cover 2extends MContainerBasefunc check_is_on_top(x,y,z):if has_tile(x,y,z):if z%2 == 0:if not has_tile(x,y,z + 1) and not has_tile(x – 1 ,y,z + 1):(box[x][y][z] as MTile).set_is_on_top(true)else:if not has_tile(x,y,z + 1) and not has_tile(x + 1 ,y,z + 1):(box[x][y][z] as MTile).set_is_on_top(true)

    • 牌堆模式C:檢測自己上方四方位是否有牌

    #1 Cover 4extends MContainerBasefunc check_is_on_top(x,y,z):if has_tile(x,y,z):if z%2 == 0:if not has_tile(x,y,z + 1) and not has_tile(x – 1 ,y,z + 1) and not has_tile(x,y – 1 ,z + 1) and not has_tile(x – 1,y – 1,z + 1):(box[x][y][z] as MTile).set_is_on_top(true)else:if not has_tile(x,y,z + 1) and not has_tile(x + 1 ,y,z + 1) and not has_tile(x,y + 1 ,z + 1) and not has_tile(x + 1,y + 1,z + 1):(box[x][y][z] as MTile).set_is_on_top(true)

    在Godot中,這三種牌堆模式還可以通過場景節(jié)點制作成預制體,這樣關卡設計師就可以輕松地制作出美觀的關卡了。

    03 如何生成新關卡

    簡單了解游戲規(guī)則后,我們就不難推導出,每個關卡能被通過的一個必要條件就是每一種圖案的總數,必須能被3整除。實現(xiàn)方法如下:

    var tiles = export var initial_tiles = { 0:10, 1:10, 2:10, 3:10, 4:10, 5:10, 6:10, 7:10, 8:10, 9:10, 10:10, 11:10, 12:10, 13:10, 14:10, 15:10}func _init: for key in initial_tiles: var num = initial_tiles[key]*3 for i in range(0,num): tiles.append(key) tiles.shuffle

    其中字典initial_tiles 的key對應著每一種圖案,后面的value對應著這一關該圖案出現(xiàn)的“對數”(此處1對等于3個)。按照value乘以3的數量存入數組tiles(下文稱之為:待發(fā)牌池),然后把待發(fā)牌池中的元素打亂順序,等待“發(fā)牌”。

    01 關于游戲中的坑

    很多朋友抱怨:“程序員故意挖坑制作死關卡”。其實不然,他無須故意挖坑,因為這個游戲本身就有很多“天然的坑”,如果不使勁填坑,它們自然而然就屬于你了。而這里就隱藏了幾個可致命的坑:乍一看,待發(fā)牌池中所有的圖案都可以被3整除那么一定可以通關?那可不一定:

    • 只有桌面牌堆中牌的數量和待發(fā)牌池牌數一致,所有的牌才能“落地”,而游戲中桌面牌堆到底有多少(層)本身就是個迷。并且如果沒猜錯的話,在每一局設計者先要確保牌堆形狀好看,然后再使堆牌數和待發(fā)池的牌數一致。二者哪怕差1個,也會造成死局。
    • 上文說了,桌面牌數和待發(fā)牌池的牌數一致只是過關的必要而非充分條件。即使該條件滿足,如果相對于牌桌上的牌數以及圖案數量,窗口牌數太少,也會造成死局。比如下面這個極端的例子:假設游戲共有 15種花色,而牌桌上只有這個模式A牌堆,它有90張牌。那么玩家只要在連續(xù)7次拾牌時沒有遇到3個相同圖案的牌,就“必死無疑”了。

    其實這個游戲,一方面要控制關卡的難度,另一方面又要保證能通關本身就是一個相當困難的問題(至少老王沒有想出辦法)。

    而設計者反其道而行之,(可能)沒有花力氣去設計算法,把坑留給玩家,得到了極低的通關率,反而制造了話題并形成爆款。

    如此說來,這確實是個抖機靈的“設計”。但老王認為這種“設計”在游戲策劃中是不宜被借鑒的,就像現(xiàn)在市面上泛濫的懸疑劇,開始埋坑無數,吊足觀眾胃口,最后爛尾不了了之一樣,長此以往觀眾(玩家)對于懸疑?。ㄓ螒颍┑男湃胃芯捅幌M殆盡了。

    02 洗牌道具的實現(xiàn)

    洗牌的實現(xiàn)原理很簡單,把當前桌面的牌記錄在一個數組tiles中,當需要洗牌時,先打亂一下數組中牌的順序,然后讓桌面上每一張牌到tiles中重新取一個值。再來個眼花繚亂點的動畫,還真挺像那么回事兒。

    funcshuffle_tiles:tiles.shuffletiles_index = -1funcredistribute_face-> int:tiles_index +=1returntiles[tiles_index]

    03 遮罩文件的讀取

    這里要夸一下Godot Engine,它的很多功能真是方便,比如下面這個str2var它可以簡單粗暴地直接把字符串轉換成對象類型。

    class_nameFileReaderstaticfuncread(path,default_data): vardata = default_data varfile =File.new file.open(path,File.READ) varcontent :String= file.get_as_text ifnot content.empty: data = str2var(content) file.close returndata

    04 對象間的通信

    這個小游戲中存在大量的對象間的通信需求:牌和牌之間、牌和牌堆之間、牌和關卡之間、牌堆和關卡之間。為了快速實現(xiàn)游戲,我大量使用了Godot Engine的Group機制,不得不說Group是Godot Engine最贊的設計之一。

    04 總結

    小游戲《羊了個羊》,從策劃和開發(fā)的角度來看并不困難,然而“瑕疵”竟然能夠成為“噱頭”,也讓人不得不感慨“游戲世界真的一切皆有可能啊”。

    來源:游戲葡萄

    鄭重聲明:本文內容及圖片均整理自互聯(lián)網,不代表本站立場,版權歸原作者所有,如有侵權請聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年9月22日 15:18
    下一篇 2022年9月22日 15:18

    相關推薦

    • 請問秀兒是你嗎什么梗

      簡要回答 秀兒是你嗎這句話其實沒有貶義的含義,這句話的意思是形容內容有趣,優(yōu)秀的意思。 現(xiàn)在很多人喜歡刷視頻,所以很多人會拍一些視頻供大家觀看,有些觀看者會在下面評論,有些人會評論…

      2022年11月27日
    • dnf一鍵拾取(dnf一鍵拾取是全圖的嗎)

      今天小編給各位分享dnf一鍵拾取的知識,其中也會對dnf一鍵拾取是全圖的嗎進行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關注本站,現(xiàn)在開始吧! dnf如何一鍵拾取物品 dnf一鍵…

      2022年11月27日
    • 《寶可夢朱紫》3天銷量破千萬(寶可夢朱紫3天銷量破千萬了)

      開局只能選一種御三家,不能同時擁有全部這是游戲設計的劇情不能更改的。 已經偷跑了寶可夢朱紫將于11月18日正式發(fā)售,而目前已有實體卡帶偷跑御三家進化型終于在泄露了,新葉喵站了起來,…

      2022年11月27日
    • 【周末玩什么】3天銷量破千萬的《寶可夢 朱/紫》,為何被評價為“又爛又好”

      本周推薦《寶可夢 朱/紫》和《第七境》。 本月18號《寶可夢 朱/紫》全球發(fā)售。截至發(fā)稿日,本作的MC媒體均分從79分跌至75分,玩家評分更是只有可憐的2.9分。發(fā)售之初,國內關于…

      2022年11月27日
    • 微軟表示:《GTA6》預計將于2024年發(fā)售

      微軟表示:《GTA6》預計將于2024年發(fā)售 近日,微軟在回應英國競爭與市場管理局(CMA)調查其收購動視暴雪時提到,《GTA6》預計將在2024年發(fā)售。 “備受期待的《GTA6》…

      2022年11月26日
    • 英雄聯(lián)盟手游好玩嗎(英雄聯(lián)盟手游好玩還是端游好玩)

      簡要回答 非常好玩,英雄聯(lián)盟手游這款游戲已經正式的進行公測,這款游戲是以5v5為模式進行對戰(zhàn)的,它是以英雄聯(lián)盟端游為原型進行開發(fā),里面的每一種玩法基本都沿襲了端游的特點。 01 這…

      2022年11月25日
    • 游戲平臺有哪些(游戲平臺有哪些)

      簡要回答 游戲平臺指的是多人通過互聯(lián)網在線游戲的平臺,例如qq游戲,聯(lián)眾世界,浩方電競平臺,VS競技游戲平臺等,只要你下載平臺,下載相關游戲,就能實現(xiàn)對戰(zhàn),擺脫了局域網的限制。 詳…

      2022年11月25日
    • 好玩的塔防游戲(好玩的單機塔防手機游戲)

      簡要回答 對于游戲愛好者來說塔防游戲并不陌生,畢竟很多人一開始玩的就是塔防游戲,比如大家都知道的植物大戰(zhàn)僵尸,而且如今植物大戰(zhàn)僵尸還在大家的視野里面,很多博主也會用植物大戰(zhàn)僵尸玩很…

      2022年11月25日
    • 2022金搖桿獎公布:《艾爾登法環(huán)》獨中四元,成為最大贏家

      2022金搖桿獎全部獎項已經公布,現(xiàn)象級熱門大作《艾爾登法環(huán)》拿下最佳多人游戲,評論家玩家選擇獎,最佳多人游戲,年度終極游戲等四項大獎,成為本次2022金搖桿獎的最大贏家。完整的獲…

      2022年11月25日
    • 世界杯怎么買體育彩票(世界杯怎么買體育彩票玩法)

      2022卡塔爾世界杯已經開賽了,除了廣大球迷外,很多彩民也十分關注比賽進程。據了解,自2012年歐洲杯以來,每逢大型國際足籃球賽事,中國體育彩票會開售冠軍競猜、冠亞軍競猜游戲。那么…

      2022年11月25日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息