From 47519ade7598a102d04dccd458c7681910996fb7 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Mon, 28 Jun 2021 21:51:09 +0200 Subject: [PATCH] Refactored rendering --- Globals.gd | 38 +++++++++++------- project.godot | 1 + scenes/Editor.gd | 2 +- scenes/FPSValue.gd | 2 +- scenes/Game.tscn | 12 +++--- scenes/Grid.gd | 60 ++++++++++++++++++++++++++++ scenes/GridHighlight.gd | 26 ++++++++++++ scenes/HexTileDrawer.gd | 47 ++++++++++++++++++++++ scenes/Island.gd | 48 ++++++++++++++++++----- scenes/World.gd | 87 +++++++++++------------------------------ 10 files changed, 228 insertions(+), 95 deletions(-) create mode 100644 scenes/Grid.gd create mode 100644 scenes/GridHighlight.gd create mode 100644 scenes/HexTileDrawer.gd diff --git a/Globals.gd b/Globals.gd index 9f50f60..30bbd3e 100644 --- a/Globals.gd +++ b/Globals.gd @@ -7,11 +7,18 @@ const GRID_COLOR="#000000" const SHOVEL_DURATION=1 var DebugLabel = null -var HexGrid = preload("../thirdparty/gdhexgrid/HexGrid.gd").new() +var HexGrid = null + +var hex_size = 128 # Called when the node enters the scene tree for the first time. func _ready(): - pass # Replace with function body. + HexGrid = preload("../thirdparty/gdhexgrid/HexGrid.gd").new() + HexGrid.hex_scale = Vector2(hex_size, hex_size) +# add_child(HexGrid) + + HexTileDrawer.hex_scale = Vector2(hex_size, hex_size) + func ClearDebugLabel(): if DebugLabel == null: @@ -25,18 +32,19 @@ func DebugLabelAdd(text): DebugLabel.text = DebugLabel.text + text + "\n" -func WorldToGridCoord(world_pos): - return Vector2( - floor (world_pos.x / Globals.GRID_SIZE), - floor (world_pos.y / Globals.GRID_SIZE) - ) -func WorldToGridCenter(world_pos): - return WorldToGridCoord(world_pos) * GRID_SIZE + Vector2(GRID_SIZE, GRID_SIZE) * 0.5 +func ScreenToWorld(pos: Vector2, camera: Camera2D): + pos = pos - OS.get_window_safe_area().size * 0.5 + return camera.offset + pos * camera.zoom -func GridCenterToWorldCoord(grid_coord): - return grid_coord * GRID_SIZE + Vector2(GRID_SIZE, GRID_SIZE) * 0.5 - -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass + +func ScreenToHex(pos: Vector2, camera: Camera2D): + return Globals.HexGrid.get_hex_at(ScreenToWorld(pos, camera)).axial_coords + + +func WorldToScreen(pos: Vector2, camera: Camera2D): + return pos * camera.zoom + camera.offset + + +func DrawTile(world_coords: Vector2, tile_type): + HexTileDrawer.draw_tile(world_coords, tile_type) diff --git a/project.godot b/project.godot index 9f40be6..b2d144b 100644 --- a/project.godot +++ b/project.godot @@ -21,6 +21,7 @@ config/icon="res://icon.png" [autoload] Globals="*res://Globals.gd" +HexTileDrawer="*res://scenes/HexTileDrawer.gd" [global] diff --git a/scenes/Editor.gd b/scenes/Editor.gd index 4608cc7..882baaf 100644 --- a/scenes/Editor.gd +++ b/scenes/Editor.gd @@ -28,7 +28,7 @@ func handle_editor_event(event): if pressed_button: tile_type = pressed_button.text - var hex_coord = Globals.HexGrid.get_hex_center(world.screen_to_hex(event.position)) + var hex_coord = Globals.HexGrid.get_hex_center(Globals.ScreenToHex(event.position,world.WorldCamera)) if tile_type != "None": world.tile_data[hex_coord] = tile_type update() diff --git a/scenes/FPSValue.gd b/scenes/FPSValue.gd index 1982b42..e5202ba 100644 --- a/scenes/FPSValue.gd +++ b/scenes/FPSValue.gd @@ -10,6 +10,6 @@ extends Label func _ready(): pass # Replace with function body. -func _process(delta): +func _process(_delta): text = str(Performance.get_monitor(Performance.TIME_FPS)) diff --git a/scenes/Game.tscn b/scenes/Game.tscn index 05980d0..f19a13e 100644 --- a/scenes/Game.tscn +++ b/scenes/Game.tscn @@ -1,12 +1,13 @@ -[gd_scene load_steps=11 format=2] +[gd_scene load_steps=12 format=2] [ext_resource path="res://scenes/World.gd" type="Script" id=1] -[ext_resource path="res://scenes/HexTile.gd" type="Script" id=2] +[ext_resource path="res://scenes/Grid.gd" type="Script" id=2] [ext_resource path="res://assets/pirate.svg" type="Texture" id=3] [ext_resource path="res://scenes/FPSValue.gd" type="Script" id=4] [ext_resource path="res://scenes/pirate.gd" type="Script" id=5] [ext_resource path="res://fonts/Roboto/Roboto-Regular.ttf" type="DynamicFontData" id=6] [ext_resource path="res://scenes/Editor.gd" type="Script" id=7] +[ext_resource path="res://scenes/GridHighlight.gd" type="Script" id=8] [sub_resource type="DynamicFont" id=1] size = 27 @@ -26,10 +27,13 @@ script = ExtResource( 1 ) [node name="Camera" type="Camera2D" parent="World"] current = true -[node name="GridDrawer" type="Node2D" parent="World"] +[node name="Islands" type="Node2D" parent="World"] + +[node name="Grid" type="Node2D" parent="World"] script = ExtResource( 2 ) [node name="GridHighlight" type="Node2D" parent="World"] +script = ExtResource( 8 ) [node name="UI" type="CanvasLayer" parent="World"] @@ -120,8 +124,6 @@ texture = ExtResource( 3 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="World/PlayerChar"] -[node name="Island" type="Node" parent="World"] - [node name="Editor" type="Node2D" parent="."] script = ExtResource( 7 ) diff --git a/scenes/Grid.gd b/scenes/Grid.gd new file mode 100644 index 0000000..8411f3f --- /dev/null +++ b/scenes/Grid.gd @@ -0,0 +1,60 @@ +extends Node2D + + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" +export(Array) var view_grid_corners = [] setget set_view_grid_corners +var view_camera = null setget set_view_camera +var last_grid_corners = [] + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +func set_view_grid_corners(value: Array): + view_grid_corners = value + return view_grid_corners + + +func set_view_camera(value: Camera2D): + view_camera = value + return view_camera + + +func calc_grid_view_rect(): + var view_tl = Vector2(-Globals.hex_size,-Globals.hex_size) + var view_br = OS.get_window_safe_area().size - view_tl + + var top_left = Globals.ScreenToHex(view_tl, view_camera) + var top_right = Globals.ScreenToHex(Vector2(view_br.x, view_tl.y), view_camera) + var bottom_left = Globals.ScreenToHex(Vector2(view_tl.x, view_br.y), view_camera) + var bottom_right = Globals.ScreenToHex(view_br, view_camera) + return [top_left, top_right, bottom_left, bottom_right] + + +func _process(_delta): + var 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() + 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 + + for c in range (nc): + var dx = 0.75 * Globals.hex_size * c + var dy = (c % 2) * sqrt(3) * 0.25 * Globals.hex_size + for r in range (nr): + draw_set_transform(tl_tile_coords + Vector2(dx, r * Globals.hex_size * sqrt(3) * 0.5 + dy), 0, Vector2.ONE) + draw_polyline(HexTileDrawer.HexPoints, "#888", 1 * view_camera.zoom.x) diff --git a/scenes/GridHighlight.gd b/scenes/GridHighlight.gd new file mode 100644 index 0000000..fe6458e --- /dev/null +++ b/scenes/GridHighlight.gd @@ -0,0 +1,26 @@ +extends Node2D + + +export(Vector2) var pos = Vector2.ZERO setget setget_pos +var view_camera = null setget set_view_camera + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +func setget_pos(value: Vector2): + update() + pos = value + return value + + +func set_view_camera(value: Camera2D): + view_camera = value + return view_camera + + +func _draw(): + var coords = Globals.HexGrid.get_hex_center (pos) + draw_set_transform(coords, 0, Vector2.ONE) + draw_polyline(HexTileDrawer.HexPoints, "#f00", 2 * view_camera.zoom.x) diff --git a/scenes/HexTileDrawer.gd b/scenes/HexTileDrawer.gd new file mode 100644 index 0000000..34818db --- /dev/null +++ b/scenes/HexTileDrawer.gd @@ -0,0 +1,47 @@ +extends Node2D + +enum TileType { + None, + Sand, + Grass +} + +var HexPoints = null +var HexColors = [] + +export(Vector2) var hex_scale = Vector2(1, 1) setget set_hex_scale + +# Called when the node enters the scene tree for the first time. +func _ready(): + print ("Initialized") + set_hex_scale(Vector2(Globals.hex_size,Globals.hex_size)) + + +func set_hex_scale(scale): + hex_scale = scale + + HexPoints = PoolVector2Array() + + var NoneColors = PoolColorArray() + var SandColors = PoolColorArray() + var GrassColors = PoolColorArray() + + for i in range (7): + var angle = (60 * i) * PI / 180 + HexPoints.append(Vector2(cos(angle), sin(angle)) * hex_scale.x / 2) + NoneColors.append("#555555") + SandColors.append("#ffa106") + GrassColors.append("#4b9635") + + HexColors = { + TileType.None: NoneColors, + TileType.Sand: SandColors, + TileType.Grass: GrassColors + } + +func get_tile_color (type_name: String): + match type_name: + "None": return HexColors[TileType.None] + "Sand": return HexColors[TileType.Sand] + "Grass": return HexColors[TileType.Grass] + _ : return null diff --git a/scenes/Island.gd b/scenes/Island.gd index 1eccaec..66e46a9 100644 --- a/scenes/Island.gd +++ b/scenes/Island.gd @@ -1,16 +1,46 @@ -extends Node - - -# Declare member variables here. Examples: -# var a = 2 -# var b = "text" +extends Node2D +var tiles = {} # Called when the node enters the scene tree for the first time. func _ready(): pass # Replace with function body. -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass +func save_island(path: String): + var island_save_data = File.new() + island_save_data.open(path, File.WRITE) + island_save_data.store_line (to_json(tiles)) + island_save_data.close() + + +func load_island(path: String): + var island_save_data = File.new() + island_save_data.open(path, File.READ) + var data = parse_json(island_save_data.get_line()) + island_save_data.close() + + var data_keys = data.keys() + tiles = {} + var coord_regex = RegEx.new() + coord_regex.compile("\\((?-?\\d+(.?\\d+)?), (?-?\\d+(.?\\d+)?)\\)") + + var reg_test_result = coord_regex.search("(0, 0)") + assert(reg_test_result) + + reg_test_result = coord_regex.search("(123.124, 552.0)") + assert(reg_test_result) + + for k in data_keys: + var coords = Vector2.ZERO + var regresult = coord_regex.search(k) + if regresult: + print(regresult.get_string("tile_x"), " - ", regresult.get_string("tile_y")) + coords = Vector2(float(regresult.get_string("tile_x")), float(regresult.get_string("tile_y"))) + tiles[coords] = data[k] + + +func _draw(): + for coord in tiles.keys(): + draw_set_transform (coord, 0, Vector2.ONE) + draw_polygon(HexTileDrawer.HexPoints, HexTileDrawer.get_tile_color(tiles[coord])) diff --git a/scenes/World.gd b/scenes/World.gd index 54bb1b3..29ba18f 100644 --- a/scenes/World.gd +++ b/scenes/World.gd @@ -1,7 +1,11 @@ extends Node2D + +onready var Grid = get_node("Grid") +onready var GridHighlight = get_node("GridHighlight") + +onready var Islands = get_node("Islands") onready var EditIslandButton = get_node("UI/TopContainer/EditIslandButton") -onready var GridDrawer = get_node("GridDrawer") onready var WorldCamera = get_node("Camera") onready var OffsetValueLabel = get_node("UI/TopContainer/OffsetValue") onready var ZoomValueLabel = get_node("UI/TopContainer/ZoomValue") @@ -11,7 +15,6 @@ onready var FPSValueLabel = get_node("UI/TopContainer/FPSValue") var Island = preload("Island.gd") -var hex_size = 128 var hex_grid_bbox = [[0,0], [10,10]] var hex_hover = Vector2.ZERO @@ -20,77 +23,32 @@ var drag_start = null var target = Vector2() var tile_data = {} var islands = [] +var island = null + -# Called when the node enters the scene tree for the first time. func _ready(): - load_world("user://pirate_game_world.save") - Globals.HexGrid.hex_scale = Vector2(hex_size, hex_size) + Grid.view_camera = WorldCamera + GridHighlight.view_camera = WorldCamera + island = Island.new() + Islands.add_child(island) + + island.load_island("user://pirate_game_world.save") + # Set player starting position PlayerChar.position = Globals.HexGrid.get_hex_center(Vector2(0,0)) - GridDrawer.hex_scale = Vector2(hex_size, hex_size) -func _draw(): - draw_tiles() - draw_grid() - - -func draw_grid(): - var view_grid_corners = calc_grid_view_rect() - - 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 / hex_size) - var nr = ceil ((bl_tile_coords[1] - tr_tile_coords[1]) / hex_size) + 2 - - for c in range (nc): - var dx = 0.75 * hex_size * c - var dy = (c % 2) * sqrt(3) * 0.25 * hex_size #(c % 2) * sqrt(3) * hex_size * 0.75 - for r in range (nr): - draw_set_transform(tl_tile_coords + Vector2(dx, r * hex_size * sqrt(3) * 0.5 + dy), 0, Vector2.ONE) - draw_polyline(GridDrawer.HexPoints, "#888", 1 * WorldCamera.zoom.x) - - var coords = Globals.HexGrid.get_hex_center (hex_hover) - draw_set_transform(coords, 0, Vector2.ONE) - draw_polyline(GridDrawer.HexPoints, "#f00", 2 * WorldCamera.zoom.x) - -func draw_tiles(): - for coord in tile_data.keys(): - draw_set_transform (coord, 0, Vector2.ONE) - draw_polygon(GridDrawer.HexPoints, GridDrawer.get_tile_color(tile_data[coord])) - -func screen_to_world(pos: Vector2): - pos = pos - OS.get_window_safe_area().size * 0.5 - return WorldCamera.offset + pos * WorldCamera.zoom - -func screen_to_hex(pos: Vector2): - return Globals.HexGrid.get_hex_at(screen_to_world(pos)).axial_coords - -func world_to_screen(pos: Vector2): - return pos * WorldCamera.zoom + WorldCamera.offset - -func calc_grid_view_rect(): - var view_tl = Vector2(-hex_size,-hex_size) - var view_br = OS.get_window_safe_area().size - view_tl - - var top_left = screen_to_hex (view_tl) - var top_right = screen_to_hex (Vector2(view_br.x, view_tl.y)) - var bottom_left = screen_to_hex (Vector2(view_tl.x, view_br.y)) - var bottom_right = screen_to_hex (view_br) - return [top_left, top_right, bottom_left, bottom_right] func handle_game_event(event): if event is InputEventMouseButton: # Move main character if event.pressed and event.button_index == BUTTON_LEFT: - PlayerChar.target = Globals.HexGrid.get_hex_center(screen_to_hex(event.position)) + PlayerChar.target = Globals.HexGrid.get_hex_center(Globals.ScreenToHex(event.position, WorldCamera)) return true return false - + + func _unhandled_input(event): if event is InputEventMouseButton: if handle_game_event(event): @@ -104,20 +62,21 @@ func _unhandled_input(event): is_dragging = false # Zoom Camera - if event.pressed and event.button_index == BUTTON_WHEEL_DOWN and event.pressed and WorldCamera.zoom.y < 3.5: + if event.pressed and event.button_index == BUTTON_WHEEL_DOWN and event.pressed and WorldCamera.zoom.y < 5.5: WorldCamera.zoom = WorldCamera.zoom * 1.0 / 0.8 elif event.button_index == BUTTON_WHEEL_UP and event.pressed: WorldCamera.zoom = WorldCamera.zoom * 0.8 if 'position' in event: - hex_hover = screen_to_hex(event.position) + hex_hover = Globals.ScreenToHex(event.position, WorldCamera) + GridHighlight.pos = hex_hover + HexCoordValueLabel.text = str(hex_hover) if is_dragging: WorldCamera.offset = (drag_start - event.position) * WorldCamera.zoom.x - - update() - + + OffsetValueLabel.text = str(WorldCamera.offset) ZoomValueLabel.text = str(WorldCamera.zoom)