首页 > 网络 > 网游资讯

程序员用12小时复刻《羊了个羊》,代码已开源

常驻编辑 网游资讯 2022-09-22 死局   数据结构   关卡   队列   数组   程序员   图案   窗口   小时   模式   代码   朋友   游戏
Axu拜客生活常识网

  • 牌堆模式A

Axu拜客生活常识网

  • 牌堆模式B

Axu拜客生活常识网

  • 牌堆模式C

Axu拜客生活常识网

02 牌堆的数据结构

我将其定义为MContainerBase基类Axu拜客生活常识网

#MContainerBase
extends Node2D
class_name MContainerBase

func _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] = null

        for 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的三维数组,我们可以使用一切方法构造想要的排队形状:柱形、条形、甚至金字塔形。这都不会影响后面程序的实现。Axu拜客生活常识网

项目中为了增加这个“大方块”的多样性,我还给它设置了如下的“遮罩”,这就是游戏中CSDN文字的由来。当然我们还可以通过“遮罩”来自由定义窗口牌,这部分就请大家自由发挥了。Axu拜客生活常识网

# 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],
]

Axu拜客生活常识网

03 如何检测和更新可拾取的牌

三种牌堆模式分别派生自MContainerBase,并对应着如下三种检测方式:Axu拜客生活常识网

  • 牌堆模式A:仅检测自己正上方是否有牌
#1 Cover 1
extends MContainerBase

func 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 2
extends MContainerBase

func 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 4
extends MContainerBase

func 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中,这三种牌堆模式还可以通过场景节点制作成预制体,这样关卡设计师就可以轻松地制作出美观的关卡了。Axu拜客生活常识网

Axu拜客生活常识网

Axu拜客生活常识网

03 如何生成新关卡

简单了解游戏规则后,我们就不难推导出,每个关卡能被通过的一个必要条件就是每一种图案的总数,必须能被3整除。实现方法如下:Axu拜客生活常识网

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对应着这一关该图案出现的“对数”(此处1对等于3个)。按照value乘以3的数量存入数组tiles(下文称之为:待发牌池),然后把待发牌池中的元素打乱顺序,等待“发牌”。

相关阅读:

  • 新华社聚焦中国足球欠薪:“死局”能否“做活”?
  • 苏群专栏:郭艾伦这个“死局”到底怎么破
  • 关于对羊了个羊的一点感受
  • 与羊宣战:别再缴纳智商税了,相公们
  • 爆火数天后,“羊了个羊”果然翻车了
  • 羊了个羊,通关秘籍,关键在于找规律
  • 羊了个羊,火了又凉?
  • 从目前楼市股市现状说开去,展望2023年股市
  • data什么意思(数据结构中data是什么意思)
  • 「数据结构之字典树Trie」C语言版本实现
    • 网站地图 |
    • 声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不做权威认证,如若验证其真实性,请咨询相关权威专业人士。