forked from Baguette/naka-chan-dayo
270 lines
5.3 KiB
Crystal
270 lines
5.3 KiB
Crystal
|
||
require "json"
|
||
|
||
require "./naka.cr"
|
||
|
||
class Map
|
||
@save_directory : String
|
||
getter generator
|
||
def initialize(@save_directory, &block : Proc(Tile, Int32, Int32, Tile?))
|
||
Dir.mkdir_p @save_directory
|
||
|
||
@generator = block
|
||
end
|
||
|
||
class Object
|
||
getter type : String
|
||
def initialize(@type)
|
||
end
|
||
|
||
def to_json(builder)
|
||
builder.object do
|
||
builder.field "type", @type
|
||
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 "stone").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)
|
||
get_chunk(x / CHUNK_SIZE, y / CHUNK_SIZE).get(x % CHUNK_SIZE, y % CHUNK_SIZE)
|
||
end
|
||
end
|
||
|
||
class ImagesLoader
|
||
getter grass : SDL::Texture
|
||
getter stone : SDL::Texture
|
||
getter dirt : SDL::Texture
|
||
getter tree : SDL::Texture
|
||
getter pine : SDL::Texture
|
||
getter flowers : SDL::Texture
|
||
getter sand : SDL::Texture
|
||
getter water : SDL::Texture
|
||
getter haunted : SDL::Texture
|
||
getter rocks : SDL::Texture
|
||
|
||
def initialize(window)
|
||
@grass = window.newImage "assets/grass.png"
|
||
@stone = window.newImage "assets/stone.png"
|
||
@dirt = window.newImage "assets/dirt.png"
|
||
@tree = window.newImage "assets/tree.png"
|
||
@flowers = window.newImage "assets/flowers.png"
|
||
@sand = window.newImage "assets/sand.png"
|
||
@water = window.newImage "assets/water.png"
|
||
@haunted = window.newImage "assets/haunted.png"
|
||
@pine = window.newImage "assets/tree_pine.png"
|
||
@rocks = window.newImage "assets/rocks.png"
|
||
end
|
||
end
|
||
|
||
Naka.init
|
||
|
||
window = Naka::Window.new "Test", 16*128, 16*128, flags: LibSDL::WindowFlags::RESIZABLE | LibSDL::WindowFlags::SHOWN | LibSDL::WindowFlags::OPENGL
|
||
|
||
images = ImagesLoader.new window
|
||
|
||
connection_font = window.newFont "Connection.otf", 30.5
|
||
window.set_font connection_font
|
||
|
||
altitude_map = Naka::Noise2D.new.tap do |a|
|
||
a.add_octave(32, 1)
|
||
a.add_octave(16, 0.5)
|
||
a.add_octave(8, 0.25)
|
||
a.add_octave(4, 0.125)
|
||
a.add_octave(2, 1/16) # wtf, too smol
|
||
end
|
||
|
||
humidity_map = Naka::Noise2D.new.tap do |a|
|
||
a.add_octave(64, 1)
|
||
a.add_octave(32, 0.5)
|
||
a.add_octave(16, 0.25)
|
||
a.add_octave(8, 0.20)
|
||
a.add_octave(4, 0.15)
|
||
a.add_octave(2, 0.10)
|
||
end
|
||
|
||
evil_map = Naka::Noise2D.new.tap do |a|
|
||
a.add_octave(48, 0.6)
|
||
a.add_octave(32, 0.6)
|
||
a.add_octave(16, 0.3)
|
||
end
|
||
|
||
flowers_map = Naka::Noise2D.new(1, 1)
|
||
|
||
map = Map.new "map-test-01" do |tile, x, y|
|
||
altitude = altitude_map.get(x, y) + 0.5
|
||
|
||
humidity = humidity_map.get(x, y) + 0.5
|
||
|
||
evil = evil_map.get(x, y)
|
||
|
||
if altitude < 0.25
|
||
tile << Map::Object.new "sand"
|
||
|
||
if altitude < 0.175
|
||
tile << Map::Object.new "water"
|
||
else
|
||
if humidity < 0.33
|
||
tile << Map::Object.new "sand"
|
||
else
|
||
tile << Map::Object.new "dirt"
|
||
end
|
||
end
|
||
elsif altitude < 0.75
|
||
tile << Map::Object.new "dirt"
|
||
|
||
if evil > 0.5
|
||
tile << Map::Object.new "haunted"
|
||
else
|
||
tile << Map::Object.new "grass"
|
||
end
|
||
|
||
if altitude > 0.35 && altitude < 0.65
|
||
if humidity > 0.4
|
||
if humidity > 0.8
|
||
tile << Map::Object.new "tree"
|
||
elsif humidity < 0.6
|
||
tile << Map::Object.new "pine"
|
||
else
|
||
if Random.rand(2) == 0
|
||
tile << Map::Object.new "tree"
|
||
else
|
||
tile << Map::Object.new "pine"
|
||
end
|
||
end
|
||
else
|
||
if Random.rand(10) == 0
|
||
tile << Map::Object.new "flowers"
|
||
end
|
||
end
|
||
end
|
||
elsif altitude > 0.85
|
||
tile << Map::Object.new "rocks"
|
||
end
|
||
end
|
||
|
||
Naka::Event.loop window do |event|
|
||
case event
|
||
when Naka::Event::Quit
|
||
next Naka::Event::Quit
|
||
when Naka::Event::Update
|
||
when Naka::Event::Draw
|
||
zoom_level = 1.0
|
||
|
||
128.times do |x|
|
||
128.times do |y|
|
||
tile = map.get x, y
|
||
|
||
# FIXME:
|
||
# - Please don’t draw more than one layer of ground…
|
||
# - Transitions. (eg. between dirt and grass)
|
||
tile.each do |object|
|
||
image = case object.type
|
||
when "grass"
|
||
images.grass
|
||
when "dirt"
|
||
images.dirt
|
||
when "stone"
|
||
images.stone
|
||
when "tree"
|
||
images.tree
|
||
when "pine"
|
||
images.pine
|
||
when "flowers"
|
||
images.flowers
|
||
when "water"
|
||
images.water
|
||
when "haunted"
|
||
images.haunted
|
||
when "sand"
|
||
images.sand
|
||
when "rocks"
|
||
images.rocks
|
||
else
|
||
images.stone
|
||
end
|
||
|
||
window.draw(
|
||
image,
|
||
x: (x * 16 * zoom_level).to_i,
|
||
y: (y * 16 * zoom_level - (image.height - 16) * zoom_level).to_i,
|
||
scale_x: zoom_level,
|
||
scale_y: zoom_level
|
||
)
|
||
end
|
||
end
|
||
end
|
||
|
||
# Urgh. This shit eats CPU. Fonts need goddamn fixing.
|
||
#window.print "The quick brown fox jumps over the lazy dog.", 50, 50
|
||
when Naka::Event::KeyUp, Naka::Event::KeyDown
|
||
pp! event
|
||
end
|
||
end
|
||
|