Slay the Spire Style Map Generation in Godot 4
unknown
plain_text
a year ago
2.8 kB
415
Indexable
################################################ # Map World ################################################ extends Node2D @onready var map_node = preload("res://map_node.tscn") @onready var map_nodes = $MapNodes func _ready(): var map = MapGenerator.new().generate_map() var map_height = map.size() var map_width = map[0].size() var floors = map for y in map_height: for x in map_width: var n = map_node.instantiate() n.room_data = floors[y][x] map_nodes.add_child(n) ################################################ # Map Generator ################################################ extends Node class_name MapGenerator # https://kosgames.com/slay-the-spire-map-generation-guide-26769/ var distance_x = 60 # x distance between nodes var distance_y = 50 # y distance between nodes var wackiness = Vector2(25, 25) #a random factor so nodes aren't exactly lined up var map_height = 15 # how many floors var map_width = 7 # how many rooms on each floor var total_paths = 6 # how many paths should generate var floors = [] # this is the map layout! func generate_map(): floors = [] # load an empty map for y in map_height: var room = [] room.resize(map_width) room.fill(null) floors.push_back(room) for x in map_width: var wack = Vector2(randf_range(0, wackiness.x), randf_range(0, wackiness.y)) floors[y][x] = { "y": y, "x": x, "position": Vector2((x * distance_x) + wack.x , (y * distance_y) + wack.y), "next_nodes": [] } if y == map_height - 1: floors[y][x].position.y = (y * distance_y) + distance_y # load paths throughout the map for i in _rand_starting_points(): var next_node = i for y in map_height - 1: next_node = _set_path(next_node, y) # load boss room for x in map_width: if floors[map_height - 2][x].next_nodes.size(): floors[map_height - 2][x].next_nodes = [ Vector2(floor(map_width * 0.5), map_height - 1) ] return floors func _set_path(x, y): var next_room_x while next_room_x == null or _would_path_cross_existing_path(x, y, next_room_x): next_room_x = clamp(randi_range(x - 1, x + 1), 0, map_width - 1) floors[y][x].next_nodes.push_back(Vector2(next_room_x, y + 1)) return next_room_x func _would_path_cross_existing_path(x, y, next_room_x): var left_node var right_node if x > 0: left_node = floors[y][x - 1] if x < map_width - 1: right_node = floors[y][x + 1] if right_node and next_room_x > x: for next in right_node.next_nodes: if next.x < next_room_x: return true if left_node and next_room_x < x: for next in left_node.next_nodes: if next.x > next_room_x: return true return false func _rand_starting_points(): var points = [] for i in total_paths: points.push_back(randi_range(0, map_width - 1)) return points
Editor is loading...