- Map drawing is now possible with custom object-specific drawing
    code. A few examples have been added, including one that draws
    borders.
    Please note that those borders are still not perfect, however, as
    some inner angles are being rendered with plain/full-tile textures.
    The drawing code helpers will probably be moved to a location that
    makes them easy to reuse.
  - Some of the old map drawing code is still present (in particular in
    src/main.cr). That code is deprecated and will be removed soon.
  - WIP Naka::Map::ObjectReference. May or may not remain as it
    currently is.
  - Some mapgen updates to match the new drawing methods.
  - Possibly other minor tweaks or grooming.
master
Luka Vandervelden 2018-11-04 08:49:40 +09:00
parent 085f7adc09
commit 9b33e7cbb5
34 changed files with 170 additions and 44 deletions

BIN
assets/dirt-----.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt----l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt---b-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt---bl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt--r--.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
assets/dirt--r-l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
assets/dirt--rb-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt--rbl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
assets/dirt-t---.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt-t--l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt-t-b-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt-t-bl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt-tr--.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/dirt-tr-l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
assets/dirt-trb-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
assets/grass-----.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass----l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass---b-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass---bl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass--r--.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass--r-l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
assets/grass--rb-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass--rbl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
assets/grass-t---.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass-t--l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass-t-b-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass-t-bl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass-tr--.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/grass-tr-l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
assets/grass-trb-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -4,9 +4,7 @@ require "json"
require "./naka.cr" require "./naka.cr"
class ImagesLoader class ImagesLoader
getter grass : SDL::Texture
getter stone : SDL::Texture getter stone : SDL::Texture
getter dirt : SDL::Texture
getter tree : SDL::Texture getter tree : SDL::Texture
getter pine : SDL::Texture getter pine : SDL::Texture
getter flowers : SDL::Texture getter flowers : SDL::Texture
@ -16,9 +14,7 @@ class ImagesLoader
getter rocks : SDL::Texture getter rocks : SDL::Texture
def initialize(window) def initialize(window)
@grass = window.newImage "assets/grass.png"
@stone = window.newImage "assets/stone.png" @stone = window.newImage "assets/stone.png"
@dirt = window.newImage "assets/dirt.png"
@tree = window.newImage "assets/tree.png" @tree = window.newImage "assets/tree.png"
@flowers = window.newImage "assets/flowers.png" @flowers = window.newImage "assets/flowers.png"
@sand = window.newImage "assets/sand.png" @sand = window.newImage "assets/sand.png"
@ -38,6 +34,114 @@ images = ImagesLoader.new window
connection_font = window.newFont "assets/connection.otf", 30.5 connection_font = window.newFont "assets/connection.otf", 30.5
window.set_font connection_font 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| altitude_noise = Naka::Noise2D.new.tap do |a|
a.add_octave(32, 1) a.add_octave(32, 1)
a.add_octave(16, 0.5) a.add_octave(16, 0.5)
@ -61,55 +165,61 @@ evil_noise = Naka::Noise2D.new.tap do |a|
a.add_octave(16, 0.3) a.add_octave(16, 0.3)
end 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 altitude = altitude_noise.get(x, y) + 0.5
humidity = humidity_noise.get(x, y) + 0.5 humidity = humidity_noise.get(x, y) + 0.5
evil = evil_noise.get(x, y) evil = evil_noise.get(x, y)
if altitude < 0.25 if altitude < 0.35
tile << Naka::Map::Object.new "sand" tile << Naka::Map::Object.new water
else
tile << Naka::Map::Object.new stone
end
if altitude < 0.175 if altitude < 0.25
tile << Naka::Map::Object.new "water" if altitude > 0.175
else
if humidity < 0.33 if humidity < 0.33
tile << Naka::Map::Object.new "sand" tile << Naka::Map::Object.new sand
else else
tile << Naka::Map::Object.new "dirt" tile << Naka::Map::Object.new dirt
end end
end end
elsif altitude < 0.75 elsif altitude < 0.75
tile << Naka::Map::Object.new "dirt" tile << Naka::Map::Object.new dirt
if evil > 0.5 if evil > 0.5
tile << Naka::Map::Object.new "haunted" tile << Naka::Map::Object.new haunted
else else
tile << Naka::Map::Object.new "grass" tile << Naka::Map::Object.new grass
end end
if altitude > 0.35 && altitude < 0.65 if altitude > 0.35 && altitude < 0.65
if humidity > 0.4 if humidity > 0.4
if humidity > 0.8 if humidity > 0.8
tile << Naka::Map::Object.new "tree" tile << Naka::Map::Object.new tree
elsif humidity < 0.6 elsif humidity < 0.6
tile << Naka::Map::Object.new "pine" tile << Naka::Map::Object.new pine
else else
if Random.rand(2) == 0 if Random.rand(2) == 0
tile << Naka::Map::Object.new "tree" tile << Naka::Map::Object.new tree
else else
tile << Naka::Map::Object.new "pine" tile << Naka::Map::Object.new pine
end end
end end
else else
if Random.rand(10) == 0 if Random.rand(10) == 0
tile << Naka::Map::Object.new "flowers" tile << Naka::Map::Object.new flowers
end end
end end
end end
elsif altitude > 0.85 else
tile << Naka::Map::Object.new "rocks" tile << Naka::Map::Object.new stone
if altitude > 0.85
tile << Naka::Map::Object.new rocks
end
end end
end end
@ -119,7 +229,7 @@ Naka::Event.loop window do |event|
next Naka::Event::Quit next Naka::Event::Quit
when Naka::Event::Update when Naka::Event::Update
when Naka::Event::Draw when Naka::Event::Draw
zoom_level = 1.0 zoom_level = 4.0
128.times do |x| 128.times do |x|
128.times do |y| 128.times do |y|
@ -128,17 +238,11 @@ Naka::Event.loop window do |event|
# FIXME: # FIXME:
# - Please dont draw more than one layer of ground… # - Please dont draw more than one layer of ground…
# - Transitions. (eg. between dirt and grass) # - Transitions. (eg. between dirt and grass)
tile.each do |object| tile.each_with_index do |object, z|
image = case object.type image = case object.reference.name.downcase
when "grass"
images.grass
when "dirt"
images.dirt
when "stone"
images.stone
when "tree" when "tree"
images.tree images.tree
when "pine" when "pine tree"
images.pine images.pine
when "flowers" when "flowers"
images.flowers images.flowers
@ -154,13 +258,23 @@ Naka::Event.loop window do |event|
images.stone images.stone
end end
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( window.draw(
image, image,
x: (x * 16 * zoom_level).to_i, x: draw_x,
y: (y * 16 * zoom_level - (image.height - 16) * zoom_level).to_i, y: draw_y,
scale_x: zoom_level, scale_x: zoom_level,
scale_y: 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 end
end end

View File

@ -3,21 +3,33 @@ require "json"
class Naka::Map class Naka::Map
@save_directory : String @save_directory : String
getter default_reference : ObjectReference
getter generator 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 Dir.mkdir_p @save_directory
@generator = block @generator = block
end 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 class Object
getter type : String getter reference : ObjectReference
def initialize(@type) def initialize(@reference)
end end
def to_json(builder) def to_json(builder)
builder.object do builder.object do
builder.field "type", @type builder.field "type", @reference.name
end end
end end
end end
@ -45,7 +57,7 @@ class Naka::Map
Array.new(CHUNK_SIZE) do |y| Array.new(CHUNK_SIZE) do |y|
y += @y * CHUNK_SIZE 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 map.generator.call tile, x, y
end end
end end