From d31fced18207901bcf18c4e82b98ef069a74878a Mon Sep 17 00:00:00 2001 From: Antti Hakkarainen Date: Wed, 15 Feb 2023 21:13:24 +0200 Subject: [PATCH] display minimap sprite as map background --- doc/array speed comparison.txt | 46 +++++++++++++++++++++++++++++ project.godot | 2 ++ scenes/Building.tscn | 4 +-- scenes/Main.tscn | 14 +++++++-- scenes/ParcelNoiseTesting.tscn | 3 ++ {scenes => scripts}/Building.gd | 0 {scenes => scripts}/CameraMarker.gd | 16 +++++----- scripts/CameraZoom2D.gd | 8 ++--- {scenes => scripts}/Chunk.gd | 26 +++++++++------- scripts/ChunkHandler.gd | 35 ++++++++++------------ scripts/Control.gd | 12 +++++++- scripts/Globals.gd | 6 ++-- scripts/Main.gd | 3 +- scripts/MapBackground.gd | 7 +++++ scripts/Minimap.gd | 9 ++++-- 15 files changed, 135 insertions(+), 56 deletions(-) create mode 100644 doc/array speed comparison.txt rename {scenes => scripts}/Building.gd (100%) rename {scenes => scripts}/CameraMarker.gd (60%) rename {scenes => scripts}/Chunk.gd (72%) create mode 100644 scripts/MapBackground.gd diff --git a/doc/array speed comparison.txt b/doc/array speed comparison.txt new file mode 100644 index 0000000..9dc8d22 --- /dev/null +++ b/doc/array speed comparison.txt @@ -0,0 +1,46 @@ +Regular array: + +Worldgen speed stats: +1/5: read image data 101.457ms +2/5: smooth water 1585.604ms +3/5: generate biomes 932.489ms +4/5: smooth forest 1706.94ms +5/5: select tiles 2336.994ms + +Worldgen speed stats: +1/5: read image data 100.047ms +2/5: smooth water 1625.953ms +3/5: generate biomes 932.566ms +4/5: smooth forest 1696.521ms +5/5: select tiles 2333.278ms + +Worldgen speed stats: +1/5: read image data 101.602ms +2/5: smooth water 1589.061ms +3/5: generate biomes 937.952ms +4/5: smooth forest 1717.81ms +5/5: select tiles 2365.742ms + + +PackedInt32Array + +Worldgen speed stats: +1/5: read image data 104.307ms +2/5: smooth water 1472.599ms +3/5: generate biomes 880.578ms +4/5: smooth forest 1632.503ms +5/5: select tiles 2334.966ms + +Worldgen speed stats: +1/5: read image data 105.705ms +2/5: smooth water 1484.185ms +3/5: generate biomes 883.91ms +4/5: smooth forest 1627.377ms +5/5: select tiles 2333.161ms + +Worldgen speed stats: +1/5: read image data 105.343ms +2/5: smooth water 1460.586ms +3/5: generate biomes 876.786ms +4/5: smooth forest 1613.83ms +5/5: select tiles 2312.17ms \ No newline at end of file diff --git a/project.godot b/project.godot index 0e389d0..f271f1b 100644 --- a/project.godot +++ b/project.godot @@ -84,4 +84,6 @@ camera_reset_rotation={ [rendering] +textures/default_filters/texture_mipmap_bias=0.5 environment/defaults/default_clear_color=Color(0, 0, 0, 1) +textures/canvas_textures/default_texture_filter=2 diff --git a/scenes/Building.tscn b/scenes/Building.tscn index 3a58c83..73e804e 100644 --- a/scenes/Building.tscn +++ b/scenes/Building.tscn @@ -1,7 +1,7 @@ -[gd_scene load_steps=3 format=3 uid="uid://sqvd1ev6ubp"] +[gd_scene load_steps=3 format=3] [ext_resource type="Texture2D" uid="uid://cxn2fno1j7vf5" path="res://icon.svg" id="1_pe5ue"] -[ext_resource type="Script" path="res://scenes/Building.gd" id="1_uqlnt"] +[ext_resource type="Script" path="res://scripts/Building.gd" id="1_uqlnt"] [node name="Building" type="Sprite2D"] texture = ExtResource("1_pe5ue") diff --git a/scenes/Main.tscn b/scenes/Main.tscn index a22b6d3..9a3130b 100644 --- a/scenes/Main.tscn +++ b/scenes/Main.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=8 format=3 uid="uid://nfayf78xiuap"] +[gd_scene load_steps=9 format=3 uid="uid://b1bahdquscsym"] [ext_resource type="Script" path="res://scripts/Main.gd" id="1_ysxum"] [ext_resource type="Script" path="res://scripts/ChunkHandler.gd" id="2_6cequ"] @@ -6,7 +6,8 @@ [ext_resource type="PackedScene" uid="uid://2we3txfr812u" path="res://scenes/Camera_zoom_2d.tscn" id="4_rx82t"] [ext_resource type="Script" path="res://scripts/EntityPlacer.gd" id="5_8jju5"] [ext_resource type="Script" path="res://scripts/Minimap.gd" id="5_rg28x"] -[ext_resource type="Script" path="res://scenes/CameraMarker.gd" id="7_0s6ed"] +[ext_resource type="Script" path="res://scripts/CameraMarker.gd" id="7_6krn1"] +[ext_resource type="Script" path="res://scripts/MapBackground.gd" id="8_ron2j"] [node name="Main" type="Node2D"] script = ExtResource("1_ysxum") @@ -32,6 +33,11 @@ limit_smoothed = true rotation_smoothing_enabled = true editor_draw_limits = true +[node name="MapBackground" type="Sprite2D" parent="."] +z_index = -1 +centered = false +script = ExtResource("8_ron2j") + [node name="UILayer" type="CanvasLayer" parent="."] [node name="Control" type="Control" parent="UILayer"] @@ -124,7 +130,7 @@ script = ExtResource("5_rg28x") z_index = 1 position = Vector2(-32, 0) centered = false -script = ExtResource("7_0s6ed") +script = ExtResource("7_6krn1") [node name="MinimapSprite" type="Sprite2D" parent="UILayer/Control/Minimap"] texture_repeat = 1 @@ -135,6 +141,7 @@ centered = false [connection signal="worldgen_ready" from="." to="CameraZoom2D" method="_on_main_worldgen_ready"] [connection signal="worldgen_ready" from="." to="UILayer/Control/Minimap" method="_on_main_worldgen_ready"] [connection signal="worldgen_ready" from="." to="UILayer/Control/Minimap/CameraMarker" method="_on_main_worldgen_ready"] +[connection signal="chunk_stats" from="ChunkHandler" to="UILayer/Control" method="_on_chunk_handler_chunk_stats"] [connection signal="camera_rotation_changed" from="CameraZoom2D" to="UILayer/Control/Minimap/CameraMarker" method="_on_camera_zoom_2d_camera_rotation_changed"] [connection signal="camera_zoom_changed" from="CameraZoom2D" to="UILayer/Control/Minimap/CameraMarker" method="_on_camera_zoom_2d_camera_zoom_changed"] [connection signal="pressed" from="UILayer/Control/ConstructionPanel/button_residental" to="UILayer/Control" method="_on_button_residental_pressed"] @@ -147,3 +154,4 @@ centered = false [connection signal="mouse_entered" from="UILayer/Control/Minimap" to="UILayer/Control/Minimap" method="_on_mouse_entered"] [connection signal="mouse_exited" from="UILayer/Control/Minimap" to="UILayer/Control/Minimap" method="_on_mouse_exited"] [connection signal="set_camera_position" from="UILayer/Control/Minimap" to="CameraZoom2D" method="_on_set_camera_position"] +[connection signal="set_map_background_texture" from="UILayer/Control/Minimap" to="MapBackground" method="_on_minimap_set_map_background_texture"] diff --git a/scenes/ParcelNoiseTesting.tscn b/scenes/ParcelNoiseTesting.tscn index 099e6f4..de3d3ba 100644 --- a/scenes/ParcelNoiseTesting.tscn +++ b/scenes/ParcelNoiseTesting.tscn @@ -24,3 +24,6 @@ position = Vector2(1480, 700) rotation = 0.523598 scale = Vector2(2.6875, 2.60938) texture = SubResource("NoiseTexture2D_kpv1q") + +[node name="TileMap" type="TileMap" parent="."] +format = 2 diff --git a/scenes/Building.gd b/scripts/Building.gd similarity index 100% rename from scenes/Building.gd rename to scripts/Building.gd diff --git a/scenes/CameraMarker.gd b/scripts/CameraMarker.gd similarity index 60% rename from scenes/CameraMarker.gd rename to scripts/CameraMarker.gd index e89f85d..dc0cf37 100644 --- a/scenes/CameraMarker.gd +++ b/scripts/CameraMarker.gd @@ -1,22 +1,22 @@ extends Sprite2D -var size_multiplier -var w_s -var previous_camera_zoom +var size_multiplier:float +var w_s:Vector2 -# draws a box represnting the camera view in minimap + +# Draws a box represnting the camera view in minimap func _draw(): draw_rect(Rect2(-w_s.x/2, -w_s.y/2, w_s.x, w_s.y), Color.GREEN, false, -3.0) -# rotates the box if camera is rotated +# Rotates the box if camera is rotated func _on_camera_zoom_2d_camera_rotation_changed(new_rotation): self.rotation = new_rotation -# redraws the box to a different size if amera is zoomed +# Redraws the box to a different size if camera is zoomed func _on_camera_zoom_2d_camera_zoom_changed(new_zoom_factor): - w_s = (DisplayServer.window_get_size(0) / size_multiplier) + w_s = DisplayServer.window_get_size(0) / size_multiplier w_s.x /= new_zoom_factor w_s.y /= new_zoom_factor queue_redraw() @@ -25,4 +25,4 @@ func _on_camera_zoom_2d_camera_zoom_changed(new_zoom_factor): # Sets the initial size of the camera box, after game is loaded func _on_main_worldgen_ready() -> void: size_multiplier = Globals.map_size / 32 - w_s = (DisplayServer.window_get_size(0) / size_multiplier) + w_s = DisplayServer.window_get_size(0) / size_multiplier diff --git a/scripts/CameraZoom2D.gd b/scripts/CameraZoom2D.gd index d27906a..16eb094 100644 --- a/scripts/CameraZoom2D.gd +++ b/scripts/CameraZoom2D.gd @@ -5,12 +5,12 @@ extends Camera2D signal camera_rotation_changed(new_rotation) signal camera_zoom_changed(new_zoom_factor) -var is_panning_camera = false -var tween +var is_panning_camera:bool = false +var tween:Tween var chunk_in_px:Vector2i = Vector2i(Globals.CHUNK_SIZE.x*Globals.TILE_SIZE_X, Globals.CHUNK_SIZE.y*Globals.TILE_SIZE_Y) -var game_res = DisplayServer.window_get_size(0) -var x_min_limit = self.game_res.x/2 - chunk_in_px.x +var game_res:Vector2i = DisplayServer.window_get_size(0) +var x_min_limit:int = self.game_res.x/2 - chunk_in_px.x func _on_main_worldgen_ready() -> void: diff --git a/scenes/Chunk.gd b/scripts/Chunk.gd similarity index 72% rename from scenes/Chunk.gd rename to scripts/Chunk.gd index d5da155..3c2e05c 100644 --- a/scenes/Chunk.gd +++ b/scripts/Chunk.gd @@ -12,6 +12,9 @@ func _init(ypos:int, xpos:int, sr: bool): self.y = ypos self.should_remove = sr + #self.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC + self.cell_quadrant_size = 32 + self.name = "Chunk [%d,%d]" % [x, y] self.set_tileset(Globals.TILESET_TERRAIN) self.position = Vector2i( @@ -24,17 +27,18 @@ func _ready(): generate_chunk() -func _draw(): - self.draw_rect( - Rect2( - Vector2(0,0), - Vector2( - Globals.CHUNK_SIZE.x*Globals.TILE_SIZE_X, - Globals.CHUNK_SIZE.y*Globals.TILE_SIZE_Y) - ), - Color(0,0,0,0.5), - false - ) +# draws borders around the chunk +#func _draw(): +# self.draw_rect( +# Rect2( +# Vector2(0,0), +# Vector2( +# Globals.CHUNK_SIZE.x*Globals.TILE_SIZE_X, +# Globals.CHUNK_SIZE.y*Globals.TILE_SIZE_Y) +# ), +# Color(0,0,0,0.5), +# false +# ) func generate_chunk() -> void: diff --git a/scripts/ChunkHandler.gd b/scripts/ChunkHandler.gd index 8cf001c..e2c52f9 100644 --- a/scripts/ChunkHandler.gd +++ b/scripts/ChunkHandler.gd @@ -9,7 +9,11 @@ extends Node2D # This is done to speed up game loading and avoiding setting one large tilemap in one go # which is extremely slow in godot 4.0, 4096x4096 takes minutes to fill with set_cell() commands + +signal chunk_stats(chunks, removal_queue) + var chunks:Dictionary = {} +var chunks_to_remove:Array[Chunk] = [] var window_width = DisplayServer.window_get_size(0).x var distance = abs((window_width/(Globals.CHUNK_SIZE.x*Globals.TILE_SIZE_X)) / 2 +1 ) @@ -20,7 +24,6 @@ var semaphore:Semaphore var thread:Thread var exit_thread = false -var _timer:Timer func _exit_tree(): mutex.lock() @@ -37,22 +40,12 @@ func _init() -> void: func _on_main_worldgen_ready(): thread.start(start_chunkgen, Thread.PRIORITY_NORMAL) - - # chunk cleanup timer - _timer = Timer.new() - add_child(_timer) - _timer.connect("timeout", _on_timer_timeout, 0) - _timer.set_wait_time(0.05) - _timer.set_one_shot(false) - _timer.start() - - -func _on_timer_timeout(): clean_up_chunks() - + func _process(_delta): update_chunks() + emit_signal("chunk_stats", self.chunks.size(), self.chunks_to_remove.size()) func _ready(): @@ -83,13 +76,14 @@ func start_chunkgen(): load_chunk(vars[0].y, vars[0].x, vars[1]) func clean_up_chunks(): - mutex.lock() - for key in chunks: - var chunk = chunks[key] - if chunk.should_remove: + while true: + if chunks_to_remove.size() > 0: + mutex.lock() + var chunk = chunks_to_remove.pop_front() + mutex.unlock() chunk.queue_free() - chunks.erase(key) - mutex.unlock() + + await get_tree().create_timer(0.02).timeout func correction_factor(d) -> float: if Globals.CAMERA_ZOOM_LEVEL < 0.6: @@ -146,5 +140,6 @@ func update_chunks(): mutex.unlock() semaphore.post() elif chunks.has(key): - chunks[key].should_remove = true + chunks_to_remove.append(chunks.get(key)) + chunks.erase(key) diff --git a/scripts/Control.gd b/scripts/Control.gd index bc8a59b..dc3d5e0 100644 --- a/scripts/Control.gd +++ b/scripts/Control.gd @@ -6,6 +6,9 @@ signal button_pressed(button_name) @onready var debug_info = get_node("DebugContainer/" + Globals.DEBUGINFO_NODE) @onready var minimap:Minimap +var amount_of_chunks:int = 0 +var size_of_chunk_removal_queue:int = 0 + # name, position var buttons = { "button_residental": [Vector2(0,0), "R"], @@ -30,7 +33,9 @@ func _process(_delta): "FPS " + str(Engine.get_frames_per_second()) + "\n" + "Zoom lvl: " + str(Globals.CAMERA_ZOOM_LEVEL) + "\n" + "Camera pos: " + str(Globals.CAMERA_POSITION) + "\n" + - "Camera pos: " + str(Globals.camera_marker.position) + "Camera pos: " + str(Globals.camera_marker.position) + "\n" + + "Chunks: " + str(self.amount_of_chunks) + "\n" + + "Chunk del: " + str(self.size_of_chunk_removal_queue), ) # defines construction toolbar buttons @@ -70,3 +75,8 @@ func _on_button_services_pressed(): func _on_button_social_pressed(): emit_signal("button_pressed", Globals.TYPE_SOCIAL) + + +func _on_chunk_handler_chunk_stats(chunks, removal_queue): + self.amount_of_chunks = chunks + self.size_of_chunk_removal_queue = removal_queue diff --git a/scripts/Globals.gd b/scripts/Globals.gd index 6dc7aef..4f20f04 100644 --- a/scripts/Globals.gd +++ b/scripts/Globals.gd @@ -45,7 +45,7 @@ const TILESET_TERRAIN:TileSet = preload("res://scenes/Chunk.tres") var map_size:int = 0 # store terrain type (water, land, forest etc. for every map cell) -var map_terrain_data:Array[Array] = [[]] +var map_terrain_data:Array[PackedInt32Array] = [[]] # preprocess and store exact tile for every map cell to speed up setting tiles var map_tile_data:Array[Array] = [[]] @@ -55,7 +55,7 @@ var map_tile_data:Array[Array] = [[]] # CAMERA SETTINGS # ################################### -var camera_marker +var camera_marker:Sprite2D # GAME WINDOW DEFAULT SIZE const DEFAULT_X_RES:int = 1920 @@ -66,7 +66,7 @@ var CAMERA_ZOOM_LEVEL: float = 1.0 var CAMERA_POSITION:Vector2i # camera movement settings -const CAMERA_MIN_ZOOM_LEVEL: float = 0.5 +const CAMERA_MIN_ZOOM_LEVEL: float = 0.1 const CAMERA_MAX_ZOOM_LEVEL: float = 2.0 const CAMERA_ZOOM_FACTOR: float = 0.1 const CAMERA_ZOOM_DURATION: float = 0.1 diff --git a/scripts/Main.gd b/scripts/Main.gd index a05bd42..e42e062 100644 --- a/scripts/Main.gd +++ b/scripts/Main.gd @@ -33,7 +33,7 @@ func _init(): # #Vector2i(Globals.DEFAULT_X_RES, Globals.DEFAULT_Y_RES) # Vector2i(3800,2000) # ) - Globals.CAMERA_POSITION = Vector2(16*256/2, 16*256/2) + Globals.CAMERA_POSITION = Vector2(16*256/2, 16*256/2) # Called when the node enters the scene tree for the first time. @@ -59,3 +59,4 @@ func quit_game(): get_tree().get_root().propagate_notification(NOTIFICATION_WM_CLOSE_REQUEST) + diff --git a/scripts/MapBackground.gd b/scripts/MapBackground.gd new file mode 100644 index 0000000..d8da366 --- /dev/null +++ b/scripts/MapBackground.gd @@ -0,0 +1,7 @@ +extends Sprite2D + +# sets the minimap texture as map background to avoid jarring transitions +func _on_minimap_set_map_background_texture(sprite): + self.texture = sprite + self.scale = Vector2(16, 16) + diff --git a/scripts/Minimap.gd b/scripts/Minimap.gd index 0fbd357..ccd640d 100644 --- a/scripts/Minimap.gd +++ b/scripts/Minimap.gd @@ -2,12 +2,13 @@ class_name Minimap extends Control signal set_camera_position(pos:Vector2) +signal set_map_background_texture(texture) @onready var minimap_texture:ImageTexture = null @onready var sprite:Sprite2D @onready var is_mouse_inside_minimap:bool = false -@onready var position_multiplier -@onready var area_size +@onready var position_multiplier:float +@onready var area_size:Vector2 # Called when the node enters the scene tree for the first time. @@ -22,7 +23,7 @@ func _draw(): func _process(_delta): if !is_mouse_inside_minimap: - Globals.camera_marker.position = Vector2i( + Globals.camera_marker.position = Vector2( Globals.CAMERA_POSITION.x / position_multiplier, Globals.CAMERA_POSITION.y / position_multiplier, ) @@ -93,6 +94,8 @@ func set_minimap() -> void: sprite.scale = Vector2(sx, sy) + emit_signal("set_map_background_texture", sprite.texture) + func setup_camera_marker() -> void: Globals.camera_marker = self.find_child("CameraMarker")