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
|
@export var cave_mine_size_threshold := 80
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
var time = generate()
|
||||||
|
print("time for generation: " + str(time))
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
func generate() -> float:
|
||||||
var start_time = Time.get_unix_time_from_system()
|
var start_time = Time.get_unix_time_from_system()
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
random_fill()
|
fill_random_noise()
|
||||||
make_cave_areas()
|
|
||||||
make_borders()
|
for i in cave_gen_iterations:
|
||||||
|
change_cells_by_neighbor_thresholds()
|
||||||
|
|
||||||
|
set_borders_solid()
|
||||||
prepare_player_start_area()
|
prepare_player_start_area()
|
||||||
connect_caves(get_caves())
|
connect_caves(get_caves())
|
||||||
make_cave_areas()
|
|
||||||
make_borders()
|
for i in cave_gen_iterations:
|
||||||
print(Time.get_unix_time_from_system() - start_time)
|
change_cells_by_neighbor_thresholds()
|
||||||
|
|
||||||
func random_fill():
|
set_borders_solid()
|
||||||
|
|
||||||
|
return Time.get_unix_time_from_system() - start_time
|
||||||
|
|
||||||
|
func fill_random_noise():
|
||||||
for x in width:
|
for x in width:
|
||||||
for y in height:
|
for y in height:
|
||||||
if randf() < fill_percentage:
|
if randf() < fill_percentage:
|
||||||
|
@ -36,15 +51,16 @@ func random_fill():
|
||||||
else:
|
else:
|
||||||
self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0))
|
self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func make_borders():
|
func set_borders_solid():
|
||||||
for x in width:
|
for x in width:
|
||||||
self.set_cell(0, Vector2i(x,0),solid_id, Vector2i(0, 0))
|
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))
|
self.set_cell(0, Vector2i(x,height-1),solid_id, Vector2i(0, 0))
|
||||||
for y in height:
|
for y in height:
|
||||||
self.set_cell(0, Vector2i(0,y),solid_id, Vector2i(0, 0))
|
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))
|
self.set_cell(0, Vector2i(width-1,y),solid_id, Vector2i(0, 0))
|
||||||
|
pass
|
||||||
|
|
||||||
func prepare_player_start_area():
|
func prepare_player_start_area():
|
||||||
var center = Vector2i(width/2, height/2)
|
var center = Vector2i(width/2, height/2)
|
||||||
for x in range(center.x - start_area_size, center.x + start_area_size):
|
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
|
var p2 = p
|
||||||
|
|
||||||
for y in range(center.y - start_area_size, center.y + start_area_size):
|
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
|
# Decide if the tile is part of the Corner or not
|
||||||
if !(p2 > 0 or p2 <= - (start_area_size*2 - p*2)):
|
if !(p2 > 0 or p2 <= - (start_area_size*2 - p*2)):
|
||||||
self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0))
|
self.set_cell(0, Vector2i(x,y),non_solid_id, Vector2i(0, 0))
|
||||||
p2 -= 1
|
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))
|
|
||||||
pass
|
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:
|
func get_caves() -> Array:
|
||||||
# get caves
|
# get caves
|
||||||
var caves := []
|
var caves := []
|
||||||
|
@ -127,7 +142,7 @@ func flood_fill(tilex, tiley, caves) -> Array:
|
||||||
caves.append(cave)
|
caves.append(cave)
|
||||||
return caves
|
return caves
|
||||||
|
|
||||||
func choose(choices):
|
func choose_rand(choices):
|
||||||
randomize()
|
randomize()
|
||||||
|
|
||||||
var rand_index = randi() % choices.size()
|
var rand_index = randi() % choices.size()
|
||||||
|
@ -139,8 +154,8 @@ func connect_caves(caves):
|
||||||
|
|
||||||
for cave in tunnel_caves:
|
for cave in tunnel_caves:
|
||||||
if prev_cave:
|
if prev_cave:
|
||||||
var new_point = choose(cave)
|
var new_point = choose_rand(cave)
|
||||||
var prev_point = choose(prev_cave)
|
var prev_point = choose_rand(prev_cave)
|
||||||
|
|
||||||
# ensure not the same point
|
# ensure not the same point
|
||||||
if new_point != prev_point:
|
if new_point != prev_point:
|
||||||
|
@ -151,7 +166,7 @@ func connect_caves(caves):
|
||||||
|
|
||||||
func create_tunnel(point1, point2, cave):
|
func create_tunnel(point1, point2, cave):
|
||||||
randomize() # for randf
|
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 steps = 0
|
||||||
var drunk_x = point2[0]
|
var drunk_x = point2[0]
|
||||||
var drunk_y = point2[1]
|
var drunk_y = point2[1]
|
||||||
|
@ -167,13 +182,13 @@ func create_tunnel(point1, point2, cave):
|
||||||
var weight = 1
|
var weight = 1
|
||||||
|
|
||||||
# weight the random walk against edges
|
# weight the random walk against edges
|
||||||
if drunk_x < point1.x: # drunkard is left of point1
|
if drunk_x < point1.x:
|
||||||
e += weight
|
e += weight
|
||||||
elif drunk_x > point1.x: # drunkard is right of point1
|
elif drunk_x > point1.x:
|
||||||
w += weight
|
w += weight
|
||||||
if drunk_y < point1.y: # drunkard is above point1
|
if drunk_y < point1.y:
|
||||||
s += weight
|
s += weight
|
||||||
elif drunk_y > point1.y: # drunkard is below point1
|
elif drunk_y > point1.y:
|
||||||
n += weight
|
n += weight
|
||||||
|
|
||||||
# normalize probabilities so they form a range from 0 to 1
|
# normalize probabilities so they form a range from 0 to 1
|
||||||
|
@ -186,7 +201,7 @@ func create_tunnel(point1, point2, cave):
|
||||||
var dx
|
var dx
|
||||||
var dy
|
var dy
|
||||||
|
|
||||||
# choose the direction
|
# choose_rand the direction
|
||||||
var choice = randf()
|
var choice = randf()
|
||||||
|
|
||||||
if 0 <= choice and choice < n:
|
if 0 <= choice and choice < n:
|
||||||
|
@ -208,9 +223,9 @@ func create_tunnel(point1, point2, cave):
|
||||||
drunk_x += dx
|
drunk_x += dx
|
||||||
drunk_y += dy
|
drunk_y += dy
|
||||||
|
|
||||||
|
|
||||||
if self.get_cell_source_id(0, Vector2i(drunk_x, drunk_y)) == solid_id:
|
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))
|
self.set_cell(0, Vector2i(drunk_x, drunk_y),non_solid_id, Vector2i(0, 0))
|
||||||
#make tunnel wider
|
#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),non_solid_id, Vector2i(0, 0))
|
||||||
self.set_cell(0, Vector2i(drunk_x+1, drunk_y+1),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