require "json" require "./naka.cr" Naka.init window = Naka::Window.new "Test", 16*128, 16*128, flags: LibSDL::WindowFlags::RESIZABLE | LibSDL::WindowFlags::SHOWN | LibSDL::WindowFlags::OPENGL connection_font = window.newFont "assets/connection.otf", 30.5 window.set_font connection_font def simple_tile_drawer(window : Naka::Window, tile_path : String) texture = window.newImage tile_path texture_height = texture.height ->(map : Naka::Map, x : Int32, y : Int32, z : Int32, tile : Naka::Map::Tile, object : Naka::Map::Object, draw_x : Int32, draw_y : Int32, zoom : Float64){ window.draw texture, draw_x, (draw_y + (16 - texture_height) * zoom).to_i, scale_x: zoom, scale_y: zoom nil } end def bordered_tile_drawer(window : Naka::Window, base_tile_path : String) mod = [ "trbl", "-rbl", "t-bl", "tr-l", "trb-", "t-b-", "-r-l", "tr--", "-rb-", "--bl", "t--l", "t---", "-r--", "--b-", "---l", "----" ] textures = Hash(String, SDL::Texture).new mod.each do |s| begin textures[s] = window.newImage base_tile_path.sub /{}/, "-" + s rescue # Not even sure we should be doing something here… # Maybe in the future, in debug mode? end end ->(map : Naka::Map, x : Int32, y : Int32, z : Int32, tile : Naka::Map::Tile, object : Naka::Map::Object, draw_x : Int32, draw_y : Int32, zoom : Float64){ neighbours = [ {x, y-1, "t"}, {x+1, y, "r"}, {x, y+1, "b"}, {x-1, y, "l"} ] neighbours = neighbours.map do |x, y| map.get(x, y)[z]?.try &.reference.== object.reference end t, r, b, l = neighbours t = t ? 't' : '-' r = r ? 'r' : '-' b = b ? 'b' : '-' l = l ? 'l' : '-' neighbours = [t, r, b, l].reduce "" { |a, c| a + c } window.draw (textures[neighbours]? || textures["trbl"]), draw_x, draw_y, scale_x: zoom, scale_y: zoom nil } end stone = Naka::Map::ObjectReference.new( name: "Stone", walkable: true, drawer: simple_tile_drawer window, "assets/stone.png" ) grass = Naka::Map::ObjectReference.new( name: "Grass", walkable: true, drawer: bordered_tile_drawer window, "assets/grass{}.png" ) dirt = Naka::Map::ObjectReference.new( name: "Dirt", walkable: true, drawer: bordered_tile_drawer window, "assets/dirt{}.png" ) sand = Naka::Map::ObjectReference.new( name: "Sand", walkable: true, drawer: bordered_tile_drawer window, "assets/sand{}.png" ) water = Naka::Map::ObjectReference.new( name: "Water", drawer: simple_tile_drawer window, "assets/water.png" ) flowers = Naka::Map::ObjectReference.new( name: "Flowers", walkable: true, drawer: simple_tile_drawer window, "assets/flowers.png" ) haunted = Naka::Map::ObjectReference.new( name: "Haunted", walkable: true, drawer: bordered_tile_drawer window, "assets/haunted{}.png" ) haunted_tree = Naka::Map::ObjectReference.new( name: "Tree (Haunted)", drawer: simple_tile_drawer window, "assets/haunted-tree.png" ) tree_cut = Naka::Map::ObjectReference.new( name: "Tree (Cut)", drawer: simple_tile_drawer window, "assets/tree-cut.png" ) tree = Naka::Map::ObjectReference.new( name: "Tree", drawer: simple_tile_drawer window, "assets/tree.png" ) pine = Naka::Map::ObjectReference.new( name: "Pine Tree", drawer: simple_tile_drawer window, "assets/tree_pine.png" ) rocks = Naka::Map::ObjectReference.new( name: "Rocks", drawer: simple_tile_drawer window, "assets/rocks.png" ) altitude_noise = 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_noise = 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_noise = 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 map = Naka::Map.new stone, "map-test-01" do |tile, x, y| altitude = altitude_noise.get(x, y) + 0.5 humidity = humidity_noise.get(x, y) + 0.5 evil = evil_noise.get(x, y) if altitude < 0.35 tile << Naka::Map::Object.new water else tile << Naka::Map::Object.new stone end if altitude < 0.75 if altitude < 0.175 next end tile << Naka::Map::Object.new sand if humidity < 0.225 next end tile << Naka::Map::Object.new dirt if altitude < 0.275 next end if evil > 0.4 tile << Naka::Map::Object.new haunted else tile << Naka::Map::Object.new grass end if altitude > 0.35 && altitude < 0.65 if humidity > 0.4 if evil > 0.4 tile << Naka::Map::Object.new haunted_tree elsif humidity > 0.8 tile << Naka::Map::Object.new tree elsif humidity < 0.6 tile << Naka::Map::Object.new pine else if Random.rand(2) == 0 tile << Naka::Map::Object.new tree else tile << Naka::Map::Object.new pine end end else if Random.rand(10) == 0 tile << Naka::Map::Object.new flowers end end end else tile << Naka::Map::Object.new stone if altitude > 0.85 tile << Naka::Map::Object.new rocks end end end Naka::Event.loop window do |event| case event when Naka::Event::Quit next Naka::Event::Quit when Naka::Event::Update p "FPS: #{(1000f64 / event.dt)}" when Naka::Event::Draw zoom_level = 4.0 64.times do |x| 32.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_with_index do |object, z| draw_x = (x * 16 * zoom_level).to_i draw_y = (y * 16 * zoom_level).to_i drawer = object.reference.drawer next if drawer.nil? # FIXME: Maybe print a warning. drawer.call map, x, y, z, tile, object, draw_x, draw_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