diff options
author | Victor Andrade de Almeida <vct.a.almeida@gmail.com> | 2022-07-16 20:41:32 -0300 |
---|---|---|
committer | Victor Andrade de Almeida <vct.a.almeida@gmail.com> | 2022-07-16 20:41:40 -0300 |
commit | cb1d61c168f2ad351e673135eee5a0ce48d0e687 (patch) | |
tree | e63060fd5bdd6e804f3a33b9051ea5faa593ac1d | |
parent | d2e568aafb3189a2be04a3bacd6a6a17cf5eac82 (diff) | |
download | gamejam-gmtk-2022-cb1d61c168f2ad351e673135eee5a0ce48d0e687.tar.gz gamejam-gmtk-2022-cb1d61c168f2ad351e673135eee5a0ce48d0e687.tar.bz2 gamejam-gmtk-2022-cb1d61c168f2ad351e673135eee5a0ce48d0e687.zip |
Randomize dungeon layouts
-rw-r--r-- | Scenes/Builder.gd | 151 | ||||
-rw-r--r-- | Scenes/Dungeon.gd | 63 | ||||
-rw-r--r-- | Scenes/Dungeon.tscn | 2 | ||||
-rw-r--r-- | project.godot | 1 |
4 files changed, 155 insertions, 62 deletions
diff --git a/Scenes/Builder.gd b/Scenes/Builder.gd new file mode 100644 index 0000000..0eebb5a --- /dev/null +++ b/Scenes/Builder.gd @@ -0,0 +1,151 @@ +extends Node + +const Obstacle = preload("res://Scenes/Obstacle.tscn") +const PlateBounce = preload("res://Scenes/PlateBounce.tscn") +const PlateDamage = preload("res://Scenes/PlateDamage.tscn") +const PlateKey = preload("res://Scenes/PlateKey.tscn") +const Crystal = preload("res://Scenes/Crystal.tscn") + +const room_size = 6 + +const room_positions = [ + Vector2(-1, -1), + Vector2( 0, -1), + Vector2( 0, 0), + Vector2(-1, 0) +] + +const room_counts = [ + 1, + 1, + 2, + 2, + 3, + 4 +] + +const crystal_counts = [ + 1, + 2, + 2, + 3, + 4, + 6 +] + +enum Divider { + NONE, + DOOR, + TRAP +} + +const divider_weight = { + Divider.NONE: 0.5, + Divider.DOOR: 0.3, + Divider.TRAP: 0.2 +} + +func build(player : Entity, dungeon): + var room_count = room_counts[Global.current_stage] + var start = randi() % 4 + + var divider_count = 0 + var rooms = {} + for i in range(start, start + room_count): + rooms[room_positions[i % 4]] = true + + for key in rooms: + var length = room_size + 1 + var corner = key * length + + for i in range(0, length): + if not rooms.has(key + Vector2(-1, 0)): + build_obstacle(corner + Vector2(0, i), dungeon) + + if not rooms.has(key + Vector2(0, -1)): + build_obstacle(corner + Vector2(i + 1, 0), dungeon) + + if not rooms.has(key + Vector2(+1, 0)): + build_obstacle(corner + Vector2(length, i + 1), dungeon) + + if not rooms.has(key + Vector2(0, +1)): + build_obstacle(corner + Vector2(i, length), dungeon) + + if rooms.has(key + Vector2(-1, 0)): + divider_count = build_divider(corner, Vector2(0, 1), divider_count, dungeon) + + if rooms.has(key + Vector2(0, -1)): + divider_count = build_divider(corner, Vector2(1, 0), divider_count, dungeon) + + var pos = Vector2(1, 1) + + dungeon.add_child(player) + dungeon.set_tile(player, pos) + + var number_crystals = floor(Global.current_stage / 2.0) + 1 + for i in range(number_crystals): + pos = Vector2(randi()%8 - 4, randi()%8 - 4) + while dungeon.tiles_entities.has(pos): + pos = Vector2(randi()%8 - 4, randi()%8 - 4) + var crystal = Crystal.instance() + dungeon.set_tile(crystal, pos) + dungeon.add_child(crystal) + + pos = Vector2(randi()%8 - 4, randi()%8 - 4) + while dungeon.tiles_entities.has(pos) or dungeon.tiles_floor.has(pos): + pos = Vector2(randi()%8 - 4, randi()%8 - 4) + var plate_key = PlateKey.instance() + plate_key.set_crystal(crystal) + dungeon.tiles_floor[pos] = plate_key + dungeon.add_child(plate_key) + + for key in dungeon.tiles_entities: + dungeon.tiles_entities[key].translation = dungeon.tile_to_pos(key) + + for key in dungeon.tiles_floor: + dungeon.tiles_floor[key].translation = dungeon.tile_to_pos(key) + +func build_obstacle(pos : Vector2, dungeon): + var object = Obstacle.instance() + dungeon.add_child(object) + dungeon.set_tile(object, pos) + +func build_plate_damage(pos : Vector2, dungeon): + var object = PlateDamage.instance() + dungeon.add_child(object) + dungeon.set_tile(object, pos) + +func build_divider(pos : Vector2, dir : Vector2, count : int, dungeon): + if count == 3: + build_obstacle(Vector2.ZERO, dungeon) + for i in range(0, room_size): + build_obstacle(pos + dir * (i + 1), dungeon) + return count + + match choose_divider(): + Divider.DOOR: + build_divider_door(pos, dir, dungeon) + + Divider.TRAP: + build_divider_trap(pos, dir, dungeon) + + return count + 1 + +func build_divider_door(pos : Vector2, dir : Vector2, dungeon): + var opening = randi() % room_size + for i in range(0, room_size): + if i != opening: + build_obstacle(pos + dir * (i + 1), dungeon) + +func build_divider_trap(pos : Vector2, dir : Vector2, dungeon): + for i in range(randi() % 2, room_size, 2): + build_plate_damage(pos + dir * (i + 1), dungeon) + +func choose_divider() -> int: + var sum = randf() + for option in [Divider.NONE, Divider.DOOR, Divider.TRAP]: + sum -= divider_weight[option] + if sum < 0: + return option + + return Divider.NONE diff --git a/Scenes/Dungeon.gd b/Scenes/Dungeon.gd index 7d500d6..331f081 100644 --- a/Scenes/Dungeon.gd +++ b/Scenes/Dungeon.gd @@ -40,69 +40,10 @@ func kill_entity(entity): func build_floor(): player = Player.instance() - add_child(player) - - var rand_pos = Vector2(-6, 0) - set_tile(player, rand_pos) - - for i in range(4): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - while tiles_entities.has(rand_pos): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - var obstacle = Obstacle.instance() - set_tile(obstacle, rand_pos) - add_child(obstacle) - - for i in range(4): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - while tiles_entities.has(rand_pos): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - var monster = MonsterScene.instance() - set_tile(monster, rand_pos) - add_child(monster) - - var number_crystals = floor(Global.current_stage / 2.0) + 1 - for i in range(number_crystals): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - while tiles_entities.has(rand_pos): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - var crystal = Crystal.instance() - set_tile(crystal, rand_pos) - add_child(crystal) - - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - while tiles_entities.has(rand_pos) or tiles_floor.has(rand_pos): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - var plate_key = PlateKey.instance() - plate_key.set_crystal(crystal) - tiles_floor[rand_pos] = plate_key - add_child(plate_key) - - for i in range(4): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - while tiles_entities.has(rand_pos) or tiles_floor.has(rand_pos): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - var plate_bounce = PlateBounce.instance() - plate_bounce.set_cardinal(randi() % 4) - tiles_floor[rand_pos] = plate_bounce - add_child(plate_bounce) - - for i in range(4): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - while tiles_entities.has(rand_pos) or tiles_floor.has(rand_pos): - rand_pos = Vector2(randi()%8 - 4, randi()%8 - 4) - var plate_damage = PlateDamage.instance() - tiles_floor[rand_pos] = plate_damage - add_child(plate_damage) - - for key in tiles_entities: - tiles_entities[key].translation = tile_to_pos(key) - - for key in tiles_floor: - tiles_floor[key].translation = tile_to_pos(key) - camera.follow(player) + Builder.build(player, self) + func _process(delta): var actionables = get_tree().get_nodes_in_group("actionables") var idle = true diff --git a/Scenes/Dungeon.tscn b/Scenes/Dungeon.tscn index 727408f..c4dc431 100644 --- a/Scenes/Dungeon.tscn +++ b/Scenes/Dungeon.tscn @@ -58,7 +58,7 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 30 ) projection = 1 current = true fov = 24.0 -size = 7.35 +size = 10.0 [node name="DirectionalLight" type="DirectionalLight" parent="."] transform = Transform( 0.73644, 0.441272, -0.512773, 0, 0.757975, 0.652284, 0.676503, -0.480367, 0.558203, 0, 35.1428, 0 ) diff --git a/project.godot b/project.godot index c9a3390..5052b97 100644 --- a/project.godot +++ b/project.godot @@ -51,6 +51,7 @@ config/icon="res://icon.png" [autoload] Global="*res://Scenes/Global.gd" +Builder="*res://Scenes/Builder.gd" [physics] |