2D multiplayer platformer using Godot Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

85 lines
2.5 KiB

class_name Chunk
extends Node2D
const SIZE := 32 # blocks
## Emitted once after a chunk has been marked dirty.
signal clean
var chunk_pos: Vector2i
var region: BlockRegion
var dirty := false
var tracked_by: Dictionary[ChunkLoader, Variant] # value is unused
func get_players_tracking() -> Array[Player]:
var result: Array[Player]
for chunk_loader in tracked_by:
var player := chunk_loader.get_parent() as Player
if player: result.append(player)
return result
func _init(chunk_pos: Vector2i) -> void:
self.chunk_pos = chunk_pos
var min := chunk_pos * Chunk.SIZE
var max := (chunk_pos + Vector2i.ONE) * Chunk.SIZE - Vector2i.ONE
region = BlockRegion.new(min, max)
name = "Chunk %s" % chunk_pos
position = (Vector2(chunk_pos) + Vector2.ONE / 2) * (Block.SIZE * SIZE)
func _process(delta: float) -> void:
if not dirty: return
clean.emit()
dirty = false
static func load(buffer: StreamBuffer) -> Chunk:
var chunk_pos := buffer.read_vector2i_16()
var chunk := Chunk.new(chunk_pos)
var layer_count := buffer.read_int8()
for i in layer_count:
var layer_name := buffer.read_string()
var layer := Layers.load(layer_name, buffer)
chunk.add_child(layer)
return chunk
func save(buffer: StreamBuffer) -> void:
buffer.write_vector2i_16(chunk_pos)
buffer.write_int8(get_child_count())
for layer in get_children():
buffer.write_string(layer.name)
layer.save(buffer)
func get_layer_or_null(script: GDScript) -> Node:
var layer_name := str(script.get_global_name())
var layer := get_node_or_null(layer_name)
return layer
func get_or_create_layer(script: GDScript) -> Node:
var layer_name := str(script.get_global_name())
var layer := get_node_or_null(layer_name)
if layer: return layer
# We actually want to create is the inner "Layer" script.
var layer_script: GDScript = script.get_script_constant_map().get("Layer")
layer = layer_script.new()
layer.name = layer_name
add_child(layer)
return layer
## Returns the chunk position as a `Vector2i` from the given global position.
static func pos_from_vec(pos: Vector2) -> Vector2i:
return Vector2i((pos / (Block.SIZE * SIZE)).floor())
## Returns the global position at the center of the chunk with the given position.
static func pos_to_center(chunk_pos: Vector2i) -> Vector2:
return (Vector2(chunk_pos) + Vector2.ONE / 2) * (Block.SIZE * SIZE)
## Creates an integer index from a chunk-local block position that can be used to index into an array.
static func array_index(local_pos: Vector2i) -> int:
return BlockRegion.LOCAL_CHUNK.array_index(local_pos)