move source files to separate folders

This commit is contained in:
Antti Hakkarainen 2023-02-18 10:45:19 +02:00
parent e619b9a6df
commit 99b28ecfa3
23 changed files with 34 additions and 34 deletions

55
source/game/Chunk.gd Normal file
View file

@ -0,0 +1,55 @@
class_name Chunk
extends TileMap
var x:int = -1
var y:int = -1
# Called when the node enters the scene tree for the first time.
func _init(ypos:int, xpos:int):
self.x = xpos
self.y = ypos
#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(
x*Globals.CHUNK_SIZE.x*Globals.TILE_SIZE_X,
y*Globals.CHUNK_SIZE.y*Globals.TILE_SIZE_Y
)
func _ready():
generate_chunk()
# 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:
for row in Globals.CHUNK_SIZE.y:
for col in Globals.CHUNK_SIZE.x:
var tile_data: Array = Globals.map_tile_data[row+y*Globals.CHUNK_SIZE.y][col+x*Globals.CHUNK_SIZE.x]
# layer | tile coords at tilemap | tilemap id | coords of the tile at tileset | alternative tile
self.set_cell(
Globals.LAYER_TERRAIN,
Vector2i(col, row),
0,
tile_data[0],
tile_data[1]
)

159
source/game/ChunkHandler.gd Normal file
View file

@ -0,0 +1,159 @@
class_name ChunkHandler
extends Node2D
# one tilemap is one chunk
# map consists of many chunks
# chunks are loaded to view when needed
# chunks are deleted after they are no longer needed (in view)
# 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:int = DisplayServer.window_get_size(0).x
var distance:int = abs((window_width/(Globals.CHUNK_SIZE.x*Globals.TILE_SIZE_X)) / 2 +1 )
# for threading
var chunk_queue:Array = []
var mutex:Mutex
var semaphore:Semaphore
var thread:Thread
var exit_thread:bool = false
func _exit_tree():
if !thread:
return
mutex.lock()
exit_thread = true
mutex.unlock()
semaphore.post()
thread.wait_to_finish()
func _init() -> void:
self.name = "ChunkHandler"
func clean_up_chunks():
while true:
if not chunks_to_remove.is_empty():
mutex.lock()
var chunk = chunks_to_remove.pop_front()
mutex.unlock()
chunk.queue_free()
await get_tree().create_timer(0.02).timeout
func correction_factor(d) -> float:
if Globals.CAMERA_ZOOM_LEVEL < 0.6:
return d * 2.0
elif Globals.CAMERA_ZOOM_LEVEL > 1.0:
return d
else:
return d * ( 1 + 2 * (1-Globals.CAMERA_ZOOM_LEVEL) )
func get_chunk(key:Vector2i):
if self.chunks.has(key):
return chunks.get(key)
return null
func load_chunk(y:int, x:int, key):
var chunk = Chunk.new(y, x)
call_deferred("add_child", chunk)
mutex.lock()
chunks[key] = chunk
mutex.unlock()
func process_delay_chunks() -> void:
while true:
update_chunks()
await get_tree().create_timer(0.05).timeout
func process_delay_stats() -> void:
# emit stats about chunk amounts every 0,5s
while true:
emit_signal("chunk_stats", self.chunks.size(), self.chunks_to_remove.size())
await get_tree().create_timer(0.5).timeout
func set_ready():
mutex = Mutex.new()
semaphore = Semaphore.new()
exit_thread = false
if !thread:
thread = Thread.new()
if !thread.is_started():
thread.start(start_chunkgen, Thread.PRIORITY_NORMAL)
clean_up_chunks()
process_delay_chunks()
process_delay_stats()
func start_chunkgen():
while true:
semaphore.wait()
mutex.lock()
var should_exit = exit_thread # Protect with Mutex.
mutex.unlock()
if should_exit:
break
# work on emptying the generation queue
if not chunk_queue.is_empty():
mutex.lock()
var vars = chunk_queue.pop_front()
mutex.unlock()
load_chunk(vars[0].y, vars[0].x, vars[1])
func update_chunks():
var p_x:float = int(Globals.CAMERA_POSITION.x- Globals.CHUNK_SIZE.x) / Globals.TILE_SIZE_X / Globals.CHUNK_SIZE.x
var p_y:float = int(Globals.CAMERA_POSITION.y- Globals.CHUNK_SIZE.y) / Globals.TILE_SIZE_Y / Globals.CHUNK_SIZE.y
# When updating chunks, adjust chunk rendering distance
# based on current zoom level.
var zoom_corrected:float = correction_factor(distance)
# iterate through all the chunks. if a chunk is in camera range,
# and it exists, it should not be removed
# if chunk should be in range and it doesn't exist, it will be
# created by adding the coords to a work queue
for y in Globals.map_size/Globals.CHUNK_SIZE.y:
for x in Globals.map_size/Globals.CHUNK_SIZE.x:
var key = Vector2i(y,x)
var chunk = null
if chunks.has(key):
chunk = get_chunk(key)
if (abs(x - p_x) <= zoom_corrected && abs(y - p_y) <= zoom_corrected):
if chunk == null:
mutex.lock()
chunk_queue.push_back([Vector2i(x, y), key])
mutex.unlock()
semaphore.post()
elif chunks.has(key):
chunks_to_remove.append(chunks.get(key))
chunks.erase(key)

23
source/game/Game.gd Normal file
View file

@ -0,0 +1,23 @@
class_name Game
extends Node2D
@onready var node_chunkhandler:ChunkHandler
@onready var node_mapbackground:MapBackground
func _ready() -> void:
node_chunkhandler = find_child("ChunkHandler")
node_mapbackground = find_child("MapBackground")
# sets the minimap texture as map background to avoid jarring transitions
func _on_minimap_set_map_background_texture(sprite, scaling:Vector2) -> void:
self.set_map_background_texture(sprite, scaling)
func set_ready() -> void:
node_chunkhandler.set_ready()
func set_map_background_texture(sprite, scaling:Vector2) -> void:
node_mapbackground.set_map_background_texture(sprite, scaling)

View file

@ -0,0 +1,8 @@
class_name MapBackground
extends Sprite2D
# sets the minimap texture as map background to avoid jarring transitions
func set_map_background_texture(sprite, scaling:Vector2) -> void:
self.texture = sprite
self.scale = scaling

12
source/game/Simulation.gd Normal file
View file

@ -0,0 +1,12 @@
class_name Simulation
extends Node
# 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