naka-chan-dayo/src/naka/map.cr

111 lines
2.0 KiB
Crystal

require "json"
class Naka::Map
@save_directory : String
getter default_reference : ObjectReference
getter generator
def initialize(@default_reference, @save_directory, &block : Proc(Tile, Int32, Int32, Tile?))
Dir.mkdir_p @save_directory
@generator = block
end
class ObjectReference
getter name : String
getter walkable : Bool
getter tiles : Array(String)
getter drawer : Proc(Map, Int32, Int32, Int32, Tile, Object, Int32, Int32, Float64, Nil)?
def initialize(@name, @walkable = false, @tiles = [] of String, @drawer = nil)
end
end
class Object
getter reference : ObjectReference
def initialize(@reference)
end
def to_json(builder)
builder.object do
builder.field "type", @reference.name
end
end
end
class Tile < Array(Object)
def initialize(element)
initialize
self << element
end
end
CHUNK_SIZE = 32
class Chunk
property tiles : Array(Array(Tile))
getter x : Int32
getter y : Int32
def initialize(@x, @y, map)
p "Creating Map::Chunk"
@tiles = Array.new(CHUNK_SIZE) do |x|
x += @x * CHUNK_SIZE
Array.new(CHUNK_SIZE) do |y|
y += @y * CHUNK_SIZE
Tile.new(Object.new map.default_reference).tap do |tile|
map.generator.call tile, x, y
end
end
end
end
def to_json
{
:x => @x,
:y => @y,
:tiles => @tiles
}.to_json
end
def get(x, y)
@tiles[x][y]
end
end
@chunks = Hash(Int32, Hash(Int32, Chunk)).new
def get_chunk(x, y)
chunks_list = @chunks[x]?
if chunks_list.nil?
chunks_list = Hash(Int32, Chunk).new
@chunks[x] = chunks_list
end
chunk = chunks_list[y]?
if chunk.nil?
chunk = Chunk.new x, y, self
chunks_list[y] = chunk
save chunk
end
chunk
end
def save(chunk : Chunk)
File.write "#{@save_directory}/chunk-#{chunk.x}-#{chunk.y}.json", chunk.to_json
end
def get(x, y)
x_value = x / CHUNK_SIZE
y_value = y / CHUNK_SIZE
get_chunk(x_value.to_i, y_value.to_i).get(x % CHUNK_SIZE, y % CHUNK_SIZE)
end
end