From db97e9d66d54c8702018e91b991c5261f0651510 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Wed, 7 Jul 2021 22:22:07 +0200 Subject: [PATCH] Trying to generate a world with multiple islands --- Globals.gd | 9 +++++++ scenes/Editor.gd | 2 +- scenes/Game.tscn | 59 +++++++++++++++++++++++++++------------- scenes/Grid.gd | 5 ++-- scenes/HexTileDrawer.gd | 1 + scenes/Island.gd | 60 ++++++++++++++++++++++++++++++++++++++++- scenes/World.gd | 49 +++++++++++++++++++++++++++++---- scenes/pirate.gd | 2 +- 8 files changed, 157 insertions(+), 30 deletions(-) diff --git a/Globals.gd b/Globals.gd index baf6863..8b26432 100644 --- a/Globals.gd +++ b/Globals.gd @@ -26,6 +26,7 @@ func ClearDebugLabel(): DebugLabel.text = "" + func DebugLabelAdd(text): if DebugLabel == null: return @@ -42,5 +43,13 @@ func ScreenToHex(pos: Vector2, camera: Camera2D): return Globals.HexGrid.get_hex_at(ScreenToWorld(pos, camera)).axial_coords +func HexToWorld(coord: Vector2): + return Globals.HexGrid.get_hex_center(coord) + + +func WorldToHex(pos: Vector2): + return Globals.HexGrid.get_hex_at(pos).axial_coords + + func WorldToScreen(pos: Vector2, camera: Camera2D): return pos * camera.zoom + camera.offset diff --git a/scenes/Editor.gd b/scenes/Editor.gd index 98a050d..e72ec44 100644 --- a/scenes/Editor.gd +++ b/scenes/Editor.gd @@ -83,7 +83,7 @@ func _on_EditIslandButton_toggled(button_pressed): print (button_pressed) -func _on_IslandIndex_value_changed(value): +func _on_IslandIndex_value_changed(_value): var island = world.current_island if last_index >= 0: island.save_island(get_island_filename_for_index(last_index)) diff --git a/scenes/Game.tscn b/scenes/Game.tscn index aa2b9f6..1d8a04e 100644 --- a/scenes/Game.tscn +++ b/scenes/Game.tscn @@ -30,11 +30,11 @@ current = true [node name="Grid" type="Node2D" parent="World"] script = ExtResource( 2 ) +[node name="Islands" type="Node2D" parent="World"] + [node name="GridHighlight" type="Node2D" parent="World"] script = ExtResource( 8 ) -[node name="Islands" type="Node2D" parent="World"] - [node name="UI" type="CanvasLayer" parent="World"] [node name="TopContainer" type="HBoxContainer" parent="World/UI"] @@ -47,20 +47,25 @@ __meta__ = { [node name="EditIslandButton" type="CheckButton" parent="World/UI/TopContainer"] margin_right = 117.0 margin_bottom = 40.0 -pressed = true text = "Editor" -[node name="Offset" type="Label" parent="World/UI/TopContainer"] +[node name="Button" type="Button" parent="World/UI/TopContainer"] margin_left = 121.0 +margin_right = 192.0 +margin_bottom = 40.0 +text = "Generate" + +[node name="Offset" type="Label" parent="World/UI/TopContainer"] +margin_left = 196.0 margin_top = 13.0 -margin_right = 168.0 +margin_right = 243.0 margin_bottom = 27.0 text = "Offset: " [node name="OffsetValue" type="Label" parent="World/UI/TopContainer"] -margin_left = 172.0 +margin_left = 247.0 margin_top = 13.0 -margin_right = 192.0 +margin_right = 267.0 margin_bottom = 27.0 text = "0,0" __meta__ = { @@ -68,16 +73,16 @@ __meta__ = { } [node name="Zoom" type="Label" parent="World/UI/TopContainer"] -margin_left = 196.0 +margin_left = 271.0 margin_top = 13.0 -margin_right = 245.0 +margin_right = 320.0 margin_bottom = 27.0 text = " Zoom: " [node name="ZoomValue" type="Label" parent="World/UI/TopContainer"] -margin_left = 249.0 +margin_left = 324.0 margin_top = 13.0 -margin_right = 269.0 +margin_right = 344.0 margin_bottom = 27.0 text = "0.0" __meta__ = { @@ -85,31 +90,45 @@ __meta__ = { } [node name="HexCoord" type="Label" parent="World/UI/TopContainer"] -margin_left = 273.0 +margin_left = 348.0 margin_top = 13.0 -margin_right = 347.0 +margin_right = 422.0 margin_bottom = 27.0 text = " HexCoord: " [node name="HexCoordValue" type="Label" parent="World/UI/TopContainer"] -margin_left = 351.0 +margin_left = 426.0 margin_top = 13.0 -margin_right = 379.0 +margin_right = 454.0 +margin_bottom = 27.0 +text = "(0,0)" + +[node name="WorldCoord" type="Label" parent="World/UI/TopContainer"] +margin_left = 458.0 +margin_top = 13.0 +margin_right = 541.0 +margin_bottom = 27.0 +text = "WorldCoord: " + +[node name="WorldCoordValue" type="Label" parent="World/UI/TopContainer"] +margin_left = 545.0 +margin_top = 13.0 +margin_right = 573.0 margin_bottom = 27.0 text = "(0,0)" [node name="VSeparator" type="VSeparator" parent="World/UI/TopContainer"] -margin_left = 383.0 -margin_right = 387.0 +margin_left = 577.0 +margin_right = 581.0 margin_bottom = 40.0 __meta__ = { "_edit_use_anchors_": false } [node name="FPSValue" type="Label" parent="World/UI/TopContainer"] -margin_left = 391.0 +margin_left = 585.0 margin_top = 13.0 -margin_right = 399.0 +margin_right = 593.0 margin_bottom = 27.0 text = "0" align = 2 @@ -130,6 +149,7 @@ script = ExtResource( 7 ) [node name="UI" type="CanvasLayer" parent="Editor"] [node name="Editor" type="VBoxContainer" parent="Editor/UI"] +visible = false margin_left = 12.0 margin_top = 53.0 margin_right = 94.0 @@ -207,6 +227,7 @@ toggle_mode = true group = SubResource( 3 ) text = "Grass" [connection signal="toggled" from="World/UI/TopContainer/EditIslandButton" to="Editor" method="_on_EditIslandButton_toggled"] +[connection signal="pressed" from="World/UI/TopContainer/Button" to="World" method="_on_generate_button_pressed"] [connection signal="value_changed" from="Editor/UI/Editor/IslandIndex" to="Editor" method="_on_IslandIndex_value_changed"] [connection signal="pressed" from="Editor/UI/Editor/ClearWorldButton" to="Editor" method="_on_ClearWorldButton_pressed"] [connection signal="pressed" from="Editor/UI/Editor/LoadWorldButton" to="Editor" method="_on_LoadWorldButton_pressed"] diff --git a/scenes/Grid.gd b/scenes/Grid.gd index 8411f3f..6c64af5 100644 --- a/scenes/Grid.gd +++ b/scenes/Grid.gd @@ -35,19 +35,18 @@ func calc_grid_view_rect(): func _process(_delta): - var view_grid_corners = calc_grid_view_rect() + view_grid_corners = calc_grid_view_rect() if view_grid_corners != last_grid_corners: update() func _draw(): - var view_grid_corners = calc_grid_view_rect() + view_grid_corners = calc_grid_view_rect() last_grid_corners = view_grid_corners var tl_tile_coords = Globals.HexGrid.get_hex_center(view_grid_corners[0]) var tr_tile_coords = Globals.HexGrid.get_hex_center(view_grid_corners[1]) var bl_tile_coords = Globals.HexGrid.get_hex_center(view_grid_corners[2]) - var br_tile_coords = Globals.HexGrid.get_hex_center(view_grid_corners[3]) var nc = ceil ((tr_tile_coords[0] - tl_tile_coords[0]) * 1.5 / Globals.hex_size) var nr = ceil ((bl_tile_coords[1] - tr_tile_coords[1]) / Globals.hex_size) + 2 diff --git a/scenes/HexTileDrawer.gd b/scenes/HexTileDrawer.gd index e655ff0..a967d34 100644 --- a/scenes/HexTileDrawer.gd +++ b/scenes/HexTileDrawer.gd @@ -33,6 +33,7 @@ func set_hex_scale(scale): NoneColors.append("#885555") SandColors.append("#ffa106") GrassColors.append("#4b9635") + HexColors = { TileType.None: NoneColors, diff --git a/scenes/Island.gd b/scenes/Island.gd index e6fac13..6cdd379 100644 --- a/scenes/Island.gd +++ b/scenes/Island.gd @@ -1,6 +1,12 @@ extends Node2D var tiles = {} +var offset = Vector2.ZERO +var center_coord = Vector2.ZERO +var center_world_coord = Vector2.ZERO +var tile_local_coords = [] +var rect_world = Rect2() +var radius_world = 0.0 # Called when the node enters the scene tree for the first time. func _ready(): @@ -17,11 +23,39 @@ func set_tile(coord: Vector2, value: String): update() +func set_offset(value: Vector2): + offset = value + + func clear_island(): tiles = {} update() +func calc_bbox(): + var coord_min = Vector2.ONE * 10000 + var coord_max = Vector2.ONE * -10000 + + var coords = tiles.keys() + for coord in coords: + var local_coords = (coord) + tile_local_coords.append(local_coords) + if local_coords.x < coord_min.x: + coord_min.x = local_coords.x + if local_coords.y < coord_min.y: + coord_min.y = local_coords.y + + if local_coords.x > coord_max.x: + coord_max.x = local_coords.x + if local_coords.y > coord_max.y: + coord_max.y = local_coords.y + + var hex_half_size = Vector2.ONE * Globals.hex_size * 0.5 + rect_world = Rect2(coord_min - hex_half_size, coord_max - coord_min + hex_half_size * 2) + center_world_coord = Globals.HexToWorld(Globals.WorldToHex(coord_min + 0.5 * (coord_max - coord_min))) + radius_world = max(rect_world.size.x, rect_world.size.y) * 0.5 + + func save_island(path: String): var island_save_data = File.new() island_save_data.open(path, File.WRITE) @@ -60,10 +94,34 @@ func load_island(path: String): coords = Vector2(float(regresult.get_string("tile_x")), float(regresult.get_string("tile_y"))) tiles[coords] = data[k] + name = path + calc_bbox() update() +func check_overlap(other): + var tile_offset = Globals.HexToWorld(offset) + var other_offset = Globals.HexToWorld(other.offset) + + var rel_offset = other_offset - tile_offset + var dist = rel_offset.length() - radius_world - other.radius_world + + return dist < 0 + + func _draw(): + var tile_offset = Globals.HexToWorld(offset) + print (name, tile_offset) for coord in tiles.keys(): - draw_set_transform (coord, 0, Vector2.ONE) + draw_set_transform (coord + tile_offset, 0, Vector2.ONE) draw_polygon(HexTileDrawer.HexPoints, HexTileDrawer.get_tile_color(tiles[coord])) + + var transform = get_transform() + draw_set_transform(transform.origin + tile_offset, transform.get_rotation(), transform.get_scale()) + + draw_rect(rect_world, Color.red, false) + draw_circle(center_world_coord, radius_world, Color.brown) + draw_circle(center_world_coord, 10, Color.red) + + var default_font = Control.new().get_font("font") + draw_string(default_font, Vector2(0, 0), name) diff --git a/scenes/World.gd b/scenes/World.gd index 557c12e..42e984a 100644 --- a/scenes/World.gd +++ b/scenes/World.gd @@ -10,6 +10,7 @@ onready var WorldCamera = get_node("Camera") onready var OffsetValueLabel = get_node("UI/TopContainer/OffsetValue") onready var ZoomValueLabel = get_node("UI/TopContainer/ZoomValue") onready var HexCoordValueLabel = get_node("UI/TopContainer/HexCoordValue") +onready var WorldCoordValueLabel = get_node("UI/TopContainer/WorldCoordValue") onready var PlayerChar = get_node("PlayerChar") onready var FPSValueLabel = get_node("UI/TopContainer/FPSValue") @@ -30,15 +31,48 @@ func _ready(): Grid.view_camera = WorldCamera GridHighlight.view_camera = WorldCamera - current_island = Island.new() - Islands.add_child(current_island) - - current_island.load_island("user://pirate_game_island_0.island") + generate() # Set player starting position PlayerChar.position = Globals.HexGrid.get_hex_center(Vector2(0,0)) +func generate(): + var rng = RandomNumberGenerator.new() + rng.randomize() + + islands.clear() + for island in Islands.get_children(): + Islands.remove_child(island) + island.queue_free() + + var radius = 5 + var num_islands = 3 + for i in range (num_islands): + + var overlapping = true + var find_free_retries = 10 + + var island = Island.new() + var file_name = "user://pirate_game_island_" + str(i) + ".island" + island.load_island(file_name) + + while overlapping and find_free_retries > 0: + overlapping = false + island.offset = Vector2(rng.randi_range(-radius, radius), rng.randi_range(-radius, radius)) + + for world_island in Islands.get_children(): + overlapping = world_island.check_overlap(island) + + find_free_retries = find_free_retries - 1 + + if overlapping: + print ("Could not find free spot for island!") + else: + print ("Retries left: " + str(find_free_retries) ) + Islands.add_child(island) + + func handle_game_event(event): if event is InputEventMouseButton: # Move main character @@ -70,9 +104,10 @@ func _unhandled_input(event): if 'position' in event: hex_hover = Globals.ScreenToHex(event.position, WorldCamera) GridHighlight.pos = hex_hover - HexCoordValueLabel.text = str(hex_hover) + WorldCoordValueLabel.text = str(Globals.ScreenToWorld(event.position, WorldCamera)) + if is_dragging: WorldCamera.offset = (drag_start - event.position) * WorldCamera.zoom.x @@ -114,3 +149,7 @@ func load_world(path: String): tile_data[coords] = data[k] update() + + +func _on_generate_button_pressed(): + generate() diff --git a/scenes/pirate.gd b/scenes/pirate.gd index 49234b6..9256b53 100644 --- a/scenes/pirate.gd +++ b/scenes/pirate.gd @@ -17,7 +17,7 @@ func get_input(): velocity.y -= 1 velocity = velocity.normalized() * speed -func _physics_process(delta): +func _physics_process(_delta): velocity = position.direction_to(target) * speed if position.distance_to(target) > 5: velocity = move_and_slide(velocity)