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