naka-chan-dayo/src/main.cr

270 lines
5.3 KiB
Crystal
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 dont 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