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.
 

94 lines
2.7 KiB

class_name Matter
static var REGISTRY := Registry.new()
static var NONE := Matter.new("none")
static var PLASTIC := Matter.new("plastic")
static var DEFAULT := NONE
var id : int
var name : String
func _init(name: String) -> void:
REGISTRY.add(name, self)
class Layer extends MeshInstance2D:
var data: PackedByteArray
var chunk: Chunk:
get: return get_parent()
func _init() -> void:
data.resize(Chunk.SIZE * Chunk.SIZE)
texture = preload("res://world/blocks/plastic.png")
static func load(buffer: StreamBuffer) -> Layer:
var result := Layer.new()
buffer.read_raw_buffer_into(result.data)
return result
func save(buffer: StreamBuffer) -> void:
buffer.write_raw_buffer(data)
func get_at(pos: Vector2i) -> Matter:
var index := Chunk.array_index(pos)
var id := data[index]
return Matter.REGISTRY.lookup_by_id(id)
func set_at(pos: Vector2i, value: Matter) -> void:
set_id_at(pos, value.id)
@rpc("reliable")
func set_id_at(pos: Vector2i, id: int) -> void:
var index := Chunk.array_index(pos)
if data[index] == id: return
# TODO: Keep track of how many non-air blocks are present, to allow for cleaning empty chunks.
data[index] = id
chunk.dirty = true
if multiplayer.is_server():
# Send change to every player tracking this chunk.
for player in chunk.get_players_tracking():
if player.network.is_local: continue # skip server player
set_id_at.rpc_id(player.network.peer_id, pos, id)
func _ready() -> void:
chunk.clean.connect(_update_mesh)
_update_mesh()
func _update_mesh() -> void:
const CHUNK_HALF_SIZE := (Vector2.ONE * Chunk.SIZE * Block.SIZE) / 2
var any_blocks := false
var m := ImmediateMesh.new()
m.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
var shapes: Shape.Layer = chunk.get_layer_or_null(Shape)
if shapes: # Should exist, but let's sanity check.
for pos in BlockRegion.LOCAL_CHUNK:
var offset := (Vector2.ONE / 2) + Vector2(pos)
# TODO: Support different matter.
# var matter := get_at(pos)
var shape := shapes.get_at(pos)
if shape.points.is_empty(): continue
any_blocks = true
for i in range(2, shape.points.size()):
var uv0 := shape.uvs[0 ]
var uv1 := shape.uvs[i-1]
var uv2 := shape.uvs[i ]
var p0 := (offset + shape.points[0 ]) * Block.SIZE - CHUNK_HALF_SIZE
var p1 := (offset + shape.points[i-1]) * Block.SIZE - CHUNK_HALF_SIZE
var p2 := (offset + shape.points[i ]) * Block.SIZE - CHUNK_HALF_SIZE
m.surface_set_uv(uv0); m.surface_add_vertex_2d(p0)
m.surface_set_uv(uv1); m.surface_add_vertex_2d(p1)
m.surface_set_uv(uv2); m.surface_add_vertex_2d(p2)
if any_blocks:
m.surface_end()
mesh = m
else:
mesh = null