在脚本里写入如下代码
## Map Panel ## 地图面板 extends PanelContainer # 方向列表 const DirectionList = [ Vector2.LEFT, Vector2.RIGHT, Vector2.UP, Vector2.DOWN ] # 产生下一个方向的砖块的几率 const Chance = 0.4 export var map_size = Vector2(40, 40) # 地图大小 export var tile_size = Vector2(32, 32) # 砖块大小 export var separate = Vector2(8, 8) # 每个 tile 分隔的距离 onready var scroll_container = $ScrollContainer # 滚动条容器 onready var container = $ScrollContainer/Container # 添加 tile 的容器 # 地图 tile 位置列表 var map_tile_pos_list = {} #============================== # 内置方法 #============================== func _ready() -> void: # 每次随机不一样 randomize() # 初始化地图 init_map() # tile 偏移距离 var offset_size = tile_size + separate # tile 容器大小 container.rect_min_size = offset_size * map_size + Vector2.ONE * 600 # 添加 tile var tile_pos_list = map_tile_pos_list.keys() var tile_list = [] for pos in tile_pos_list: var button = Button.new() button.rect_position = pos * offset_size button.rect_size = tile_size if map_tile_pos_list[pos] == 1000: print(button) container.add_child(button) tile_list.push_back(button) # 将起始位置的 tile 设置为红色 var first_tile = tile_list[0] as Button first_tile.modulate = Color.red # Scroll 容器滚动条的值发生改变的时候 # 滚动条滚动到第一个 tile 的位置 yield(scroll_container.get_h_scrollbar(), "changed") scroll_container.scroll_horizontal = int(first_tile.rect_position.x - 200) scroll_container.scroll_vertical = int(first_tile.rect_position.y - 200) #============================== # 自定义方法 #============================== ## 初始化地图 func init_map(): # 起始位置在地图中间 var start_pos = map_size / 2 add_pos(start_pos, 1000) # 开始延伸向四周 for dir in DirectionList: next_tile(start_pos, dir) ## 下一个瓷砖 ## @pos 移动前的位置 ## @dir 移动的方向 ## @count 递归次数 func next_tile(pos: Vector2, dir: Vector2, count=0): for temp_dir in DirectionList: if temp_dir == dir * -1: # 方向不能向反方向移动 # 当前 dir 是向左移动,即 dir 为 Vector2.LEFT # 那么 temp_dir 就不能向右移动,即不能为 Vector2.RIGHT continue # 随机 `Chance` 的几率添加下一个 var rand = randf() if rand <= Chance: var temp_pos = pos + temp_dir add_pos(temp_pos) # 开始进行添加下一个位置 if valid_next_pos(temp_pos): # 防止堆栈溢出,超过 1024 则错误 if count > 1000: return next_tile(temp_pos, temp_dir, count+1) ## 返回当前位置还能否向其他位置移动 ## @pos 位置 func valid_next_pos(pos: Vector2) -> bool: var left = pos + Vector2.LEFT var right = pos + Vector2.RIGHT var up = pos + Vector2.UP var down = pos + Vector2.DOWN if (has_pos(left) && has_pos(right) && has_pos(up) && has_pos(down) ): # 所有方向已经存在,则返回 false return false return true ## 添加位置 ## @pos 位置 ## @type 地图 tile 类型 func add_pos(pos: Vector2, type = 1) -> void: if pos > Vector2.ZERO && pos <= map_size: map_tile_pos_list[pos] = type ## 是否已经有了这个位置 func has_pos(pos: Vector2) -> bool: return map_tile_pos_list.has(pos)
下图是生成后的效果图: