Improve and Speedup MapGeneration Code #18
1 changed files with 66 additions and 51 deletions
|
@ -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:
|
||||
|
@ -37,13 +52,14 @@ func random_fill():
|
|||
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)
|
||||
|
@ -58,35 +74,34 @@ 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
|
||||
# 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 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
|
||||
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 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))
|
||||
# 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:
|
||||
|
@ -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
|
||||
|
|
Reference in a new issue