diff options
author | Lucas Fryzek <lucas.fryzek@fryzekconcepts.com> | 2024-09-17 22:02:33 +0100 |
---|---|---|
committer | Lucas Fryzek <lucas.fryzek@fryzekconcepts.com> | 2024-09-17 22:02:33 +0100 |
commit | 0abec8156bd944aa883d544850ee1187219ba943 (patch) | |
tree | 55e222da361d176b0ba79611704b56e2d942a831 /scripts/level_generator.gd |
Initial commit
Diffstat (limited to 'scripts/level_generator.gd')
-rw-r--r-- | scripts/level_generator.gd | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/scripts/level_generator.gd b/scripts/level_generator.gd new file mode 100644 index 0000000..94a87dd --- /dev/null +++ b/scripts/level_generator.gd @@ -0,0 +1,118 @@ +extends Node3D + +@export var width: int = 10 +@export var height: int = 10 + +var room = preload("res://prefabs/round_room.tscn") +var door = preload("res://prefabs/door.tscn") + +var bounds: Vector3 = Vector3.ZERO +var astar: AStar3D + +signal astar_created + +func get_grid_index(pos: Vector2i) -> int: + return pos.y*height + pos.x + +func set_grid_index(grid: Array[int], pos: Vector2i): + # If the point lies outside the grid we return + if pos.x < 0 or pos.x >= width or pos.y < 0 or pos.y >= height: + return + + var index = get_grid_index(pos) + + # If we already set this point we exit + if grid[index] != 0: + return + + grid[index] = 1 + var new_room: Node3D = room.instantiate() + var mesh = new_room.find_child("MeshInstance3D") + # TODO can we just load and cache the bounds? + bounds = mesh.get_aabb().size + var offset_pos = Vector3(pos.x - width / 2, 0, pos.y - height / 2) + new_room.position = (offset_pos * bounds) + #print("Placing at ", pos) + add_child(new_room) + + var next = [pos + Vector2i.UP, + pos + Vector2i.LEFT, + pos + Vector2i.DOWN, + pos + Vector2i.RIGHT] + + for n in next: + var chance = randi_range(0, 1) + if chance == 0: + set_grid_index(grid, n) + +func place_door(grid: Array[int], pos: Vector2i): + var index = get_grid_index(pos) + if grid[index] == 0: + return + + var next = [pos + Vector2i.UP, + pos + Vector2i.LEFT, + pos + Vector2i.DOWN, + pos + Vector2i.RIGHT] + + var angle = -90 + for n in next: + angle += 90 + var next_index = get_grid_index(n) + if n.x < 0 or n.x >= width or n.y < 0 or n.y >= height or grid[next_index] == 0: + var new_door: Node3D = door.instantiate() + var offset_pos = Vector3(pos.x - width / 2, 0, pos.y - height / 2) + new_door.position = (offset_pos * bounds) + new_door.rotate_y(deg_to_rad(angle)) + add_child(new_door) + +func place_doors(grid: Array[int]): + for y in range(0, height): + for x in range(0, width): + place_door(grid, Vector2i(x, y)) + +func compute_astar(grid: Array[int]): + for y in range(0, height): + for x in range(0, width): + var pos = Vector2i(x, y) + var index = get_grid_index(pos) + if grid[index] == 0: + continue + var offset_pos = Vector3(pos.x - width / 2, 0, pos.y - height / 2) + astar.add_point(index, offset_pos * bounds) + + for y in range(0, height): + for x in range(0, width): + var pos = Vector2i(x, y) + var index = get_grid_index(pos) + if grid[index] == 0: + continue + + var next = [pos + Vector2i.UP, + pos + Vector2i.LEFT, + pos + Vector2i.DOWN, + pos + Vector2i.RIGHT] + for n in next: + var next_index = get_grid_index(n) + if n.x < 0 or n.x >= width or n.y < 0 or n.y >= height or grid[next_index] == 0: + continue + + astar.connect_points(index, next_index) + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + astar = AStar3D.new() + var grid: Array[int] = [0] + grid.resize(width*height) + grid.fill(0) + + var middle_x: int = width / 2 + var middle_y: int = height / 2 + + var pos = Vector2i(middle_x, middle_y) + set_grid_index(grid, pos) + + place_doors(grid) + compute_astar(grid) + + astar_created.emit(astar) |