From f731170b15d7a9a98561acc4a76e23fcf05ec9d5 Mon Sep 17 00:00:00 2001 From: Snoweuph Date: Fri, 7 Apr 2023 16:53:54 +0200 Subject: [PATCH] Improve and Speedup MapGeneration Code --- Scripts/MapGenerator.gd | 117 ++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 51 deletions(-) diff --git a/Scripts/MapGenerator.gd b/Scripts/MapGenerator.gd index 7267c96..9b066e6 100644 --- a/Scripts/MapGenerator.gd +++ b/Scripts/MapGenerator.gd @@ -17,18 +17,33 @@ extends TileMap @export var cave_mine_size_threshold := 80 func _ready(): + var time = generate() + print("time for generation: " + str(time)) + + pass + + +func generate() -> float: var start_time = Time.get_unix_time_from_system() + randomize() - random_fill() - make_cave_areas() - make_borders() + fill_random_noise() + + for i in cave_gen_iterations: + change_cells_by_neighbor_thresholds() + + set_borders_solid() prepare_player_start_area() connect_caves(get_caves()) - make_cave_areas() - make_borders() - print(Time.get_unix_time_from_system() - start_time) - -func random_fill(): + + for i in cave_gen_iterations: + change_cells_by_neighbor_thresholds() + + set_borders_solid() + + return Time.get_unix_time_from_system() - start_time + +func fill_random_noise(): for x in width: for y in height: if randf() < fill_percentage: @@ -36,15 +51,16 @@ func random_fill(): else: self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0)) pass - -func make_borders(): + +func set_borders_solid(): for x in width: self.set_cell(0, Vector2i(x,0),solid_id, Vector2i(0, 0)) self.set_cell(0, Vector2i(x,height-1),solid_id, Vector2i(0, 0)) for y in height: self.set_cell(0, Vector2i(0,y),solid_id, Vector2i(0, 0)) self.set_cell(0, Vector2i(width-1,y),solid_id, Vector2i(0, 0)) - + pass + func prepare_player_start_area(): var center = Vector2i(width/2, height/2) for x in range(center.x - start_area_size, center.x + start_area_size): @@ -58,37 +74,36 @@ func prepare_player_start_area(): var p2 = p for y in range(center.y - start_area_size, center.y + start_area_size): - # Decide if the tile is part of the Corner or not - if !(p2 > 0 or p2 <= - (start_area_size*2 - p*2)): - self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0)) - p2 -= 1 - -func make_cave_areas(): - for i in cave_gen_iterations: - for x in range(1, width): - for y in range(1, height): - # Count Solid Neighbor Cells - var count := 0 - #y-1 - if self.get_cell_source_id(0, Vector2i(x-1, y-1)) == solid_id: count +=1 - if self.get_cell_source_id(0, Vector2i(x, y-1)) == solid_id: count +=1 - if self.get_cell_source_id(0, Vector2i(x+1, y-1)) == solid_id: count +=1 - #y - if self.get_cell_source_id(0, Vector2i(x-1, y)) == solid_id: count +=1 - if self.get_cell_source_id(0, Vector2i(x+1, y)) == solid_id: count +=1 - #y+1 - if self.get_cell_source_id(0, Vector2i(x-1, y+1)) == solid_id: count +=1 - if self.get_cell_source_id(0, Vector2i(x, y+1)) == solid_id: count +=1 - if self.get_cell_source_id(0, Vector2i(x+1, y+1)) == solid_id: count +=1 - - # Check Wether to Change the Cell or Not - if count < nonsolid_threshold: - self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0)) - - if count >= solid_threshold: - self.set_cell(0, Vector2i(x,y),solid_id, Vector2i(0, 0)) + # Decide if the tile is part of the Corner or not + if !(p2 > 0 or p2 <= - (start_area_size*2 - p*2)): + self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0)) + p2 -= 1 pass - + +func change_cells_by_neighbor_thresholds(): + for x in range(1, width): + for y in range(1, height): + # Count Solid Neighbor Cells + var count := 0 + #y-1 + if self.get_cell_source_id(0, Vector2i(x-1, y-1)) == solid_id: count +=1 + if self.get_cell_source_id(0, Vector2i(x, y-1)) == solid_id: count +=1 + if self.get_cell_source_id(0, Vector2i(x+1, y-1)) == solid_id: count +=1 + #y + if self.get_cell_source_id(0, Vector2i(x-1, y)) == solid_id: count +=1 + if self.get_cell_source_id(0, Vector2i(x+1, y)) == solid_id: count +=1 + #y+1 + if self.get_cell_source_id(0, Vector2i(x-1, y+1)) == solid_id: count +=1 + if self.get_cell_source_id(0, Vector2i(x, y+1)) == solid_id: count +=1 + if self.get_cell_source_id(0, Vector2i(x+1, y+1)) == solid_id: count +=1 + + # Check Threshold + if count < nonsolid_threshold: + self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0)) + if count >= solid_threshold: + self.set_cell(0, Vector2i(x,y),solid_id, Vector2i(0, 0)) + pass + func get_caves() -> Array: # get caves var caves := [] @@ -127,7 +142,7 @@ func flood_fill(tilex, tiley, caves) -> Array: caves.append(cave) return caves -func choose(choices): +func choose_rand(choices): randomize() var rand_index = randi() % choices.size() @@ -139,8 +154,8 @@ func connect_caves(caves): for cave in tunnel_caves: if prev_cave: - var new_point = choose(cave) - var prev_point = choose(prev_cave) + var new_point = choose_rand(cave) + var prev_point = choose_rand(prev_cave) # ensure not the same point if new_point != prev_point: @@ -151,7 +166,7 @@ func connect_caves(caves): func create_tunnel(point1, point2, cave): randomize() # for randf - var max_steps = 500 # so editor won't hang if walk fails + var max_steps = 500 # so game won't hang if walk fails var steps = 0 var drunk_x = point2[0] var drunk_y = point2[1] @@ -167,13 +182,13 @@ func create_tunnel(point1, point2, cave): var weight = 1 # weight the random walk against edges - if drunk_x < point1.x: # drunkard is left of point1 + if drunk_x < point1.x: e += weight - elif drunk_x > point1.x: # drunkard is right of point1 + elif drunk_x > point1.x: w += weight - if drunk_y < point1.y: # drunkard is above point1 + if drunk_y < point1.y: s += weight - elif drunk_y > point1.y: # drunkard is below point1 + elif drunk_y > point1.y: n += weight # normalize probabilities so they form a range from 0 to 1 @@ -186,7 +201,7 @@ func create_tunnel(point1, point2, cave): var dx var dy - # choose the direction + # choose_rand the direction var choice = randf() if 0 <= choice and choice < n: @@ -208,9 +223,9 @@ func create_tunnel(point1, point2, cave): drunk_x += dx drunk_y += dy - if self.get_cell_source_id(0, Vector2i(drunk_x, drunk_y)) == solid_id: self.set_cell(0, Vector2i(drunk_x, drunk_y),non_solid_id, Vector2i(0, 0)) #make tunnel wider self.set_cell(0, Vector2i(drunk_x+1, drunk_y),non_solid_id, Vector2i(0, 0)) self.set_cell(0, Vector2i(drunk_x+1, drunk_y+1),non_solid_id, Vector2i(0, 0)) + pass -- 2.45.2