WIP checkpoint: Implement chunk streaming system in GDScript
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
class_name Chunk
|
||||||
|
extends Node2D
|
||||||
|
## A single loaded chunk in the world.
|
||||||
|
##
|
||||||
|
## A chunk is a fixed-size, axis-aligned region of a room. It is the atomic
|
||||||
|
## unit of load, save, and stream. This node is instantiated by the
|
||||||
|
## [ChunkStreamer] when a chunk is loaded from the server and freed when the
|
||||||
|
## chunk is unloaded.
|
||||||
|
|
||||||
|
## World-space size of a chunk along X (world units / tiles).
|
||||||
|
const CHUNK_SIZE_X := 32.0
|
||||||
|
## World-space size of a chunk along Y (world units / tiles).
|
||||||
|
const CHUNK_SIZE_Y := 32.0
|
||||||
|
## World-space size of a chunk along Z (world units / tiles).
|
||||||
|
const CHUNK_SIZE_Z := 1.0
|
||||||
|
|
||||||
|
## Canonical chunk key: "{world_id}:{room_id}:{cx}:{cy}:{cz}".
|
||||||
|
var key: String = ""
|
||||||
|
## World id this chunk belongs to.
|
||||||
|
var world_id: String = ""
|
||||||
|
## Room id this chunk belongs to.
|
||||||
|
var room_id: String = ""
|
||||||
|
## Integer chunk coordinate along X.
|
||||||
|
var cx: int = 0
|
||||||
|
## Integer chunk coordinate along Y.
|
||||||
|
var cy: int = 0
|
||||||
|
## Integer chunk coordinate along Z.
|
||||||
|
var cz: int = 0
|
||||||
|
|
||||||
|
## Whether this chunk is currently loaded and active in the scene tree.
|
||||||
|
var is_loaded := false
|
||||||
|
|
||||||
|
## Emitted when the chunk has finished loading its content.
|
||||||
|
signal chunk_loaded(chunk: Chunk)
|
||||||
|
## Emitted when the chunk is about to be unloaded.
|
||||||
|
signal chunk_unloaded(chunk: Chunk)
|
||||||
|
|
||||||
|
|
||||||
|
## Build the canonical chunk key from the chunk's coordinates.
|
||||||
|
func build_key() -> String:
|
||||||
|
return "%s:%s:%d:%d:%d" % [world_id, room_id, cx, cy, cz]
|
||||||
|
|
||||||
|
|
||||||
|
## Compute the world-space origin (min corner) of this chunk.
|
||||||
|
func world_origin() -> Vector2:
|
||||||
|
return Vector2(cx * CHUNK_SIZE_X, cy * CHUNK_SIZE_Y)
|
||||||
|
|
||||||
|
|
||||||
|
## Compute the world-space bounding box of this chunk.
|
||||||
|
func world_bounds() -> Rect2:
|
||||||
|
var origin := world_origin()
|
||||||
|
return Rect2(origin, Vector2(CHUNK_SIZE_X, CHUNK_SIZE_Y))
|
||||||
|
|
||||||
|
|
||||||
|
## Compute the integer chunk coordinate for a world-space position.
|
||||||
|
static func coord_for_position(pos: Vector2) -> Vector2i:
|
||||||
|
return Vector2i(
|
||||||
|
floori(pos.x / CHUNK_SIZE_X),
|
||||||
|
floori(pos.y / CHUNK_SIZE_Y)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
## Compute the canonical key for a world-space position.
|
||||||
|
static func key_for_position(pos: Vector2, p_world_id: String, p_room_id: String) -> String:
|
||||||
|
var c := coord_for_position(pos)
|
||||||
|
return "%s:%s:%d:%d:0" % [p_world_id, p_room_id, c.x, c.y]
|
||||||
|
|
||||||
|
|
||||||
|
## Load this chunk's content. In a real deployment this would fetch the chunk
|
||||||
|
## payload from the server (see world.md §5.3 `request_chunk` / `chunk_data`)
|
||||||
|
## and instantiate tiles/objects. For now it just marks the chunk loaded.
|
||||||
|
func load_chunk() -> void:
|
||||||
|
is_loaded = true
|
||||||
|
chunk_loaded.emit(self)
|
||||||
|
|
||||||
|
|
||||||
|
## Unload this chunk's content and free any child nodes.
|
||||||
|
func unload_chunk() -> void:
|
||||||
|
chunk_unloaded.emit(self)
|
||||||
|
for child in get_children():
|
||||||
|
child.queue_free()
|
||||||
|
is_loaded = false
|
||||||
Reference in New Issue
Block a user