Improve and Speedup MapGeneration Code #18

Merged
Snoweuph merged 1 commit from dev-map-generation into dev-base 2023-04-07 14:55:24 +00:00
Showing only changes of commit f731170b15 - Show all commits

View file

@ -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