diff --git a/assets/dirt-----.png b/assets/dirt-----.png new file mode 100644 index 0000000..b762402 Binary files /dev/null and b/assets/dirt-----.png differ diff --git a/assets/dirt----l.png b/assets/dirt----l.png new file mode 100644 index 0000000..db81ff6 Binary files /dev/null and b/assets/dirt----l.png differ diff --git a/assets/dirt---b-.png b/assets/dirt---b-.png new file mode 100644 index 0000000..d144d4d Binary files /dev/null and b/assets/dirt---b-.png differ diff --git a/assets/dirt---bl.png b/assets/dirt---bl.png new file mode 100644 index 0000000..719af03 Binary files /dev/null and b/assets/dirt---bl.png differ diff --git a/assets/dirt--r--.png b/assets/dirt--r--.png new file mode 100644 index 0000000..e3ec3ab Binary files /dev/null and b/assets/dirt--r--.png differ diff --git a/assets/dirt--r-l.png b/assets/dirt--r-l.png new file mode 100644 index 0000000..b029015 Binary files /dev/null and b/assets/dirt--r-l.png differ diff --git a/assets/dirt--rb-.png b/assets/dirt--rb-.png new file mode 100644 index 0000000..68f0f60 Binary files /dev/null and b/assets/dirt--rb-.png differ diff --git a/assets/dirt--rbl.png b/assets/dirt--rbl.png new file mode 100644 index 0000000..202b53a Binary files /dev/null and b/assets/dirt--rbl.png differ diff --git a/assets/dirt-t---.png b/assets/dirt-t---.png new file mode 100644 index 0000000..d1b5043 Binary files /dev/null and b/assets/dirt-t---.png differ diff --git a/assets/dirt-t--l.png b/assets/dirt-t--l.png new file mode 100644 index 0000000..5d7ed69 Binary files /dev/null and b/assets/dirt-t--l.png differ diff --git a/assets/dirt-t-b-.png b/assets/dirt-t-b-.png new file mode 100644 index 0000000..4ec57be Binary files /dev/null and b/assets/dirt-t-b-.png differ diff --git a/assets/dirt-t-bl.png b/assets/dirt-t-bl.png new file mode 100644 index 0000000..d12527f Binary files /dev/null and b/assets/dirt-t-bl.png differ diff --git a/assets/dirt-tr--.png b/assets/dirt-tr--.png new file mode 100644 index 0000000..f4d2499 Binary files /dev/null and b/assets/dirt-tr--.png differ diff --git a/assets/dirt-tr-l.png b/assets/dirt-tr-l.png new file mode 100644 index 0000000..f2d343b Binary files /dev/null and b/assets/dirt-tr-l.png differ diff --git a/assets/dirt-trb-.png b/assets/dirt-trb-.png new file mode 100644 index 0000000..a6c1f4f Binary files /dev/null and b/assets/dirt-trb-.png differ diff --git a/assets/dirt.png b/assets/dirt-trbl.png similarity index 100% rename from assets/dirt.png rename to assets/dirt-trbl.png diff --git a/assets/grass-----.png b/assets/grass-----.png new file mode 100644 index 0000000..4d46787 Binary files /dev/null and b/assets/grass-----.png differ diff --git a/assets/grass----l.png b/assets/grass----l.png new file mode 100644 index 0000000..7808ba5 Binary files /dev/null and b/assets/grass----l.png differ diff --git a/assets/grass---b-.png b/assets/grass---b-.png new file mode 100644 index 0000000..8572121 Binary files /dev/null and b/assets/grass---b-.png differ diff --git a/assets/grass---bl.png b/assets/grass---bl.png new file mode 100644 index 0000000..293f08a Binary files /dev/null and b/assets/grass---bl.png differ diff --git a/assets/grass--r--.png b/assets/grass--r--.png new file mode 100644 index 0000000..efb8815 Binary files /dev/null and b/assets/grass--r--.png differ diff --git a/assets/grass--r-l.png b/assets/grass--r-l.png new file mode 100644 index 0000000..2a3f38e Binary files /dev/null and b/assets/grass--r-l.png differ diff --git a/assets/grass--rb-.png b/assets/grass--rb-.png new file mode 100644 index 0000000..e9e798d Binary files /dev/null and b/assets/grass--rb-.png differ diff --git a/assets/grass--rbl.png b/assets/grass--rbl.png new file mode 100644 index 0000000..fbb42b6 Binary files /dev/null and b/assets/grass--rbl.png differ diff --git a/assets/grass-t---.png b/assets/grass-t---.png new file mode 100644 index 0000000..a1a83ff Binary files /dev/null and b/assets/grass-t---.png differ diff --git a/assets/grass-t--l.png b/assets/grass-t--l.png new file mode 100644 index 0000000..503dca7 Binary files /dev/null and b/assets/grass-t--l.png differ diff --git a/assets/grass-t-b-.png b/assets/grass-t-b-.png new file mode 100644 index 0000000..4b6f58e Binary files /dev/null and b/assets/grass-t-b-.png differ diff --git a/assets/grass-t-bl.png b/assets/grass-t-bl.png new file mode 100644 index 0000000..5aa139c Binary files /dev/null and b/assets/grass-t-bl.png differ diff --git a/assets/grass-tr--.png b/assets/grass-tr--.png new file mode 100644 index 0000000..d2e8e9b Binary files /dev/null and b/assets/grass-tr--.png differ diff --git a/assets/grass-tr-l.png b/assets/grass-tr-l.png new file mode 100644 index 0000000..a2e5181 Binary files /dev/null and b/assets/grass-tr-l.png differ diff --git a/assets/grass-trb-.png b/assets/grass-trb-.png new file mode 100644 index 0000000..f2af3fc Binary files /dev/null and b/assets/grass-trb-.png differ diff --git a/assets/grass.png b/assets/grass-trbl.png similarity index 100% rename from assets/grass.png rename to assets/grass-trbl.png diff --git a/src/main.cr b/src/main.cr index 9884eb5..7e86fab 100644 --- a/src/main.cr +++ b/src/main.cr @@ -4,9 +4,7 @@ require "json" require "./naka.cr" 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 @@ -16,9 +14,7 @@ class ImagesLoader 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" @@ -38,6 +34,114 @@ images = ImagesLoader.new window 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 + + ->(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, scale_x: zoom, scale_y: zoom + nil + } +end + +def bordered_tile_drawer(window : Naka::Window, base_tile_path : String) + # FIXME: Both excessive, insufficient, and broken. + + 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 +) +water = Naka::Map::ObjectReference.new( + name: "Water" +) +flowers = Naka::Map::ObjectReference.new( + name: "Flowers", + walkable: true +) +haunted = Naka::Map::ObjectReference.new( + name: "Haunted", + walkable: true +) +tree = Naka::Map::ObjectReference.new( + name: "Tree" +) +pine = Naka::Map::ObjectReference.new( + name: "Pine Tree" +) +rocks = Naka::Map::ObjectReference.new( + name: "Rocks" +) + altitude_noise = Naka::Noise2D.new.tap do |a| a.add_octave(32, 1) a.add_octave(16, 0.5) @@ -61,55 +165,61 @@ evil_noise = Naka::Noise2D.new.tap do |a| a.add_octave(16, 0.3) end -map = Naka::Map.new "map-test-01" do |tile, x, y| +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.25 - tile << Naka::Map::Object.new "sand" + if altitude < 0.35 + tile << Naka::Map::Object.new water + else + tile << Naka::Map::Object.new stone + end - if altitude < 0.175 - tile << Naka::Map::Object.new "water" - else + if altitude < 0.25 + if altitude > 0.175 if humidity < 0.33 - tile << Naka::Map::Object.new "sand" + tile << Naka::Map::Object.new sand else - tile << Naka::Map::Object.new "dirt" + tile << Naka::Map::Object.new dirt end end elsif altitude < 0.75 - tile << Naka::Map::Object.new "dirt" + tile << Naka::Map::Object.new dirt if evil > 0.5 - tile << Naka::Map::Object.new "haunted" + tile << Naka::Map::Object.new haunted else - tile << Naka::Map::Object.new "grass" + tile << Naka::Map::Object.new grass end if altitude > 0.35 && altitude < 0.65 if humidity > 0.4 if humidity > 0.8 - tile << Naka::Map::Object.new "tree" + tile << Naka::Map::Object.new tree elsif humidity < 0.6 - tile << Naka::Map::Object.new "pine" + tile << Naka::Map::Object.new pine else if Random.rand(2) == 0 - tile << Naka::Map::Object.new "tree" + tile << Naka::Map::Object.new tree else - tile << Naka::Map::Object.new "pine" + tile << Naka::Map::Object.new pine end end else if Random.rand(10) == 0 - tile << Naka::Map::Object.new "flowers" + tile << Naka::Map::Object.new flowers end end end - elsif altitude > 0.85 - tile << Naka::Map::Object.new "rocks" + else + tile << Naka::Map::Object.new stone + + if altitude > 0.85 + tile << Naka::Map::Object.new rocks + end end end @@ -119,7 +229,7 @@ Naka::Event.loop window do |event| next Naka::Event::Quit when Naka::Event::Update when Naka::Event::Draw - zoom_level = 1.0 + zoom_level = 4.0 128.times do |x| 128.times do |y| @@ -128,17 +238,11 @@ Naka::Event.loop window do |event| # 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 + tile.each_with_index do |object, z| + image = case object.reference.name.downcase when "tree" images.tree - when "pine" + when "pine tree" images.pine when "flowers" images.flowers @@ -154,13 +258,23 @@ Naka::Event.loop window do |event| 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 - ) + draw_x = (x * 16 * zoom_level).to_i + draw_y = (y * 16 * zoom_level - (image.height - 16) * zoom_level).to_i + + drawer = object.reference.drawer + + if drawer.nil? + window.draw( + image, + x: draw_x, + y: draw_y, + scale_x: zoom_level, + scale_y: zoom_level + ) + next + end + + drawer.call map, x, y, z, tile, object, draw_x, draw_y, zoom_level end end end diff --git a/src/naka/map.cr b/src/naka/map.cr index d6f1650..42209af 100644 --- a/src/naka/map.cr +++ b/src/naka/map.cr @@ -3,21 +3,33 @@ require "json" class Naka::Map @save_directory : String + getter default_reference : ObjectReference getter generator - def initialize(@save_directory, &block : Proc(Tile, Int32, Int32, Tile?)) + + 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 type : String - def initialize(@type) + getter reference : ObjectReference + def initialize(@reference) end def to_json(builder) builder.object do - builder.field "type", @type + builder.field "type", @reference.name end end end @@ -45,7 +57,7 @@ class Naka::Map Array.new(CHUNK_SIZE) do |y| y += @y * CHUNK_SIZE - Tile.new(Object.new "stone").tap do |tile| + Tile.new(Object.new map.default_reference).tap do |tile| map.generator.call tile, x, y end end