羊了個羊,但是Python簡(li)單(pu)版

語言: CN / TW / HK

大家好,歡迎來到 Crossin的程式設計教室 !

要說最近最熱門的遊戲,那肯定是《羊了個羊》沒跑了。

連續上了好幾天熱搜,火到連央視都來提醒謹防有人利用遊戲之名詐騙。

但遊戲爆火的另一面,也是無數玩家對於第二關難度的吐槽和不滿。

如果你也像我一樣,因為過不了關而不爽,不如自己用 Python 來寫一個簡單版,想過幾關過幾關。

甚至還可以調個無解關卡去霍霍其他人

我這個版本不僅難度簡單,程式碼也很簡單,一共不到100行。程式碼已開源:

http:// python666.cn/c/8

可下載,可修改,可商用,但公開發布需署名來源: Crossin的程式設計教室

做了一個同樣簡單的整活影片,供大家一樂:

稍微解釋一下思路和程式碼:

1.

遊戲用了 pygame-zero 這個庫(所以才能這麼少的程式碼實現),執行前需要安裝 pgzero 庫:

pip install pgzero

(或者通過 IDE 安裝)

2.

執行時需要帶上專案裡的 imagesmusic 資料夾(你可以替換裡面的圖片和音樂)

3.

每一張牌是一個 Actor 物件(相當於一般遊戲開發中的精靈類),具有 種類 (12種各12張)、 層級狀態 (不可點/可點/已收集)等屬性。

開局時隨機打亂後襬放,根據種類顯示不同圖片。

除了最上層的牌可點,其餘均不可點。

# 初始化牌組,12*12張牌隨機打亂
ts = list(range(1, 13))*12
random.shuffle(ts)
n = 0
for k in range(7):    # 7層
    for i in range(7-k):    #每層減1行
        for j in range(7-k):
            t = ts[n]        #獲取排種類
            n += 1
            tile = Actor(f'tile{t}')       #使用tileX圖片建立Actor物件
            tile.pos = 120 + (k * 0.5 + j) * tile.width, 100 + (k * 0.5 + i) * tile.height * 0.9    #設定位置
            tile.tag = t            #記錄種類
            tile.layer = k          #記錄層級
            tile.status = 1 if k == 6 else 0        #除了最頂層,狀態都設定為0(不可點)這裡是個簡化實現
            tiles.append(tile)

4.

判斷滑鼠點選的位置是否處於某張可點的牌內,是的話就從所有牌列表中移除,加到下方牌堆列表裡。

然後遍歷與這張牌有重疊的下一層牌,對於每張下層牌,反過來檢查是否有其他上層牌覆蓋它,如果沒有,就把它變成可點。

for tile in reversed(tiles):    #逆序迴圈是為了先判斷上方的牌,如果點選了就直接跳出,避免重複判定
    if tile.status == 1 and tile.collidepoint(pos):
        # 狀態1可點,並且滑鼠在範圍內
        tile.status = 2
        tiles.remove(tile)
        diff = [t for t in docks if t.tag != tile.tag]    #獲取牌堆內不相同的牌
        if len(docks) - len(diff) < 2:    #如果相同的牌數量<2,就加進牌堆
            docks.append(tile)
        else:             #否則用不相同的牌替換牌堆(即消除相同的牌)
            docks = diff
        for down in tiles:      #遍歷所有的牌
            if down.layer == tile.layer - 1 and down.colliderect(tile):   #如果在此牌的下一層,並且有重疊
                for up in tiles:      #那就再反過來判斷這種被覆蓋的牌,是否還有其他牌覆蓋它
                    if up.layer == down.layer + 1 and up.colliderect(down):     #如果有就跳出
                        break
                else:      #如果全都沒有,說明它變成了可點狀態
                    down.status = 1
        return

5.

下方牌堆達到7張為失敗,上方沒有剩牌則為勝利

# 達到7張,失敗
if len(docks) >= 7:
    screen.blit('end', (0, 0))
# 沒有剩牌,勝利
if len(tiles) == 0:
    screen.blit('win', (0, 0))

6.

本demo距離《羊了個羊》尚有改進空間,有興趣的小夥伴可自行嘗試擴充套件,包括但不限於:

  • 道具功能
  • 增加收牌的動畫效果(可以用 pgzero 提供的 animate 方法)
  • 更多的關卡布局
  • 打包成exe
  • 遊戲排行榜
  • 當然還有遊戲最最核心的部分:觀看廣告

程式碼已開源:

http:// python666.cn/c/8

可下載,可修改,可商用,但公開發布需署名來源: Crossin的程式設計教室

如果喜歡的話,感謝幫忙 點贊轉發 ,你的支援是我持續更新的動力!

我是Crossin,我們下個遊戲見~

對了,哦,對了,如果你想學Python,記得來看下我的《人人都能學Python》系列:

零基礎python入門 圖文系列教程: http:// python666.cn